diff --git a/Cargo.lock b/Cargo.lock index 779e67bb..33c649ec 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" @@ -35,6 +41,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cc" version = "1.0.83" @@ -211,6 +223,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + [[package]] name = "flagset" version = "0.4.4" @@ -386,13 +404,44 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "multipart" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182" +dependencies = [ + "log", + "mime", + "mime_guess", + "rand", + "tempfile", +] + [[package]] name = "nethsm-sdk-rs" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b72723fa71b2448d6095c0bc788600858e19d1e939e920482bc6bba3aa7c1c2" +checksum = "2ef50e7e369f89a28621b330b81e2eafb26823c9b2bd1ffda2356968567a0e23" dependencies = [ - "base64", + "base64 0.21.6", + "mime", + "multipart", "serde", "serde_derive", "serde_json", @@ -426,6 +475,7 @@ dependencies = [ "sha2", "syslog", "thiserror", + "ureq", "x509-cert", ] @@ -477,6 +527,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -519,6 +578,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rayon" version = "1.8.0" @@ -539,6 +628,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "ring" version = "0.17.7" @@ -568,44 +666,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 +734,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 +839,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" @@ -774,6 +880,19 @@ dependencies = [ "time", ] +[[package]] +name = "tempfile" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -857,6 +976,15 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.14" @@ -892,15 +1020,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 +1060,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" @@ -1110,6 +1241,27 @@ dependencies = [ "spki", ] +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "zeroize" version = "1.7.0" diff --git a/pkcs11/Cargo.toml b/pkcs11/Cargo.toml index 7ca56c89..3dc4e953 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.1" } +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..01a53ef9 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..3b7c61b3 100644 --- a/pkcs11/src/config/initialization.rs +++ b/pkcs11/src/config/initialization.rs @@ -11,7 +11,7 @@ use super::{ }; use log::{debug, error, info, trace}; use nethsm_sdk_rs::ureq; -use rustls::client::ServerCertVerifier; +use rustls::client::{danger::ServerCertVerifier, WebPkiServerVerifier}; use sha2::Digest; const DEFAULT_USER_AGENT: &str = concat!("pkcs11-rs/", env!("CARGO_PKG_VERSION")); @@ -60,50 +60,94 @@ pub fn initialize() -> Result { initialize_with_configs(config_files()) } -struct DangerIgnoreVerifier {} +#[derive(Debug)] +struct DangerIgnoreVerifier(Arc); 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 { + self.0.verify_tls12_signature(message, cert, dss) + } + + fn verify_tls13_signature( + &self, + message: &[u8], + cert: &rustls::pki_types::CertificateDer<'_>, + dss: &rustls::DigitallySignedStruct, + ) -> Result { + self.0.verify_tls13_signature(message, cert, dss) + } + + fn supported_verify_schemes(&self) -> Vec { + self.0.supported_verify_schemes() } } +#[derive(Debug)] struct FingerprintVerifier { fingerprints: Vec>, + inner: Arc, } 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 { + self.inner.verify_tls12_signature(message, cert, dss) + } + + fn verify_tls13_signature( + &self, + message: &[u8], + cert: &rustls::pki_types::CertificateDer<'_>, + dss: &rustls::DigitallySignedStruct, + ) -> Result { + self.inner.verify_tls13_signature(message, cert, dss) + } + + fn supported_verify_schemes(&self) -> Vec { + self.inner.supported_verify_schemes() + } } fn slot_from_config(slot: &SlotConfig) -> Result { @@ -123,11 +167,16 @@ 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( + WebPkiServerVerifier::builder(Arc::new(rustls::RootCertStore::empty())) + .build() + .unwrap(), + ))) .with_no_client_auth() } else if !instance.sha256_fingerprints.is_empty() { let fingerprints = instance @@ -136,7 +185,13 @@ fn slot_from_config(slot: &SlotConfig) -> Result { .map(|f| f.value.clone()) .collect(); tls_conf - .with_custom_certificate_verifier(Arc::new(FingerprintVerifier { fingerprints })) + .dangerous() + .with_custom_certificate_verifier(Arc::new(FingerprintVerifier { + fingerprints, + inner: WebPkiServerVerifier::builder(Arc::new(rustls::RootCertStore::empty())) + .build() + .unwrap(), + })) .with_no_client_auth() } else { let mut roots = rustls::RootCertStore::empty(); @@ -145,7 +200,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");