Skip to content

Commit ae5f7a8

Browse files
jbrcpu
authored andcommitted
feat: add Verifier::set_provider and Verifier::with_provider
1 parent b6f6334 commit ae5f7a8

File tree

5 files changed

+79
-54
lines changed

5 files changed

+79
-54
lines changed

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

+8-15
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

+9-16
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

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use rustls::crypto::CryptoProvider;
2+
use std::sync::Arc;
3+
14
#[cfg(all(
25
any(unix, target_arch = "wasm32"),
36
not(target_os = "android"),
@@ -64,7 +67,7 @@ fn log_server_cert(_end_entity: &rustls::pki_types::CertificateDer<'_>) {
6467
#[cfg(any(windows, target_os = "macos", target_os = "ios"))]
6568
fn invalid_certificate(reason: impl Into<String>) -> rustls::Error {
6669
rustls::Error::InvalidCertificate(rustls::CertificateError::Other(rustls::OtherError(
67-
std::sync::Arc::from(Box::from(reason.into())),
70+
Arc::from(Box::from(reason.into())),
6871
)))
6972
}
7073

@@ -77,3 +80,30 @@ fn invalid_certificate(reason: impl Into<String>) -> rustls::Error {
7780
/// - id-kp-serverAuth
7881
// TODO: Chromium also allows for `OID_ANY_EKU` on Android.
7982
pub const ALLOWED_EKUS: &[&str] = &["1.3.6.1.5.5.7.3.1"];
83+
84+
impl Verifier {
85+
/// Chainable setter to configure the [`CryptoProvider`] for this `Verifier`.
86+
///
87+
/// This will be used instead of the rustls processs-default `CryptoProvider`, even if one has
88+
/// been installed.
89+
pub fn with_provider(mut self, crypto_provider: Arc<CryptoProvider>) -> Self {
90+
self.set_provider(crypto_provider);
91+
self
92+
}
93+
94+
/// Configures the [`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(&mut self, crypto_provider: Arc<CryptoProvider>) {
99+
self.crypto_provider = crypto_provider.into();
100+
}
101+
102+
fn get_provider(&self) -> &Arc<CryptoProvider> {
103+
self.crypto_provider.get_or_init(|| {
104+
CryptoProvider::get_default()
105+
.expect("rustls default CryptoProvider not set")
106+
.clone()
107+
})
108+
}
109+
}

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

+23-7
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,24 @@ 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.
3643
pub fn new() -> Self {
3744
Self {
3845
inner: OnceCell::new(),
3946
extra_roots: Vec::new().into(),
4047
#[cfg(any(test, feature = "ffi-testing", feature = "dbg"))]
4148
test_only_root_ca_override: None,
49+
crypto_provider: OnceCell::new(),
4250
}
4351
}
4452

@@ -53,6 +61,7 @@ impl Verifier {
5361
extra_roots: roots.into_iter().collect::<Vec<_>>().into(),
5462
#[cfg(any(test, feature = "ffi-testing", feature = "dbg"))]
5563
test_only_root_ca_override: None,
64+
crypto_provider: OnceCell::new(),
5665
}
5766
}
5867

@@ -63,6 +72,7 @@ impl Verifier {
6372
inner: OnceCell::new(),
6473
extra_roots: Vec::new().into(),
6574
test_only_root_ca_override: Some(root.into()),
75+
crypto_provider: OnceCell::new(),
6676
}
6777
}
6878

@@ -85,9 +95,12 @@ impl Verifier {
8595
if (added != 1) || (ignored != 0) {
8696
panic!("Failed to insert fake, test-only root trust anchor");
8797
}
88-
return Ok(WebPkiServerVerifier::builder(root_store.into())
89-
.build()
90-
.unwrap());
98+
return Ok(WebPkiServerVerifier::builder_with_provider(
99+
root_store.into(),
100+
Arc::clone(self.get_provider()),
101+
)
102+
.build()
103+
.unwrap());
91104
}
92105
}
93106

@@ -143,9 +156,12 @@ impl Verifier {
143156
}));
144157
};
145158

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

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

+8-15
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)