Skip to content

Commit e885f64

Browse files
committed
feat: add Verifier::set_provider and Verifier::with_provider
1 parent b6f6334 commit e885f64

File tree

5 files changed

+82
-53
lines changed

5 files changed

+82
-53
lines changed

rustls-platform-verifier/src/verification/android.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub struct Verifier {
4747
/// Testing only: The root CA certificate to trust.
4848
#[cfg(any(test, feature = "ffi-testing"))]
4949
test_only_root_ca_override: Option<Vec<u8>>,
50-
default_provider: OnceCell<Arc<CryptoProvider>>,
50+
pub(super) crypto_provider: OnceCell<Arc<CryptoProvider>>,
5151
}
5252

5353
impl Default for Verifier {
@@ -71,13 +71,16 @@ impl Drop for Verifier {
7171

7272
impl Verifier {
7373
/// Creates a new instance of a TLS certificate verifier that utilizes the
74-
/// Android certificate facilities. The rustls default [`CryptoProvider`]
75-
/// must be set before the verifier can be used.
74+
/// Android certificate facilities.
75+
///
76+
/// A [`CryptoProvider`] must be set with
77+
/// [`set_provider`][Verifier::set_provider]/[`with_provider`][Verifier::with_provider] or
78+
/// [`CryptoProvider::install_default`] before the verifier can be used.
7679
pub fn new() -> Self {
7780
Self {
7881
#[cfg(any(test, feature = "ffi-testing"))]
7982
test_only_root_ca_override: None,
80-
default_provider: OnceCell::new(),
83+
crypto_provider: OnceCell::new(),
8184
}
8285
}
8386

@@ -86,20 +89,10 @@ impl Verifier {
8689
pub(crate) fn new_with_fake_root(root: &[u8]) -> Self {
8790
Self {
8891
test_only_root_ca_override: Some(root.into()),
89-
default_provider: OnceCell::new(),
92+
crypto_provider: OnceCell::new(),
9093
}
9194
}
9295

93-
fn get_provider(&self) -> &CryptoProvider {
94-
self.default_provider
95-
.get_or_init(|| {
96-
rustls::crypto::CryptoProvider::get_default()
97-
.expect("rustls default CryptoProvider not set")
98-
.clone()
99-
})
100-
.as_ref()
101-
}
102-
10396
fn verify_certificate(
10497
&self,
10598
end_entity: &pki_types::CertificateDer<'_>,

rustls-platform-verifier/src/verification/apple.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,21 @@ pub struct Verifier {
4646
/// Testing only: The root CA certificate to trust.
4747
#[cfg(any(test, feature = "ffi-testing", feature = "dbg"))]
4848
test_only_root_ca_override: Option<Vec<u8>>,
49-
default_provider: OnceCell<Arc<CryptoProvider>>,
49+
pub(super) crypto_provider: OnceCell<Arc<CryptoProvider>>,
5050
}
5151

5252
impl Verifier {
53-
/// Creates a new instance of a TLS certificate verifier that utilizes the
54-
/// macOS certificate facilities. The rustls default [`CryptoProvider`]
55-
/// must be set before the verifier can be used.
53+
/// Creates a new instance of a TLS certificate verifier that utilizes the macOS certificate
54+
/// facilities.
55+
///
56+
/// A [`CryptoProvider`] must be set with
57+
/// [`set_provider`][Verifier::set_provider]/[`with_provider`][Verifier::with_provider] or
58+
/// [`CryptoProvider::install_default`] before the verifier can be used.
5659
pub fn new() -> Self {
5760
Self {
5861
#[cfg(any(test, feature = "ffi-testing", feature = "dbg"))]
5962
test_only_root_ca_override: None,
60-
default_provider: OnceCell::new(),
63+
crypto_provider: OnceCell::new(),
6164
}
6265
}
6366

@@ -66,20 +69,10 @@ impl Verifier {
6669
pub(crate) fn new_with_fake_root(root: &[u8]) -> Self {
6770
Self {
6871
test_only_root_ca_override: Some(root.into()),
69-
default_provider: OnceCell::new(),
72+
crypto_provider: OnceCell::new(),
7073
}
7174
}
7275

73-
fn get_provider(&self) -> &CryptoProvider {
74-
self.default_provider
75-
.get_or_init(|| {
76-
rustls::crypto::CryptoProvider::get_default()
77-
.expect("rustls default CryptoProvider not set")
78-
.clone()
79-
})
80-
.as_ref()
81-
}
82-
8376
fn verify_certificate(
8477
&self,
8578
end_entity: &pki_types::CertificateDer<'_>,

rustls-platform-verifier/src/verification/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,36 @@ fn invalid_certificate(reason: impl Into<String>) -> rustls::Error {
7777
/// - id-kp-serverAuth
7878
// TODO: Chromium also allows for `OID_ANY_EKU` on Android.
7979
pub const ALLOWED_EKUS: &[&str] = &["1.3.6.1.5.5.7.3.1"];
80+
81+
impl Verifier {
82+
/// Chainable setter to configure the [`CryptoProvider`][rustls::crypto::CryptoProvider] for this `Verifier`.
83+
///
84+
/// This will be used instead of the rustls processs-default `CryptoProvider`, even if one has
85+
/// been installed.
86+
pub fn with_provider(
87+
mut self,
88+
crypto_provider: std::sync::Arc<rustls::crypto::CryptoProvider>,
89+
) -> Self {
90+
self.set_provider(crypto_provider);
91+
self
92+
}
93+
94+
/// Configures the [`CryptoProvider`][rustls::crypto::CryptoProvider] for this `Verifier`.
95+
///
96+
/// This will be used instead of the rustls processs-default `CryptoProvider`, even if one has
97+
/// been installed.
98+
pub fn set_provider(
99+
&mut self,
100+
crypto_provider: std::sync::Arc<rustls::crypto::CryptoProvider>,
101+
) {
102+
self.crypto_provider = crypto_provider.into();
103+
}
104+
105+
fn get_provider(&self) -> &std::sync::Arc<rustls::crypto::CryptoProvider> {
106+
self.crypto_provider.get_or_init(|| {
107+
rustls::crypto::CryptoProvider::get_default()
108+
.expect("rustls default CryptoProvider not set")
109+
.clone()
110+
})
111+
}
112+
}

rustls-platform-verifier/src/verification/others.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, Server
44
use rustls::client::WebPkiServerVerifier;
55
use rustls::pki_types;
66
use rustls::{
7-
CertificateError, DigitallySignedStruct, Error as TlsError, OtherError, SignatureScheme,
7+
crypto::CryptoProvider, CertificateError, DigitallySignedStruct, Error as TlsError, OtherError,
8+
SignatureScheme,
89
};
910
use std::fmt::Debug;
1011
use std::sync::{Arc, Mutex};
@@ -28,17 +29,25 @@ pub struct Verifier {
2829
/// Testing only: an additional root CA certificate to trust.
2930
#[cfg(any(test, feature = "ffi-testing", feature = "dbg"))]
3031
test_only_root_ca_override: Option<Vec<u8>>,
32+
33+
pub(super) crypto_provider: OnceCell<Arc<CryptoProvider>>,
3134
}
3235

3336
impl Verifier {
3437
/// Creates a new verifier whose certificate validation is provided by
3538
/// WebPKI, using root certificates provided by the platform.
39+
///
40+
/// A [`CryptoProvider`] must be set with
41+
/// [`set_provider`][Verifier::set_provider]/[`with_provider`][Verifier::with_provider] or
42+
/// [`CryptoProvider::install_default`] before the verifier can be used.
43+
3644
pub fn new() -> Self {
3745
Self {
3846
inner: OnceCell::new(),
3947
extra_roots: Vec::new().into(),
4048
#[cfg(any(test, feature = "ffi-testing", feature = "dbg"))]
4149
test_only_root_ca_override: None,
50+
crypto_provider: OnceCell::new(),
4251
}
4352
}
4453

@@ -53,6 +62,7 @@ impl Verifier {
5362
extra_roots: roots.into_iter().collect::<Vec<_>>().into(),
5463
#[cfg(any(test, feature = "ffi-testing", feature = "dbg"))]
5564
test_only_root_ca_override: None,
65+
crypto_provider: OnceCell::new(),
5666
}
5767
}
5868

@@ -63,6 +73,7 @@ impl Verifier {
6373
inner: OnceCell::new(),
6474
extra_roots: Vec::new().into(),
6575
test_only_root_ca_override: Some(root.into()),
76+
crypto_provider: OnceCell::new(),
6677
}
6778
}
6879

@@ -85,9 +96,12 @@ impl Verifier {
8596
if (added != 1) || (ignored != 0) {
8697
panic!("Failed to insert fake, test-only root trust anchor");
8798
}
88-
return Ok(WebPkiServerVerifier::builder(root_store.into())
89-
.build()
90-
.unwrap());
99+
return Ok(WebPkiServerVerifier::builder_with_provider(
100+
root_store.into(),
101+
Arc::clone(self.get_provider()),
102+
)
103+
.build()
104+
.unwrap());
91105
}
92106
}
93107

@@ -143,9 +157,12 @@ impl Verifier {
143157
}));
144158
};
145159

146-
WebPkiServerVerifier::builder(root_store.into())
147-
.build()
148-
.map_err(|e| TlsError::Other(OtherError(Arc::new(e))))
160+
WebPkiServerVerifier::builder_with_provider(
161+
root_store.into(),
162+
Arc::clone(self.get_provider()),
163+
)
164+
.build()
165+
.map_err(|e| TlsError::Other(OtherError(Arc::new(e))))
149166
}
150167
}
151168

rustls-platform-verifier/src/verification/windows.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -421,18 +421,21 @@ pub struct Verifier {
421421
/// Testing only: The root CA certificate to trust.
422422
#[cfg(any(test, feature = "ffi-testing", feature = "dbg"))]
423423
test_only_root_ca_override: Option<Vec<u8>>,
424-
default_provider: OnceCell<Arc<CryptoProvider>>,
424+
pub(super) crypto_provider: OnceCell<Arc<CryptoProvider>>,
425425
}
426426

427427
impl Verifier {
428428
/// Creates a new instance of a TLS certificate verifier that utilizes the
429-
/// Windows certificate facilities. The rustls default [`CryptoProvider`]
430-
/// must be set before the verifier can be used.
429+
/// Windows certificate facilities.
430+
///
431+
/// A [`CryptoProvider`] must be set with
432+
/// [`set_provider`][Verifier::set_provider]/[`with_provider`][Verifier::with_provider] or
433+
/// [`CryptoProvider::install_default`] before the verifier can be used.
431434
pub fn new() -> Self {
432435
Self {
433436
#[cfg(any(test, feature = "ffi-testing", feature = "dbg"))]
434437
test_only_root_ca_override: None,
435-
default_provider: OnceCell::new(),
438+
crypto_provider: OnceCell::new(),
436439
}
437440
}
438441

@@ -441,20 +444,10 @@ impl Verifier {
441444
pub(crate) fn new_with_fake_root(root: &[u8]) -> Self {
442445
Self {
443446
test_only_root_ca_override: Some(root.into()),
444-
default_provider: OnceCell::new(),
447+
crypto_provider: OnceCell::new(),
445448
}
446449
}
447450

448-
fn get_provider(&self) -> &CryptoProvider {
449-
self.default_provider
450-
.get_or_init(|| {
451-
rustls::crypto::CryptoProvider::get_default()
452-
.expect("rustls default CryptoProvider not set")
453-
.clone()
454-
})
455-
.as_ref()
456-
}
457-
458451
/// Verifies a certificate and its chain for the specified `server`.
459452
///
460453
/// Return `Ok(())` if the certificate was valid.

0 commit comments

Comments
 (0)