diff --git a/Cargo.lock b/Cargo.lock index 78eea86..6097d75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -266,9 +266,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" dependencies = [ "once_cell", "ring", @@ -303,9 +303,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-platform-verifier" @@ -335,9 +335,9 @@ version = "0.1.1" [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", diff --git a/README.md b/README.md index 90ec9fe..278f641 100644 --- a/README.md +++ b/README.md @@ -55,26 +55,21 @@ rustls-platform-verifier = "0.3" To get a rustls `ClientConfig` configured to use the platform verifier use: ```rust -let config = rustls_platform_verifier::tls_config(); +use rustls::ClientConfig; +use rustls_platform_verifier::ConfigVerifierExt; +let config = ClientConfig::with_platform_verifier(); ``` This crate will use the [rustls process-default crypto provider](https://docs.rs/rustls/latest/rustls/crypto/struct.CryptoProvider.html#using-the-per-process-default-cryptoprovider). To construct a `ClientConfig` with a different `CryptoProvider`, use: ```rust -let arc_crypto_provider = std::sync::Arc::new(rustls::crypto::ring::default_provider()); -let config = rustls_platform_verifier::tls_config_with_provider(arc_crypto_provider); -``` - -If you want to adapt the configuration, you can build the `ClientConfig` like this: - -```rust -use std::sync::Arc; use rustls::ClientConfig; -use rustls_platform_verifier::Verifier; - -let mut config = ClientConfig::builder() - .dangerous() // The `Verifier` we're using is actually safe - .with_custom_certificate_verifier(Arc::new(Verifier::new())) +use rustls_platform_verifier::BuilderVerifierExt; +let arc_crypto_provider = std::sync::Arc::new(rustls::crypto::ring::default_provider()); +let config = ClientConfig::builder_with_provider(arc_crypto_provider) + .with_safe_default_protocol_versions() + .unwrap() + .with_platform_verifier() .with_no_client_auth(); ``` diff --git a/rustls-platform-verifier/Cargo.toml b/rustls-platform-verifier/Cargo.toml index 002a52d..d1725f9 100644 --- a/rustls-platform-verifier/Cargo.toml +++ b/rustls-platform-verifier/Cargo.toml @@ -29,7 +29,7 @@ cert-logging = ["base64"] docsrs = ["jni"] [dependencies] -rustls = { version = "0.23", default-features = false, features = ["std"] } +rustls = { version = "0.23.16", default-features = false, features = ["std"] } log = { version = "0.4" } base64 = { version = "0.22", optional = true } # Only used when the `cert-logging` feature is enabled. jni = { version = "0.19", default-features = false, optional = true } # Only used during doc generation diff --git a/rustls-platform-verifier/src/lib.rs b/rustls-platform-verifier/src/lib.rs index 975ad0d..f254d0d 100644 --- a/rustls-platform-verifier/src/lib.rs +++ b/rustls-platform-verifier/src/lib.rs @@ -2,7 +2,7 @@ #![doc = include_str!("../README.md")] #![warn(missing_docs)] -use rustls::ClientConfig; +use rustls::{client::WantsClientCert, ClientConfig, ConfigBuilder, WantsVerifier}; use std::sync::Arc; mod verification; @@ -36,9 +36,11 @@ pub use tests::ffi::*; /// ```ignore /// # use reqwest::ClientBuilder; /// #[tokio::main] +/// use rustls_platform_verifier::ConfigVerifierExt; +/// /// async fn main() { /// let client = ClientBuilder::new() -/// .use_preconfigured_tls(rustls_platform_verifier::tls_config()) +/// .use_preconfigured_tls(ClientConfig::with_platform_verifier()) /// .build() /// .expect("nothing should fail"); /// @@ -49,17 +51,14 @@ pub use tests::ffi::*; /// **Important:** You must ensure that your `reqwest` version is using the same Rustls /// version as this crate or it will panic when downcasting the `&dyn Any` verifier. /// -/// If you require more control over the rustls `ClientConfig`, you can -/// instantiate a [Verifier] with [Verifier::default] and then use it -/// with [`DangerousClientConfigBuilder::with_custom_certificate_verifier`][rustls::client::danger::DangerousClientConfigBuilder::with_custom_certificate_verifier]. +/// If you require more control over the rustls [`ClientConfig`], you can import the +/// [`BuilderVerifierExt`] trait and call `.with_platform_verifier()` on the [`ConfigBuilder`]. /// /// Refer to the crate level documentation to see what platforms /// are currently supported. +#[deprecated(since = "0.4.0", note = "use the `ConfigVerifierExt` instead")] pub fn tls_config() -> ClientConfig { - ClientConfig::builder() - .dangerous() - .with_custom_certificate_verifier(Arc::new(Verifier::new())) - .with_no_client_auth() + ClientConfig::with_platform_verifier() } /// Attempts to construct a `rustls` configuration that verifies TLS certificates in the best way @@ -71,13 +70,13 @@ pub fn tls_config() -> ClientConfig { /// # Errors /// /// Propagates any error returned by [`rustls::ConfigBuilder::with_safe_default_protocol_versions`]. +#[deprecated(since = "0.4.0", note = "use the `BuilderVerifierExt` instead")] pub fn tls_config_with_provider( provider: Arc, ) -> Result { - Ok(ClientConfig::builder_with_provider(provider.clone()) + Ok(ClientConfig::builder_with_provider(provider) .with_safe_default_protocol_versions()? - .dangerous() - .with_custom_certificate_verifier(Arc::new(Verifier::new().with_provider(provider))) + .with_platform_verifier() .with_no_client_auth()) } @@ -88,3 +87,45 @@ pub fn tls_config_with_provider( pub fn verifier_for_dbg(root: &[u8]) -> Arc { Arc::new(Verifier::new_with_fake_root(root)) } + +/// Extension trait to help configure [`ClientConfig`]s with the platform verifier. +pub trait BuilderVerifierExt { + /// Configures the `ClientConfig` with the platform verifier. + /// + /// ```rust + /// use rustls::ClientConfig; + /// use rustls_platform_verifier::BuilderVerifierExt; + /// let config = ClientConfig::builder() + /// .with_platform_verifier() + /// .with_no_client_auth(); + /// ``` + fn with_platform_verifier(self) -> ConfigBuilder; +} + +impl BuilderVerifierExt for ConfigBuilder { + fn with_platform_verifier(self) -> ConfigBuilder { + let provider = self.crypto_provider().clone(); + self.dangerous() + .with_custom_certificate_verifier(Arc::new(Verifier::new().with_provider(provider))) + } +} + +/// Extension trait to help build a [`ClientConfig`] with the platform verifier. +pub trait ConfigVerifierExt { + /// Build a [`ClientConfig`] with the platform verifier and the default `CryptoProvider`. + /// + /// ```rust + /// use rustls::ClientConfig; + /// use rustls_platform_verifier::ConfigVerifierExt; + /// let config = ClientConfig::with_platform_verifier(); + /// ``` + fn with_platform_verifier() -> ClientConfig; +} + +impl ConfigVerifierExt for ClientConfig { + fn with_platform_verifier() -> ClientConfig { + ClientConfig::builder() + .with_platform_verifier() + .with_no_client_auth() + } +}