From 09142b7b34a4ff17c1bdf1ce580fd1ad6d915e98 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Fri, 1 Dec 2023 12:52:13 -0800 Subject: [PATCH] Update to rustls 0.22 --- Cargo.lock | 172 ++++++++++++++++------------------------- Cargo.toml | 13 ++-- examples/cureq/main.rs | 40 +++++++--- examples/tls_config.rs | 14 +--- src/agent.rs | 12 +-- src/rtls.rs | 42 +++------- tests/https-agent.rs | 37 +++------ 7 files changed, 130 insertions(+), 200 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index af5aedb2..a708ff82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,12 +66,6 @@ dependencies = [ "alloc-stdlib", ] -[[package]] -name = "bumpalo" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" - [[package]] name = "byteorder" version = "1.4.3" @@ -247,6 +241,17 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -324,15 +329,6 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" -[[package]] -name = "js-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -341,9 +337,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "linux-raw-sys" @@ -510,17 +506,16 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "ring" -version = "0.16.20" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +checksum = "684d5e6e18f669ccebf64a92236bb7db9a34f07be010e3627368182027180866" dependencies = [ "cc", + "getrandom", "libc", - "once_cell", "spin", "untrusted", - "web-sys", - "winapi", + "windows-sys", ] [[package]] @@ -538,14 +533,16 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.7" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "5bc238b76c51bbc449c55ffbc39d03772a057cc8cf783c49d4af4c2537b74a8b" dependencies = [ "log", "ring", + "rustls-pki-types", "rustls-webpki", - "sct", + "subtle", + "zeroize", ] [[package]] @@ -555,7 +552,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 1.0.3", "schannel", "security-framework", ] @@ -569,13 +566,30 @@ dependencies = [ "base64", ] +[[package]] +name = "rustls-pemfile" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4" +dependencies = [ + "base64", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb0a1f9b9efec70d32e6d6aa3e58ebd88c3754ec98dfe9145c63cf54cc829b83" + [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "de2635c8bc2b88d367767c5de8ea1d8db9af3f6219eba28442242d9ab81d1b89" dependencies = [ "ring", + "rustls-pki-types", "untrusted", ] @@ -594,16 +608,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "sct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "security-framework" version = "2.9.2" @@ -671,9 +675,15 @@ dependencies = [ [[package]] name = "spin" -version = "0.5.2" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" @@ -774,9 +784,9 @@ dependencies = [ [[package]] name = "untrusted" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" @@ -796,7 +806,8 @@ dependencies = [ "once_cell", "rustls", "rustls-native-certs", - "rustls-pemfile", + "rustls-pemfile 2.0.0", + "rustls-pki-types", "rustls-webpki", "serde", "serde_json", @@ -829,75 +840,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] -name = "wasm-bindgen" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.87" +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "web-sys" -version = "0.3.64" +name = "webpki-roots" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "0de2cfda980f21be5a7ed2eadb3e6fe074d56022bea2cdeb1a62eb220fc04188" dependencies = [ - "js-sys", - "wasm-bindgen", + "rustls-pki-types", ] -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - [[package]] name = "winapi" version = "0.3.9" @@ -994,3 +950,9 @@ name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml index 9db57653..e2e1d116 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = ["tls", "gzip"] -tls = ["dep:webpki", "dep:webpki-roots", "dep:rustls"] +tls = ["dep:webpki", "dep:webpki-roots", "dep:rustls", "dep:rustls-pki-types"] native-certs = ["dep:rustls-native-certs"] json = ["dep:serde", "dep:serde_json"] charset = ["dep:encoding_rs"] @@ -43,9 +43,10 @@ serde_json = { version = ">=1.0.97", optional = true } encoding_rs = { version = "0.8", optional = true } cookie_store = { version = "0.20", optional = true, default-features = false, features = ["preserve_order"] } log = "0.4" -webpki = { package = "rustls-webpki", version = "0.101", optional = true } -webpki-roots = { version = "0.25", optional = true } -rustls = { version = "0.21.6", optional = true } +webpki = { package = "rustls-webpki", version = "0.102", optional = true } +webpki-roots = { version = "0.26", optional = true } +rustls = { version = "0.22.0", optional = true } +rustls-pki-types = { version = "1", optional = true } rustls-native-certs = { version = "0.6", optional = true } native-tls = { version = "0.2", optional = true } flate2 = { version = "1.0.22", optional = true } @@ -56,8 +57,8 @@ http = { version = "1.0", optional = true } [dev-dependencies] serde = { version = "1", features = ["derive"] } env_logger = "0.10" -rustls = { version = ">=0.21.6, <0.22", features = ["dangerous_configuration"] } -rustls-pemfile = { version = "1.0" } +rustls = { version = "0.22.0" } +rustls-pemfile = { version = "2.0" } [[example]] name = "cureq" diff --git a/examples/cureq/main.rs b/examples/cureq/main.rs index 3d584bc4..2afd8310 100644 --- a/examples/cureq/main.rs +++ b/examples/cureq/main.rs @@ -3,13 +3,11 @@ use std::fmt; use std::io; use std::thread; use std::time::Duration; -use std::time::SystemTime; use std::{env, sync::Arc}; -use rustls::client::ServerCertVerified; -use rustls::client::ServerCertVerifier; -use rustls::ServerName; -use rustls::{Certificate, ClientConfig}; +use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}; +use rustls::ClientConfig; +use rustls_pki_types::{CertificateDer, ServerName, UnixTime}; use ureq; #[derive(Debug)] @@ -96,20 +94,42 @@ fn perform( Ok(()) } +#[derive(Debug)] struct AcceptAll {} impl ServerCertVerifier for AcceptAll { fn verify_server_cert( &self, - _end_entity: &Certificate, - _intermediates: &[Certificate], + _end_entity: &CertificateDer, + _intermediates: &[CertificateDer], _server_name: &ServerName, - _scts: &mut dyn Iterator, _ocsp_response: &[u8], - _now: SystemTime, + _now: UnixTime, ) -> Result { Ok(ServerCertVerified::assertion()) } + + fn verify_tls12_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &rustls::DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn verify_tls13_signature( + &self, + _message: &[u8], + _cert: &CertificateDer<'_>, + _dss: &rustls::DigitallySignedStruct, + ) -> Result { + Ok(HandshakeSignatureValid::assertion()) + } + + fn supported_verify_schemes(&self) -> Vec { + todo!() + } } fn main() { @@ -165,7 +185,7 @@ Fetch url and copy it to stdout. } "-k" => { let client_config = ClientConfig::builder() - .with_safe_defaults() + .dangerous() .with_custom_certificate_verifier(Arc::new(AcceptAll {})) .with_no_client_auth(); builder = builder.tls_config(Arc::new(client_config)); diff --git a/examples/tls_config.rs b/examples/tls_config.rs index 7746f6d4..ab2549ed 100644 --- a/examples/tls_config.rs +++ b/examples/tls_config.rs @@ -21,23 +21,13 @@ pub fn main() { // } // This adds webpki_roots certs. - root_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| { - rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( - ta.subject, - ta.spki, - ta.name_constraints, - ) - })); + root_store.roots = webpki_roots::TLS_SERVER_ROOTS.iter().cloned().collect(); // This is how we narrow down the allowed TLS versions for rustls. let protocol_versions = &[&TLS12, &TLS13]; // See rustls documentation for more configuration options. - let tls_config = rustls::ClientConfig::builder() - .with_safe_default_cipher_suites() - .with_safe_default_kx_groups() - .with_protocol_versions(protocol_versions) - .unwrap() + let tls_config = rustls::ClientConfig::builder_with_protocol_versions(protocol_versions) .with_root_certificates(root_store) .with_no_client_auth(); diff --git a/src/agent.rs b/src/agent.rs index 30a0038e..986d3f92 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -595,17 +595,11 @@ impl AgentBuilder { /// # fn main() -> Result<(), ureq::Error> { /// # ureq::is_test(true); /// use std::sync::Arc; - /// let mut root_store = rustls::RootCertStore::empty(); - /// root_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| { - /// rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( - /// ta.subject, - /// ta.spki, - /// ta.name_constraints, - /// ) - /// })); + /// let mut root_store = rustls::RootCertStore { + /// roots: webpki_roots::TLS_SERVER_ROOTS.iter().cloned().collect(), + /// }; /// /// let tls_config = rustls::ClientConfig::builder() - /// .with_safe_defaults() /// .with_root_certificates(root_store) /// .with_no_client_auth(); /// let agent = ureq::builder() diff --git a/src/rtls.rs b/src/rtls.rs index f18adee6..086e6de4 100644 --- a/src/rtls.rs +++ b/src/rtls.rs @@ -64,30 +64,12 @@ fn root_certs() -> rustls::RootCertStore { use log::error; let mut root_cert_store = rustls::RootCertStore::empty(); - - let mut valid_count = 0; - let mut invalid_count = 0; - let certs = rustls_native_certs::load_native_certs().unwrap_or_else(|e| { + let native_certs = rustls_native_certs::load_native_certs().unwrap_or_else(|e| { error!("loading native certificates: {}", e); vec![] }); - for cert in certs { - let cert = rustls::Certificate(cert.0); - // Continue on parsing errors, as native stores often include ancient or syntactically - // invalid certificates, like root certificates without any X509 extensions. - // Inspiration: https://github.com/rustls/rustls/blob/633bf4ba9d9521a95f68766d04c22e2b01e68318/rustls/src/anchors.rs#L105-L112 - match root_cert_store.add(&cert) { - Ok(_) => valid_count += 1, - Err(err) => { - invalid_count += 1; - log::warn!( - "rustls failed to parse DER certificate {:?} {:?}", - &err, - &cert - ); - } - } - } + let (valid_count, invalid_count) = + root_cert_store.add_parsable_certificates(native_certs.into_iter().map(|c| c.0.into())); if valid_count == 0 && invalid_count > 0 { error!( "no valid certificates loaded by rustls-native-certs. all HTTPS requests will fail." @@ -98,15 +80,9 @@ fn root_certs() -> rustls::RootCertStore { #[cfg(not(feature = "native-certs"))] fn root_certs() -> rustls::RootCertStore { - let mut root_store = rustls::RootCertStore::empty(); - root_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| { - rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( - ta.subject, - ta.spki, - ta.name_constraints, - ) - })); - root_store + rustls::RootCertStore { + roots: webpki_roots::TLS_SERVER_ROOTS.to_vec(), + } } impl TlsConnector for Arc { @@ -122,8 +98,9 @@ impl TlsConnector for Arc { dns_name }; - let sni = rustls::ServerName::try_from(dns_name) - .map_err(|e| ErrorKind::Dns.msg(format!("parsing '{}'", dns_name)).src(e))?; + let sni = rustls_pki_types::ServerName::try_from(dns_name) + .map_err(|e| ErrorKind::Dns.msg(format!("parsing '{}'", dns_name)).src(e))? + .to_owned(); let mut sess = rustls::ClientConnection::new(self.clone(), sni) .map_err(|e| ErrorKind::Io.msg("tls connection creation failed").src(e))?; @@ -142,7 +119,6 @@ impl TlsConnector for Arc { pub fn default_tls_config() -> Arc { static TLS_CONF: Lazy> = Lazy::new(|| { let config = rustls::ClientConfig::builder() - .with_safe_defaults() .with_root_certificates(root_certs()) .with_no_client_auth(); Arc::new(Arc::new(config)) diff --git a/tests/https-agent.rs b/tests/https-agent.rs index 6722bc54..1cb92225 100644 --- a/tests/https-agent.rs +++ b/tests/https-agent.rs @@ -96,26 +96,19 @@ m0Wqhhi8/24Sy934t5Txgkfoltg8ahkx934WjP6WWRnSAu+cf+vW use ureq::OrAnyStatus; let certs = rustls_pemfile::certs(&mut BADSSL_CLIENT_CERT_PEM.as_bytes()) + .collect::, _>>() + .unwrap(); + let key = rustls_pemfile::private_key(&mut BADSSL_CLIENT_CERT_PEM.as_bytes()) .unwrap() - .into_iter() - .map(rustls::Certificate) - .collect(); - let key = rustls_pemfile::rsa_private_keys(&mut BADSSL_CLIENT_CERT_PEM.as_bytes()).unwrap()[0] - .clone(); - - let mut root_store = rustls::RootCertStore::empty(); - root_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| { - rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( - ta.subject, - ta.spki, - ta.name_constraints, - ) - })); + .unwrap(); + + let root_store = rustls::RootCertStore { + roots: webpki_roots::TLS_SERVER_ROOTS.iter().cloned().collect(), + }; let tls_config = rustls::ClientConfig::builder() - .with_safe_defaults() .with_root_certificates(root_store) - .with_single_cert(certs, rustls::PrivateKey(key)) + .with_client_auth_cert(certs, key) .unwrap(); let agent = ureq::builder() @@ -156,17 +149,11 @@ m0Wqhhi8/24Sy934t5Txgkfoltg8ahkx934WjP6WWRnSAu+cf+vW #[test] #[cfg(any(feature = "tls", feature = "tls-native"))] fn ipv6_addr_in_dns_name() { - let mut root_store = rustls::RootCertStore::empty(); - root_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| { - rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( - ta.subject, - ta.spki, - ta.name_constraints, - ) - })); + let root_store = rustls::RootCertStore { + roots: webpki_roots::TLS_SERVER_ROOTS.to_vec(), + }; let tls_config = rustls::ClientConfig::builder() - .with_safe_defaults() .with_root_certificates(root_store) .with_no_client_auth();