diff --git a/Cargo.toml b/Cargo.toml index 0f73850e0..826dda4b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ native-tls-vendored = ["native-tls", "native-tls-crate/vendored"] rustls-tls = ["rustls-tls-webpki-roots"] rustls-tls-manual-roots = ["__rustls"] rustls-tls-webpki-roots = ["webpki-roots", "__rustls"] +rustls-tls-native-roots = ["rustls-native-certs", "__rustls"] blocking = ["futures-util/io", "tokio/rt-threaded", "tokio/rt-core", "tokio/sync"] @@ -104,6 +105,7 @@ hyper-rustls = { version = "0.21", default-features = false, optional = true } rustls = { version = "0.18", features = ["dangerous_configuration"], optional = true } tokio-rustls = { version = "0.14", optional = true } webpki-roots = { version = "0.20", optional = true } +rustls-native-certs = { version = "0.4", optional = true } ## cookies cookie_crate = { version = "0.14", package = "cookie", optional = true } diff --git a/src/async_impl/client.rs b/src/async_impl/client.rs index 9c4fbee68..3b3ef8587 100644 --- a/src/async_impl/client.rs +++ b/src/async_impl/client.rs @@ -21,6 +21,8 @@ use http::Uri; use hyper::client::ResponseFuture; #[cfg(feature = "native-tls-crate")] use native_tls_crate::TlsConnector; +#[cfg(feature = "rustls-tls-native-roots")] +use rustls::RootCertStore; use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; @@ -259,6 +261,11 @@ impl ClientBuilder { #[cfg(feature = "rustls-tls-webpki-roots")] tls.root_store .add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS); + #[cfg(feature = "rustls-tls-native-roots")] + { + let roots_slice = NATIVE_ROOTS.as_ref().unwrap().roots.as_slice(); + tls.root_store.roots.extend_from_slice(roots_slice); + } if !config.certs_verification { tls.dangerous() @@ -1540,6 +1547,11 @@ fn add_cookie_header(headers: &mut HeaderMap, cookie_store: &cookie::CookieStore } } +#[cfg(feature = "rustls-tls-native-roots")] +lazy_static! { + static ref NATIVE_ROOTS: std::io::Result = rustls_native_certs::load_native_certs().map_err(|e| e.1); +} + #[cfg(test)] mod tests { #[tokio::test] diff --git a/src/lib.rs b/src/lib.rs index 642453c02..1277c1f43 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -174,7 +174,9 @@ //! - **rustls-tls-manual-roots**: Enables TLS functionality provided by `rustls`, //! without setting any root certificates. Roots have to be specified manually. //! - **rustls-tls-webpki-roots**: Enables TLS functionality provided by `rustls`, -//! while using root certificates from the `webpki-roots` crate +//! while using root certificates from the `webpki-roots` crate. +//! - **rustls-tls-native-roots**: Enables TLS functionality provided by `rustls`, +//! while using root certificates from the `rustls-native-certs` crate. //! - **blocking**: Provides the [blocking][] client API. //! - **cookies**: Provides cookie session support. //! - **gzip**: Provides response body gzip decompression. diff --git a/tests/badssl.rs b/tests/badssl.rs index 7ee5d2346..8eec030d4 100644 --- a/tests/badssl.rs +++ b/tests/badssl.rs @@ -18,7 +18,10 @@ async fn test_badssl_modern() { assert!(text.contains("mozilla-modern.badssl.com")); } -#[cfg(feature = "rustls-tls-webpki-roots")] +#[cfg(any( + feature = "rustls-tls-webpki-roots", + feature = "rustls-tls-native-roots" +))] #[tokio::test] async fn test_rustls_badssl_modern() { let text = reqwest::Client::builder()