From 836e95c4d3b111973ce0e718b8e0035a97658d01 Mon Sep 17 00:00:00 2001 From: iadev09 <166385752+iadev09@users.noreply.github.com> Date: Tue, 9 Jun 2026 07:13:01 +0300 Subject: [PATCH] Port hyper-rustls to rustls 0.24 --- Cargo.lock | 116 ++++++++++++++++++++-------------- Cargo.toml | 20 +++--- examples/client.rs | 27 +++++--- examples/server.rs | 31 ++++++--- src/config.rs | 41 ++++++++++++ src/connector.rs | 4 +- src/connector/builder.rs | 131 +++++++++++++++++++++++++++------------ src/lib.rs | 6 +- src/stream.rs | 5 +- 9 files changed, 262 insertions(+), 119 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e34aadf..74664e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,9 +33,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.16.3" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" dependencies = [ "aws-lc-fips-sys", "aws-lc-sys", @@ -44,9 +44,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.40.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" dependencies = [ "cc", "cmake", @@ -70,15 +70,15 @@ dependencies = [ "quote", "regex", "rustc-hash", - "shlex", + "shlex 1.3.0", "syn", ] [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "bytes" @@ -88,14 +88,14 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.60" +version = "1.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" dependencies = [ "find-msvc-tools", "jobserver", "libc", - "shlex", + "shlex 2.0.1", ] [[package]] @@ -167,9 +167,9 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "equivalent" @@ -283,15 +283,15 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "http" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ "bytes", "itoa", @@ -365,8 +365,10 @@ dependencies = [ "hyper-util", "log", "rustls", + "rustls-aws-lc-rs", "rustls-native-certs", "rustls-platform-verifier", + "rustls-ring", "tokio", "tokio-rustls", "tower-service", @@ -479,9 +481,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.185" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libloading" @@ -495,15 +497,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" [[package]] name = "minimal-lexical" @@ -513,9 +515,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi", @@ -644,20 +646,29 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +version = "0.24.0-dev.0" +source = "git+https://github.com/rustls/rustls.git?branch=main#97f4f106922facf64a555209411b7045cc9c3a49" dependencies = [ - "aws-lc-rs", "log", "once_cell", - "ring", "rustls-pki-types", "rustls-webpki", "subtle", "zeroize", ] +[[package]] +name = "rustls-aws-lc-rs" +version = "0.1.0-dev.0" +source = "git+https://github.com/rustls/rustls.git?branch=main#97f4f106922facf64a555209411b7045cc9c3a49" +dependencies = [ + "aws-lc-rs", + "rustls", + "rustls-pki-types", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" version = "0.8.4" @@ -672,9 +683,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ "zeroize", ] @@ -682,8 +693,7 @@ dependencies = [ [[package]] name = "rustls-platform-verifier" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +source = "git+https://github.com/rustls/rustls-platform-verifier.git?rev=733494d8ade721f249dc1b4e93196adf409ae8c0#733494d8ade721f249dc1b4e93196adf409ae8c0" dependencies = [ "core-foundation", "core-foundation-sys", @@ -691,6 +701,7 @@ dependencies = [ "log", "once_cell", "rustls", + "rustls-aws-lc-rs", "rustls-native-certs", "rustls-platform-verifier-android", "rustls-webpki", @@ -703,17 +714,25 @@ dependencies = [ [[package]] name = "rustls-platform-verifier-android" version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" +source = "git+https://github.com/rustls/rustls-platform-verifier.git?rev=733494d8ade721f249dc1b4e93196adf409ae8c0#733494d8ade721f249dc1b4e93196adf409ae8c0" + +[[package]] +name = "rustls-ring" +version = "0.1.0-dev.0" +source = "git+https://github.com/rustls/rustls.git?branch=main#97f4f106922facf64a555209411b7045cc9c3a49" +dependencies = [ + "ring", + "rustls", + "rustls-pki-types", + "subtle", +] [[package]] name = "rustls-webpki" -version = "0.103.13" +version = "0.104.0-alpha.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +checksum = "bea702cca24d344fc70973022bf7eb920c224e318466eb49784272337dd24b1a" dependencies = [ - "aws-lc-rs", - "ring", "rustls-pki-types", "untrusted", ] @@ -771,6 +790,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + [[package]] name = "simd_cesu8" version = "1.1.1" @@ -801,9 +826,9 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", "windows-sys 0.61.2", @@ -848,9 +873,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.52.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -875,10 +900,11 @@ dependencies = [ [[package]] name = "tokio-rustls" version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +source = "git+https://github.com/rustls/tokio-rustls.git?rev=be34e90bfe59f124363d725ceb739a435bfafa1e#be34e90bfe59f124363d725ceb739a435bfafa1e" dependencies = [ "rustls", + "rustls-aws-lc-rs", + "rustls-ring", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index 659cb48..92225f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,14 +13,14 @@ include = ["Cargo.toml", "LICENSE-MIT", "LICENSE-APACHE", "LICENSE-ISC", "README [features] default = ["native-tokio", "http1", "tls12", "logging", "aws-lc-rs"] -aws-lc-rs = ["rustls/aws_lc_rs"] -fips = ["aws-lc-rs", "rustls/fips"] +aws-lc-rs = ["dep:rustls-aws-lc-rs", "tokio-rustls/aws-lc-rs"] +fips = ["aws-lc-rs", "rustls-aws-lc-rs/fips", "tokio-rustls/fips"] http1 = ["hyper-util/http1"] http2 = ["hyper-util/http2"] -logging = ["log", "tokio-rustls/logging", "rustls/logging"] +logging = ["log", "tokio-rustls/logging", "rustls/log"] native-tokio = ["rustls-native-certs"] -ring = ["rustls/ring"] -tls12 = ["tokio-rustls/tls12", "rustls/tls12"] +ring = ["dep:rustls-ring", "tokio-rustls/ring"] +tls12 = ["tokio-rustls/tls12"] webpki-tokio = ["webpki-roots"] [dependencies] @@ -29,10 +29,12 @@ hyper = { version = "1", default-features = false } hyper-util = { version = "0.1", default-features = false, features = ["client-legacy", "tokio"] } log = { version = "0.4.4", optional = true } rustls-native-certs = { version = "0.8", optional = true } -rustls-platform-verifier = { version = "0.7", optional = true } -rustls = { version = "0.23", default-features = false } +rustls-platform-verifier = { git = "https://github.com/rustls/rustls-platform-verifier.git", rev = "733494d8ade721f249dc1b4e93196adf409ae8c0", version = "0.7", optional = true } +rustls = { git = "https://github.com/rustls/rustls.git", branch = "main", version = "0.24.0-dev.0", default-features = false, features = ["webpki"] } +rustls-aws-lc-rs = { git = "https://github.com/rustls/rustls.git", branch = "main", version = "0.1.0-dev.0", default-features = false, features = ["aws-lc-sys", "std"], optional = true } +rustls-ring = { git = "https://github.com/rustls/rustls.git", branch = "main", version = "0.1.0-dev.0", default-features = false, features = ["std"], optional = true } tokio = "1.0" -tokio-rustls = { version = "0.26", default-features = false } +tokio-rustls = { git = "https://github.com/rustls/tokio-rustls.git", rev = "be34e90bfe59f124363d725ceb739a435bfafa1e", version = "0.26.4", default-features = false } tower-service = "0.3" webpki-roots = { version = "1", optional = true } @@ -40,7 +42,7 @@ webpki-roots = { version = "1", optional = true } cfg-if = "1" http-body-util = "0.1" hyper-util = { version = "0.1", default-features = false, features = ["server-auto"] } -rustls = { version = "0.23", default-features = false, features = ["tls12"] } +rustls = { git = "https://github.com/rustls/rustls.git", branch = "main", version = "0.24.0-dev.0", default-features = false, features = ["webpki"] } tokio = { version = "1.0", features = ["io-std", "macros", "net", "rt-multi-thread"] } [[example]] diff --git a/examples/client.rs b/examples/client.rs index 713d481..bab601b 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -12,6 +12,7 @@ use rustls::pki_types::CertificateDer; use rustls::RootCertStore; use std::str::FromStr; +use std::sync::Arc; use std::{env, io}; fn main() { @@ -28,12 +29,6 @@ fn error(err: String) -> io::Error { #[tokio::main] async fn run_client() -> io::Result<()> { - // Set a process wide default crypto provider. - #[cfg(feature = "ring")] - let _ = rustls::crypto::ring::default_provider().install_default(); - #[cfg(feature = "aws-lc-rs")] - let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); - // First parameter is target URL (mandatory). let url = match env::args().nth(1) { Some(ref url) => Uri::from_str(url).map_err(|e| error(format!("{e}")))?, @@ -54,14 +49,16 @@ async fn run_client() -> io::Result<()> { let mut roots = RootCertStore::empty(); roots.add_parsable_certificates(certs); // TLS client config using the custom CA store for lookups - rustls::ClientConfig::builder() + rustls::ClientConfig::builder(provider()) .with_root_certificates(roots) .with_no_client_auth() + .map_err(|e| error(e.to_string()))? } // Default TLS client config with native roots - None => rustls::ClientConfig::builder() + None => rustls::ClientConfig::builder(provider()) .with_native_roots()? - .with_no_client_auth(), + .with_no_client_auth() + .map_err(|e| error(e.to_string()))?, }; // Prepare the HTTPS connector let https = hyper_rustls::HttpsConnectorBuilder::new() @@ -97,3 +94,15 @@ async fn run_client() -> io::Result<()> { fut.await } + +fn provider() -> Arc { + #[cfg(feature = "aws-lc-rs")] + { + return Arc::new(rustls_aws_lc_rs::DEFAULT_PROVIDER.clone()); + } + + #[cfg(all(not(feature = "aws-lc-rs"), feature = "ring"))] + { + return Arc::new(rustls_ring::DEFAULT_PROVIDER.clone()); + } +} diff --git a/examples/server.rs b/examples/server.rs index 96d97b4..d0d900f 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -15,6 +15,8 @@ use hyper::body::{Bytes, Incoming}; use hyper::service::service_fn; use hyper_util::rt::{TokioExecutor, TokioIo}; use hyper_util::server::conn::auto::Builder; +use rustls::crypto::Identity; +use rustls::enums::ApplicationProtocol; use rustls::pki_types::pem::PemObject; use rustls::pki_types::{CertificateDer, PrivateKeyDer}; use rustls::ServerConfig; @@ -35,12 +37,6 @@ fn error(err: String) -> io::Error { #[tokio::main] async fn run_server() -> Result<(), Box> { - // Set a process wide default crypto provider. - #[cfg(feature = "ring")] - let _ = rustls::crypto::ring::default_provider().install_default(); - #[cfg(feature = "aws-lc-rs")] - let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); - // First parameter is port number (optional, defaults to 1337) let port = match env::args().nth(1) { Some(ref p) => p.parse()?, @@ -63,11 +59,16 @@ async fn run_server() -> Result<(), Box> { println!("Starting to serve on https://{addr}"); // Build TLS configuration. - let mut server_config = ServerConfig::builder() + let identity = Arc::new(Identity::from_cert_chain(certs)?); + let mut server_config = ServerConfig::builder(provider()) .with_no_client_auth() - .with_single_cert(certs, key) + .with_single_cert(identity, key) .map_err(|e| error(e.to_string()))?; - server_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec(), b"http/1.0".to_vec()]; + server_config.alpn_protocols = vec![ + ApplicationProtocol::from(&b"h2"[..]), + ApplicationProtocol::from(&b"http/1.1"[..]), + ApplicationProtocol::from(&b"http/1.0"[..]), + ]; let tls_acceptor = TlsAcceptor::from(Arc::new(server_config)); let service = service_fn(echo); @@ -119,3 +120,15 @@ async fn echo(req: Request) -> Result>, hyper::Er }; Ok(response) } + +fn provider() -> Arc { + #[cfg(feature = "aws-lc-rs")] + { + return Arc::new(rustls_aws_lc_rs::DEFAULT_PROVIDER.clone()); + } + + #[cfg(all(not(feature = "aws-lc-rs"), feature = "ring"))] + { + return Arc::new(rustls_ring::DEFAULT_PROVIDER.clone()); + } +} diff --git a/src/config.rs b/src/config.rs index 8c77647..f43f74c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,15 @@ #[cfg(feature = "rustls-native-certs")] use std::io; +#[cfg(all( + any(feature = "aws-lc-rs", feature = "ring"), + any( + feature = "rustls-platform-verifier", + feature = "rustls-native-certs", + feature = "webpki-roots", + test + ) +))] +use std::sync::Arc; #[cfg(any( feature = "rustls-platform-verifier", @@ -7,6 +17,16 @@ use std::io; feature = "webpki-roots" ))] use rustls::client::WantsClientCert; +#[cfg(all( + any(feature = "aws-lc-rs", feature = "ring"), + any( + feature = "rustls-platform-verifier", + feature = "rustls-native-certs", + feature = "webpki-roots", + test + ) +))] +use rustls::crypto::CryptoProvider; use rustls::{ClientConfig, ConfigBuilder, WantsVerifier}; #[cfg(feature = "rustls-native-certs")] use rustls_native_certs::CertificateResult; @@ -133,3 +153,24 @@ mod sealed { impl Sealed for ConfigBuilder {} } + +#[cfg(all( + any(feature = "aws-lc-rs", feature = "ring"), + any( + feature = "rustls-platform-verifier", + feature = "rustls-native-certs", + feature = "webpki-roots", + test + ) +))] +pub(crate) fn default_provider() -> Arc { + #[cfg(feature = "aws-lc-rs")] + { + return Arc::new(rustls_aws_lc_rs::DEFAULT_PROVIDER.clone()); + } + + #[cfg(all(not(feature = "aws-lc-rs"), feature = "ring"))] + { + return Arc::new(rustls_ring::DEFAULT_PROVIDER.clone()); + } +} diff --git a/src/connector.rs b/src/connector.rs index 9e3e58d..e15874b 100644 --- a/src/connector.rs +++ b/src/connector.rs @@ -266,7 +266,7 @@ mod tests { allow: Allow, scheme: Scheme, ) -> Result>, BoxError> { - let config_builder = rustls::ClientConfig::builder(); + let config_builder = rustls::ClientConfig::builder(crate::config::default_provider()); cfg_if::cfg_if! { if #[cfg(feature = "rustls-platform-verifier")] { let config_builder = config_builder.try_with_platform_verifier()?; @@ -276,7 +276,7 @@ mod tests { let config_builder = config_builder.with_webpki_roots(); } } - let config = config_builder.with_no_client_auth(); + let config = config_builder.with_no_client_auth()?; let builder = HttpsConnectorBuilder::new().with_tls_config(config); let mut service = match allow { diff --git a/src/connector/builder.rs b/src/connector/builder.rs index 1b4a825..7b457fb 100644 --- a/src/connector/builder.rs +++ b/src/connector/builder.rs @@ -7,10 +7,22 @@ use hyper_util::client::legacy::connect::HttpConnector; feature = "webpki-roots" ))] use rustls::crypto::CryptoProvider; +#[cfg(any(feature = "http2", test))] +use rustls::enums::ApplicationProtocol; use rustls::pki_types::ServerName; use rustls::ClientConfig; use super::{DefaultServerNameResolver, HttpsConnector, ResolveServerName}; +#[cfg(all( + any(feature = "aws-lc-rs", feature = "ring"), + any( + feature = "rustls-platform-verifier", + feature = "rustls-native-certs", + feature = "webpki-roots", + test + ) +))] +use crate::config::default_provider; #[cfg(any( feature = "rustls-native-certs", feature = "webpki-roots", @@ -30,7 +42,6 @@ use crate::config::ConfigBuilderExt; /// /// # #[cfg(all(feature = "webpki-roots", feature = "http1", feature="aws-lc-rs"))] /// # { -/// # let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); /// let https = HttpsConnectorBuilder::new() /// .with_webpki_roots() /// .https_only() @@ -90,9 +101,9 @@ impl ConnectorBuilder { self, ) -> Result, rustls::Error> { Ok(self.with_tls_config( - ClientConfig::builder() + ClientConfig::builder(default_provider()) .try_with_platform_verifier()? - .with_no_client_auth(), + .with_no_client_auth()?, )) } @@ -105,11 +116,11 @@ impl ConnectorBuilder { provider: impl Into>, ) -> std::io::Result> { Ok(self.with_tls_config( - ClientConfig::builder_with_provider(provider.into()) - .with_safe_default_protocol_versions() - .and_then(|builder| builder.try_with_platform_verifier()) + ClientConfig::builder(provider.into()) + .try_with_platform_verifier() .map_err(std::io::Error::other)? - .with_no_client_auth(), + .with_no_client_auth() + .map_err(std::io::Error::other)?, )) } @@ -123,9 +134,10 @@ impl ConnectorBuilder { ))] pub fn with_native_roots(self) -> std::io::Result> { Ok(self.with_tls_config( - ClientConfig::builder() + ClientConfig::builder(default_provider()) .with_native_roots()? - .with_no_client_auth(), + .with_no_client_auth() + .map_err(std::io::Error::other)?, )) } @@ -138,11 +150,10 @@ impl ConnectorBuilder { provider: impl Into>, ) -> std::io::Result> { Ok(self.with_tls_config( - ClientConfig::builder_with_provider(provider.into()) - .with_safe_default_protocol_versions() - .map_err(std::io::Error::other)? + ClientConfig::builder(provider.into()) .with_native_roots()? - .with_no_client_auth(), + .with_no_client_auth() + .map_err(std::io::Error::other)?, )) } @@ -153,9 +164,10 @@ impl ConnectorBuilder { #[cfg(all(any(feature = "ring", feature = "aws-lc-rs"), feature = "webpki-roots"))] pub fn with_webpki_roots(self) -> ConnectorBuilder { self.with_tls_config( - ClientConfig::builder() + ClientConfig::builder(default_provider()) .with_webpki_roots() - .with_no_client_auth(), + .with_no_client_auth() + .expect("rustls provider configuration is invalid"), ) } @@ -169,10 +181,9 @@ impl ConnectorBuilder { provider: impl Into>, ) -> Result, rustls::Error> { Ok(self.with_tls_config( - ClientConfig::builder_with_provider(provider.into()) - .with_safe_default_protocol_versions()? + ClientConfig::builder(provider.into()) .with_webpki_roots() - .with_no_client_auth(), + .with_no_client_auth()?, )) } } @@ -258,7 +269,7 @@ impl ConnectorBuilder { /// This needs to be called explicitly, no protocol is enabled by default #[cfg(feature = "http2")] pub fn enable_http2(mut self) -> ConnectorBuilder { - self.0.tls_config.alpn_protocols = vec![b"h2".to_vec()]; + self.0.tls_config.alpn_protocols = vec![alpn(b"h2")]; ConnectorBuilder(WantsProtocols3 { inner: self.0, enable_http1: false, @@ -272,9 +283,9 @@ impl ConnectorBuilder { #[cfg(feature = "http2")] pub fn enable_all_versions(mut self) -> ConnectorBuilder { #[cfg(feature = "http1")] - let alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; + let alpn_protocols = vec![alpn(b"h2"), alpn(b"http/1.1")]; #[cfg(not(feature = "http1"))] - let alpn_protocols = vec![b"h2".to_vec()]; + let alpn_protocols = vec![alpn(b"h2")]; self.0.tls_config.alpn_protocols = alpn_protocols; ConnectorBuilder(WantsProtocols3 { @@ -343,7 +354,7 @@ impl ConnectorBuilder { /// This needs to be called explicitly, no protocol is enabled by default #[cfg(feature = "http2")] pub fn enable_http2(mut self) -> ConnectorBuilder { - self.0.inner.tls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; + self.0.inner.tls_config.alpn_protocols = vec![alpn(b"h2"), alpn(b"http/1.1")]; ConnectorBuilder(WantsProtocols3 { inner: self.0.inner, enable_http1: true, @@ -365,6 +376,11 @@ impl ConnectorBuilder { } } +#[cfg(any(feature = "http2", test))] +fn alpn(protocol: &'static [u8]) -> ApplicationProtocol<'static> { + protocol.into() +} + /// State of a builder with HTTP2 (and possibly HTTP1) enabled /// /// At this point a connector can be built, see @@ -414,10 +430,11 @@ mod tests { fn test_reject_predefined_alpn() { ensure_global_state(); let roots = rustls::RootCertStore::empty(); - let mut config_with_alpn = rustls::ClientConfig::builder() + let mut config_with_alpn = rustls::ClientConfig::builder(crate::config::default_provider()) .with_root_certificates(roots) - .with_no_client_auth(); - config_with_alpn.alpn_protocols = vec![b"fancyprotocol".to_vec()]; + .with_no_client_auth() + .unwrap(); + config_with_alpn.alpn_protocols = vec![super::alpn(b"fancyprotocol")]; let _connector = super::ConnectorBuilder::new() .with_tls_config(config_with_alpn) .https_only() @@ -430,9 +447,10 @@ mod tests { fn test_alpn() { ensure_global_state(); let roots = rustls::RootCertStore::empty(); - let tls_config = rustls::ClientConfig::builder() + let tls_config = rustls::ClientConfig::builder(crate::config::default_provider()) .with_root_certificates(roots) - .with_no_client_auth(); + .with_no_client_auth() + .unwrap(); let connector = super::ConnectorBuilder::new() .with_tls_config(tls_config.clone()) .https_only() @@ -447,7 +465,15 @@ mod tests { .https_only() .enable_http2() .build(); - assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]); + assert_eq!( + connector + .tls_config + .alpn_protocols + .iter() + .map(|protocol| protocol.as_ref()) + .collect::>(), + vec![b"h2".as_slice()] + ); let connector = super::ConnectorBuilder::new() .with_tls_config(tls_config.clone()) .https_only() @@ -455,8 +481,13 @@ mod tests { .enable_http2() .build(); assert_eq!( - &connector.tls_config.alpn_protocols, - &[b"h2".to_vec(), b"http/1.1".to_vec()] + connector + .tls_config + .alpn_protocols + .iter() + .map(|protocol| protocol.as_ref()) + .collect::>(), + vec![b"h2".as_slice(), b"http/1.1".as_slice()] ); let connector = super::ConnectorBuilder::new() .with_tls_config(tls_config) @@ -464,8 +495,13 @@ mod tests { .enable_all_versions() .build(); assert_eq!( - &connector.tls_config.alpn_protocols, - &[b"h2".to_vec(), b"http/1.1".to_vec()] + connector + .tls_config + .alpn_protocols + .iter() + .map(|protocol| protocol.as_ref()) + .collect::>(), + vec![b"h2".as_slice(), b"http/1.1".as_slice()] ); } @@ -473,28 +509,41 @@ mod tests { #[cfg(all(not(feature = "http1"), feature = "http2"))] fn test_alpn_http2() { let roots = rustls::RootCertStore::empty(); - let tls_config = rustls::ClientConfig::builder() - .with_safe_defaults() + let tls_config = rustls::ClientConfig::builder(crate::config::default_provider()) .with_root_certificates(roots) - .with_no_client_auth(); + .with_no_client_auth() + .unwrap(); let connector = super::ConnectorBuilder::new() .with_tls_config(tls_config.clone()) .https_only() .enable_http2() .build(); - assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]); + assert_eq!( + connector + .tls_config + .alpn_protocols + .iter() + .map(|protocol| protocol.as_ref()) + .collect::>(), + vec![b"h2".as_slice()] + ); let connector = super::ConnectorBuilder::new() .with_tls_config(tls_config) .https_only() .enable_all_versions() .build(); - assert_eq!(&connector.tls_config.alpn_protocols, &[b"h2".to_vec()]); + assert_eq!( + connector + .tls_config + .alpn_protocols + .iter() + .map(|protocol| protocol.as_ref()) + .collect::>(), + vec![b"h2".as_slice()] + ); } fn ensure_global_state() { - #[cfg(feature = "ring")] - let _ = rustls::crypto::ring::default_provider().install_default(); - #[cfg(feature = "aws-lc-rs")] - let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); + let _ = crate::config::default_provider(); } } diff --git a/src/lib.rs b/src/lib.rs index 0b11298..b2b8297 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,7 +41,7 @@ mod stream; #[cfg(feature = "logging")] mod log { - #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] + #[cfg(feature = "rustls-native-certs")] pub(crate) use log::debug; #[cfg(feature = "rustls-native-certs")] pub(crate) use log::warn; @@ -49,9 +49,9 @@ mod log { #[cfg(not(feature = "logging"))] mod log { - #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] + #[cfg(feature = "rustls-native-certs")] macro_rules! debug ( ($($tt:tt)*) => {{}} ); - #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] + #[cfg(feature = "rustls-native-certs")] pub(crate) use debug; #[cfg(feature = "rustls-native-certs")] macro_rules! warn_ ( ($($tt:tt)*) => {{}} ); diff --git a/src/stream.rs b/src/stream.rs index 538aa29..0c99248 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -25,7 +25,10 @@ impl Connection for MaybeHttpsStre Self::Http(s) => s.connected(), Self::Https(s) => { let (tcp, tls) = s.inner().get_ref(); - if tls.alpn_protocol() == Some(b"h2") { + if tls + .alpn_protocol() + .is_some_and(|protocol| protocol.as_ref() == b"h2") + { tcp.inner().connected().negotiated_h2() } else { tcp.inner().connected()