From f5b34694d140c9adb6feeb606484596020449e95 Mon Sep 17 00:00:00 2001 From: asonix Date: Tue, 4 Jun 2024 07:33:29 -0500 Subject: [PATCH] feat: add cargo feature to use rustls without ring (#2301) --- .github/workflows/ci.yml | 6 ++++++ Cargo.toml | 20 +++++++++++++------- src/async_impl/client.rs | 14 +++++++++++++- src/async_impl/request.rs | 2 ++ tests/badssl.rs | 1 + tests/client.rs | 1 + tests/proxy.rs | 1 + tests/redirect.rs | 1 + tests/timeouts.rs | 1 + tests/upgrade.rs | 1 + 10 files changed, 40 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec18a401c..846feccf8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,8 +72,10 @@ jobs: - "feat.: rustls-tls" - "feat.: rustls-tls-manual-roots" - "feat.: rustls-tls-native-roots" + - "feat.: rustls-tls-no-provider" - "feat.: native-tls" - "feat.: default-tls and rustls-tls" + - "feat.: rustls-tls and rustls-tls-no-provider" - "feat.: cookies" - "feat.: blocking" - "feat.: blocking only" @@ -131,8 +133,12 @@ jobs: features: "--no-default-features --features rustls-tls-manual-roots" - name: "feat.: rustls-tls-native-roots" features: "--no-default-features --features rustls-tls-native-roots" + - name: "feat.: rustls-tls-no-provider" + features: "--no-default-features --features rustls-tls-no-provider" - name: "feat.: native-tls" features: "--features native-tls" + - name: "feat.: rustls-tls and rustls-tls-no-provider" + features: "--features rustls-tls,rustls-tls-no-provider" - name: "feat.: default-tls and rustls-tls" features: "--features rustls-tls" - name: "feat.: cookies" diff --git a/Cargo.toml b/Cargo.toml index 46e7307fc..7af59bdcb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,9 +41,12 @@ native-tls-alpn = ["native-tls", "native-tls-crate?/alpn", "hyper-tls?/alpn"] native-tls-vendored = ["native-tls", "native-tls-crate?/vendored"] rustls-tls = ["rustls-tls-webpki-roots"] -rustls-tls-manual-roots = ["__rustls"] -rustls-tls-webpki-roots = ["dep:webpki-roots", "__rustls"] -rustls-tls-native-roots = ["dep:rustls-native-certs", "__rustls"] +rustls-tls-no-provider = ["rustls-tls-manual-roots-no-provider"] + +rustls-tls-manual-roots = ["__rustls", "__rustls-ring"] +rustls-tls-webpki-roots = ["dep:webpki-roots", "__rustls", "__rustls-ring"] +rustls-tls-native-roots = ["dep:rustls-native-certs", "__rustls", "__rustls-ring"] +rustls-tls-manual-roots-no-provider = ["__rustls"] blocking = ["dep:futures-channel", "futures-channel?/sink", "futures-util/io", "futures-util/sink", "tokio/sync"] @@ -77,6 +80,7 @@ macos-system-configuration = ["dep:system-configuration"] # Experimental HTTP/3 client. http3 = ["rustls-tls-manual-roots", "dep:h3", "dep:h3-quinn", "dep:quinn", "dep:slab", "dep:futures-channel"] + # Internal (PRIVATE!) features used to aid testing. # Don't rely on these whatsoever. They may disappear at anytime. @@ -86,6 +90,7 @@ __tls = ["dep:rustls-pemfile", "tokio/io-util"] # Enables common rustls code. # Equivalent to rustls-tls-manual-roots but shorter :) __rustls = ["dep:hyper-rustls", "dep:tokio-rustls", "dep:rustls", "__tls", "dep:rustls-pemfile", "dep:rustls-pki-types"] +__rustls-ring = ["hyper-rustls?/ring", "tokio-rustls?/ring", "rustls?/ring", "quinn?/ring"] # When enabled, disable using the cached SYS_PROXIES. __internal_proxy_sys_no_cache = [] @@ -133,10 +138,10 @@ native-tls-crate = { version = "0.2.10", optional = true, package = "native-tls" tokio-native-tls = { version = "0.3.0", optional = true } # rustls-tls -hyper-rustls = { version = "0.27.0", default-features = false, optional = true, features = ["http1", "http2", "native-tokio", "ring", "tls12"] } -rustls = { version = "0.23.4", optional = true, default-features = false, features = ["std", "ring", "tls12"] } +hyper-rustls = { version = "0.27.0", default-features = false, optional = true, features = ["http1", "http2", "native-tokio", "tls12"] } +rustls = { version = "0.23.4", optional = true, default-features = false, features = ["std", "tls12"] } rustls-pki-types = { version = "1.1.0", features = ["alloc"] ,optional = true } -tokio-rustls = { version = "0.26", optional = true, default-features = false, features = ["ring", "tls12"] } +tokio-rustls = { version = "0.26", optional = true, default-features = false, features = ["tls12"] } webpki-roots = { version = "0.26.0", optional = true } rustls-native-certs = { version = "0.7", optional = true } @@ -157,7 +162,7 @@ hickory-resolver = { version = "0.24", optional = true, features = ["tokio-runti # HTTP/3 experimental support h3 = { version = "0.0.5", optional = true } h3-quinn = { version = "0.0.6", optional = true } -quinn = { version = "0.11.1", default-features = false, features = ["rustls", "ring", "runtime-tokio"], optional = true } +quinn = { version = "0.11.1", default-features = false, features = ["rustls", "runtime-tokio"], optional = true } slab = { version = "0.4.9", optional = true } # just to get minimal versions working with quinn futures-channel = { version = "0.3", optional = true } @@ -173,6 +178,7 @@ zstd_crate = { package = "zstd", version = "0.13" } doc-comment = "0.3" tokio = { version = "1.0", default-features = false, features = ["macros", "rt-multi-thread"] } futures-util = { version = "0.3.28", default-features = false, features = ["std", "alloc"] } +rustls = { version = "0.23", default-features = false, features = ["ring"] } [target.'cfg(windows)'.dependencies] winreg = "0.52.0" diff --git a/src/async_impl/client.rs b/src/async_impl/client.rs index f74ef37f0..f9ed12a69 100644 --- a/src/async_impl/client.rs +++ b/src/async_impl/client.rs @@ -571,7 +571,13 @@ impl ClientBuilder { // If not, we use ring. let provider = rustls::crypto::CryptoProvider::get_default() .map(|arc| arc.clone()) - .unwrap_or_else(|| Arc::new(rustls::crypto::ring::default_provider())); + .unwrap_or_else(|| { + #[cfg(not(feature = "__rustls-ring"))] + panic!("No provider set"); + + #[cfg(feature = "__rustls-ring")] + Arc::new(rustls::crypto::ring::default_provider()) + }); // Build TLS config let config_builder = rustls::ClientConfig::builder_with_provider(provider) @@ -1322,6 +1328,8 @@ impl ClientBuilder { /// # Example /// /// ``` + /// # #[cfg(all(feature = "__rustls", not(feature = "__rustls-ring")))] + /// # let _ = rustls::crypto::ring::default_provider().install_default(); /// use std::net::IpAddr; /// let local_addr = IpAddr::from([12, 4, 1, 8]); /// let client = reqwest::Client::builder() @@ -1341,6 +1349,8 @@ impl ClientBuilder { /// # Example /// /// ``` + /// # #[cfg(all(feature = "__rustls", not(feature = "__rustls-ring")))] + /// # let _ = rustls::crypto::ring::default_provider().install_default(); /// let interface = "lo"; /// let client = reqwest::Client::builder() /// .interface(interface) @@ -2781,6 +2791,8 @@ fn add_cookie_header(headers: &mut HeaderMap, cookie_store: &dyn cookie::CookieS #[cfg(test)] mod tests { + #![cfg(not(feature = "rustls-tls-manual-roots-no-provider"))] + #[tokio::test] async fn execute_request_rejects_invalid_urls() { let url_str = "hxxps://www.rust-lang.org/"; diff --git a/src/async_impl/request.rs b/src/async_impl/request.rs index 665710430..aa900ca02 100644 --- a/src/async_impl/request.rs +++ b/src/async_impl/request.rs @@ -649,6 +649,8 @@ impl TryFrom for HttpRequest { #[cfg(test)] mod tests { + #![cfg(not(feature = "rustls-tls-manual-roots-no-provider"))] + use super::{Client, HttpRequest, Request, RequestBuilder, Version}; use crate::Method; use serde::Serialize; diff --git a/tests/badssl.rs b/tests/badssl.rs index 9b001d070..e889e864f 100644 --- a/tests/badssl.rs +++ b/tests/badssl.rs @@ -1,4 +1,5 @@ #![cfg(not(target_arch = "wasm32"))] +#![cfg(not(feature = "rustls-tls-manual-roots-no-provider"))] #[cfg(all(feature = "__tls", not(feature = "rustls-tls-manual-roots")))] #[tokio::test] diff --git a/tests/client.rs b/tests/client.rs index 292fd4e19..0a1f6923a 100644 --- a/tests/client.rs +++ b/tests/client.rs @@ -1,4 +1,5 @@ #![cfg(not(target_arch = "wasm32"))] +#![cfg(not(feature = "rustls-tls-manual-roots-no-provider"))] mod support; use support::server; diff --git a/tests/proxy.rs b/tests/proxy.rs index 231de25d8..9231a3267 100644 --- a/tests/proxy.rs +++ b/tests/proxy.rs @@ -1,4 +1,5 @@ #![cfg(not(target_arch = "wasm32"))] +#![cfg(not(feature = "rustls-tls-manual-roots-no-provider"))] mod support; use support::server; diff --git a/tests/redirect.rs b/tests/redirect.rs index c98c799ef..c496d90d3 100644 --- a/tests/redirect.rs +++ b/tests/redirect.rs @@ -1,4 +1,5 @@ #![cfg(not(target_arch = "wasm32"))] +#![cfg(not(feature = "rustls-tls-manual-roots-no-provider"))] mod support; use http_body_util::BodyExt; use reqwest::Body; diff --git a/tests/timeouts.rs b/tests/timeouts.rs index c18fecdbe..c3649ea9f 100644 --- a/tests/timeouts.rs +++ b/tests/timeouts.rs @@ -1,4 +1,5 @@ #![cfg(not(target_arch = "wasm32"))] +#![cfg(not(feature = "rustls-tls-manual-roots-no-provider"))] mod support; use support::server; diff --git a/tests/upgrade.rs b/tests/upgrade.rs index 5ea72acc2..7a67c0457 100644 --- a/tests/upgrade.rs +++ b/tests/upgrade.rs @@ -1,4 +1,5 @@ #![cfg(not(target_arch = "wasm32"))] +#![cfg(not(feature = "rustls-tls-manual-roots-no-provider"))] mod support; use support::server; use tokio::io::{AsyncReadExt, AsyncWriteExt};