Skip to content

Commit

Permalink
Use extension traits to simplify config
Browse files Browse the repository at this point in the history
  • Loading branch information
djc committed Oct 28, 2024
1 parent e81e0f4 commit dde835b
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 33 deletions.
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 9 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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();
```

Expand Down
2 changes: 1 addition & 1 deletion rustls-platform-verifier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
65 changes: 53 additions & 12 deletions rustls-platform-verifier/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
///
Expand All @@ -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
Expand All @@ -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<rustls::crypto::CryptoProvider>,
) -> Result<ClientConfig, rustls::Error> {
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())
}

Expand All @@ -88,3 +87,45 @@ pub fn tls_config_with_provider(
pub fn verifier_for_dbg(root: &[u8]) -> Arc<dyn rustls::client::danger::ServerCertVerifier> {
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<ClientConfig, WantsClientCert>;
}

impl BuilderVerifierExt for ConfigBuilder<ClientConfig, WantsVerifier> {
fn with_platform_verifier(self) -> ConfigBuilder<ClientConfig, WantsClientCert> {
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()
}
}

0 comments on commit dde835b

Please sign in to comment.