diff --git a/Cargo.lock b/Cargo.lock index 779e67bb..9bb9df6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,12 @@ version = "0.21.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c79fed4cdb43e993fcdadc7e58a09fd0e3e649c4436fa11da71c9f1f3ee7feb9" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -388,11 +394,11 @@ dependencies = [ [[package]] name = "nethsm-sdk-rs" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b72723fa71b2448d6095c0bc788600858e19d1e939e920482bc6bba3aa7c1c2" +checksum = "2d97b61d4b7b3f91c7f95af3c13a2477261ff244c83a6a480310258b308e9d4f" dependencies = [ - "base64", + "base64 0.21.6", "serde", "serde_derive", "serde_json", @@ -426,6 +432,7 @@ dependencies = [ "sha2", "syslog", "thiserror", + "ureq", "x509-cert", ] @@ -568,44 +575,56 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.11" +version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ "log", + "once_cell", "ring", + "rustls-pki-types", "rustls-webpki", - "sct", + "subtle", + "zeroize", ] [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "04182dffc9091a404e0fc069ea5cd60e5b866c3adf881eff99a32d048242dffa" dependencies = [ "openssl-probe", "rustls-pemfile", + "rustls-pki-types", "schannel", "security-framework", ] [[package]] name = "rustls-pemfile" -version = "1.0.4" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ - "base64", + "base64 0.22.1", + "rustls-pki-types", ] +[[package]] +name = "rustls-pki-types" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" + [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.102.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ "ring", + "rustls-pki-types", "untrusted", ] @@ -624,16 +643,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "security-framework" version = "2.9.2" @@ -739,6 +748,12 @@ dependencies = [ "der", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "1.0.109" @@ -892,15 +907,15 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.9.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" +checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" dependencies = [ - "base64", + "base64 0.22.1", "log", "once_cell", "rustls", - "rustls-webpki", + "rustls-pki-types", "serde", "serde_json", "url", @@ -932,9 +947,12 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +dependencies = [ + "rustls-pki-types", +] [[package]] name = "winapi" diff --git a/pkcs11/Cargo.toml b/pkcs11/Cargo.toml index 7ca56c89..8df5fc46 100644 --- a/pkcs11/Cargo.toml +++ b/pkcs11/Cargo.toml @@ -22,11 +22,9 @@ serde = { version = "1", features = ["derive"], default-features = false } serde_yaml = "0.9.22" serde_json = { default-features = false, version = "1.0.64" } lazy_static = "1.4.0" -nethsm-sdk-rs = { version = "1" } -rustls = { version = "0.21", features = [ - "dangerous_configuration", -], default-features = false } -rustls-native-certs = "0.6" +nethsm-sdk-rs = { version = "1.0" } +rustls = { version = "0.23", default-features = false } +rustls-native-certs = "0.7" base64ct = { version = "1.6", default-features = false } hex = "0.4" der = { version = "0.7", default-features = false } @@ -39,5 +37,8 @@ rayon = "1.8.0" syslog = "6.1.0" thiserror = "1.0.63" +# Needed to prevent breaking change with rustls updates +ureq = { version = "2.10", default-features = false } + [dev-dependencies] hex-literal = "0.4.1" diff --git a/pkcs11/src/backend/mod.rs b/pkcs11/src/backend/mod.rs index af385709..c9427c3c 100644 --- a/pkcs11/src/backend/mod.rs +++ b/pkcs11/src/backend/mod.rs @@ -61,6 +61,7 @@ impl From> for ApiError { }), }), apis::Error::StringParse(e) => ApiError::StringParse(e), + // apis::Error::Multipart { field: _, error } => ApiError::Io(error), } } } diff --git a/pkcs11/src/config/initialization.rs b/pkcs11/src/config/initialization.rs index 98b858bf..ff812ecf 100644 --- a/pkcs11/src/config/initialization.rs +++ b/pkcs11/src/config/initialization.rs @@ -11,7 +11,10 @@ use super::{ }; use log::{debug, error, info, trace}; use nethsm_sdk_rs::ureq; -use rustls::client::ServerCertVerifier; +use rustls::{ + client::danger::ServerCertVerifier, + crypto::{verify_tls12_signature, verify_tls13_signature, CryptoProvider}, +}; use sha2::Digest; const DEFAULT_USER_AGENT: &str = concat!("pkcs11-rs/", env!("CARGO_PKG_VERSION")); @@ -57,26 +60,67 @@ pub fn initialize_with_configs( } pub fn initialize() -> Result { + rustls::crypto::ring::default_provider() + .install_default() + .unwrap(); initialize_with_configs(config_files()) } -struct DangerIgnoreVerifier {} +#[derive(Debug)] +struct DangerIgnoreVerifier; impl ServerCertVerifier for DangerIgnoreVerifier { fn verify_server_cert( &self, - _end_entity: &rustls::Certificate, - _intermediates: &[rustls::Certificate], - _server_name: &rustls::ServerName, - _scts: &mut dyn Iterator, + _end_entity: &rustls::pki_types::CertificateDer<'_>, + _intermediates: &[rustls::pki_types::CertificateDer<'_>], + _server_name: &rustls::pki_types::ServerName<'_>, _ocsp_response: &[u8], - _now: std::time::SystemTime, - ) -> Result { - // always accept the certificate - Ok(rustls::client::ServerCertVerified::assertion()) + _now: rustls::pki_types::UnixTime, + ) -> Result { + Ok(rustls::client::danger::ServerCertVerified::assertion()) + } + + fn verify_tls12_signature( + &self, + message: &[u8], + cert: &rustls::pki_types::CertificateDer<'_>, + dss: &rustls::DigitallySignedStruct, + ) -> Result { + let default_provider = CryptoProvider::get_default().unwrap(); + verify_tls12_signature( + message, + cert, + dss, + &default_provider.signature_verification_algorithms, + ) + } + + fn verify_tls13_signature( + &self, + message: &[u8], + cert: &rustls::pki_types::CertificateDer<'_>, + dss: &rustls::DigitallySignedStruct, + ) -> Result { + let default_provider = CryptoProvider::get_default().unwrap(); + verify_tls13_signature( + message, + cert, + dss, + &default_provider.signature_verification_algorithms, + ) + } + + fn supported_verify_schemes(&self) -> Vec { + let default_provider = CryptoProvider::get_default().unwrap(); + + default_provider + .signature_verification_algorithms + .supported_schemes() } } +#[derive(Debug)] struct FingerprintVerifier { fingerprints: Vec>, } @@ -84,26 +128,63 @@ struct FingerprintVerifier { impl ServerCertVerifier for FingerprintVerifier { fn verify_server_cert( &self, - end_entity: &rustls::Certificate, - _intermediates: &[rustls::Certificate], - _server_name: &rustls::ServerName, - _scts: &mut dyn Iterator, + end_entity: &rustls::pki_types::CertificateDer<'_>, + _intermediates: &[rustls::pki_types::CertificateDer<'_>], + _server_name: &rustls::pki_types::ServerName<'_>, _ocsp_response: &[u8], - _now: std::time::SystemTime, - ) -> Result { + _now: rustls::pki_types::UnixTime, + ) -> Result { let mut hasher = sha2::Sha256::new(); - hasher.update(&end_entity.0); + hasher.update(end_entity.as_ref()); let result = hasher.finalize(); - for fingerprint in self.fingerprints.iter() { - if fingerprint == &result[..] { + for fingerprint in &self.fingerprints { + if fingerprint == &*result { trace!("Certificate fingerprint matches"); - return Ok(rustls::client::ServerCertVerified::assertion()); + return Ok(rustls::client::danger::ServerCertVerified::assertion()); } } Err(rustls::Error::General( "Could not verify certificate fingerprint".to_string(), )) } + + fn verify_tls12_signature( + &self, + message: &[u8], + cert: &rustls::pki_types::CertificateDer<'_>, + dss: &rustls::DigitallySignedStruct, + ) -> Result { + let default_provider = CryptoProvider::get_default().unwrap(); + verify_tls12_signature( + message, + cert, + dss, + &default_provider.signature_verification_algorithms, + ) + } + + fn verify_tls13_signature( + &self, + message: &[u8], + cert: &rustls::pki_types::CertificateDer<'_>, + dss: &rustls::DigitallySignedStruct, + ) -> Result { + let default_provider = CryptoProvider::get_default().unwrap(); + verify_tls13_signature( + message, + cert, + dss, + &default_provider.signature_verification_algorithms, + ) + } + + fn supported_verify_schemes(&self) -> Vec { + let default_provider = CryptoProvider::get_default().unwrap(); + + default_provider + .signature_verification_algorithms + .supported_schemes() + } } fn slot_from_config(slot: &SlotConfig) -> Result { @@ -123,11 +204,12 @@ fn slot_from_config(slot: &SlotConfig) -> Result { ); for instance in slot.instances.iter() { - let tls_conf = rustls::ClientConfig::builder().with_safe_defaults(); + let tls_conf = rustls::ClientConfig::builder(); let tls_conf = if instance.danger_insecure_cert { tls_conf - .with_custom_certificate_verifier(Arc::new(DangerIgnoreVerifier {})) + .dangerous() + .with_custom_certificate_verifier(Arc::new(DangerIgnoreVerifier)) .with_no_client_auth() } else if !instance.sha256_fingerprints.is_empty() { let fingerprints = instance @@ -136,6 +218,7 @@ fn slot_from_config(slot: &SlotConfig) -> Result { .map(|f| f.value.clone()) .collect(); tls_conf + .dangerous() .with_custom_certificate_verifier(Arc::new(FingerprintVerifier { fingerprints })) .with_no_client_auth() } else { @@ -145,7 +228,7 @@ fn slot_from_config(slot: &SlotConfig) -> Result { InitializationError::NoCerts })?; - let (added, failed) = roots.add_parsable_certificates(&native_certs); + let (added, failed) = roots.add_parsable_certificates(native_certs); // panic!("{:?}", (added, failed)); debug!("Added {added} certifcates and failed to parse {failed} certificates");