mirror of https://github.com/ctz/rustls
Add support for enforcing CRL expiration
This commit is contained in:
parent
e0c97ec982
commit
398931ab7e
|
@ -2,7 +2,7 @@ use alloc::sync::Arc;
|
|||
use alloc::vec::Vec;
|
||||
|
||||
use pki_types::{CertificateDer, CertificateRevocationListDer, UnixTime};
|
||||
use webpki::{CertRevocationList, RevocationCheckDepth, UnknownStatusPolicy};
|
||||
use webpki::{CertRevocationList, ExpirationPolicy, RevocationCheckDepth, UnknownStatusPolicy};
|
||||
|
||||
use super::{pki_error, VerifierBuilderError};
|
||||
#[cfg(doc)]
|
||||
|
@ -30,6 +30,7 @@ pub struct ClientCertVerifierBuilder {
|
|||
crls: Vec<CertificateRevocationListDer<'static>>,
|
||||
revocation_check_depth: RevocationCheckDepth,
|
||||
unknown_revocation_policy: UnknownStatusPolicy,
|
||||
revocation_expiration_policy: ExpirationPolicy,
|
||||
anon_policy: AnonymousClientPolicy,
|
||||
supported_algs: WebPkiSupportedAlgorithms,
|
||||
}
|
||||
|
@ -46,6 +47,7 @@ impl ClientCertVerifierBuilder {
|
|||
anon_policy: AnonymousClientPolicy::Deny,
|
||||
revocation_check_depth: RevocationCheckDepth::Chain,
|
||||
unknown_revocation_policy: UnknownStatusPolicy::Deny,
|
||||
revocation_expiration_policy: ExpirationPolicy::Ignore,
|
||||
supported_algs,
|
||||
}
|
||||
}
|
||||
|
@ -138,6 +140,19 @@ impl ClientCertVerifierBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
/// Enforce the CRL nextUpdate field (i.e. expiration)
|
||||
///
|
||||
/// If CRLs are provided with [`with_crls`][Self::with_crls] and the verification time is
|
||||
/// beyond the time in the CRL nextUpdate field, it is expired and treated as an error condition.
|
||||
/// Overrides the default behavior where expired CRLs are not treated as an error condition.
|
||||
///
|
||||
/// If no CRLs are provided then this setting has no effect as revocation status checks
|
||||
/// are not performed.
|
||||
pub fn enforce_revocation_expiration(mut self) -> Self {
|
||||
self.revocation_expiration_policy = ExpirationPolicy::Enforce;
|
||||
self
|
||||
}
|
||||
|
||||
/// Build a client certificate verifier. The built verifier will be used for the server to offer
|
||||
/// client certificate authentication, to control how offered client certificates are validated,
|
||||
/// and to determine what to do with anonymous clients that do not respond to the client
|
||||
|
@ -165,6 +180,7 @@ impl ClientCertVerifierBuilder {
|
|||
parse_crls(self.crls)?,
|
||||
self.revocation_check_depth,
|
||||
self.unknown_revocation_policy,
|
||||
self.revocation_expiration_policy,
|
||||
self.anon_policy,
|
||||
self.supported_algs,
|
||||
)))
|
||||
|
@ -237,6 +253,7 @@ pub struct WebPkiClientVerifier {
|
|||
crls: Vec<CertRevocationList<'static>>,
|
||||
revocation_check_depth: RevocationCheckDepth,
|
||||
unknown_revocation_policy: UnknownStatusPolicy,
|
||||
revocation_expiration_policy: ExpirationPolicy,
|
||||
anonymous_policy: AnonymousClientPolicy,
|
||||
supported_algs: WebPkiSupportedAlgorithms,
|
||||
}
|
||||
|
@ -305,6 +322,7 @@ impl WebPkiClientVerifier {
|
|||
crls: Vec<CertRevocationList<'static>>,
|
||||
revocation_check_depth: RevocationCheckDepth,
|
||||
unknown_revocation_policy: UnknownStatusPolicy,
|
||||
revocation_expiration_policy: ExpirationPolicy,
|
||||
anonymous_policy: AnonymousClientPolicy,
|
||||
supported_algs: WebPkiSupportedAlgorithms,
|
||||
) -> Self {
|
||||
|
@ -314,6 +332,7 @@ impl WebPkiClientVerifier {
|
|||
crls,
|
||||
revocation_check_depth,
|
||||
unknown_revocation_policy,
|
||||
revocation_expiration_policy,
|
||||
anonymous_policy,
|
||||
supported_algs,
|
||||
}
|
||||
|
@ -356,6 +375,7 @@ impl ClientCertVerifier for WebPkiClientVerifier {
|
|||
.unwrap()
|
||||
.with_depth(self.revocation_check_depth)
|
||||
.with_status_policy(self.unknown_revocation_policy)
|
||||
.with_expiration_policy(self.revocation_expiration_policy)
|
||||
.build(),
|
||||
)
|
||||
};
|
||||
|
@ -605,6 +625,20 @@ test_for_each_provider! {
|
|||
builder.build().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_client_verifier_enforce_expiration() {
|
||||
// We should be able to build a client verifier that allows unknown revocation status
|
||||
let builder = WebPkiClientVerifier::builder_with_provider(
|
||||
test_roots(),
|
||||
provider::default_provider().into(),
|
||||
)
|
||||
.with_crls(test_crls())
|
||||
.enforce_revocation_expiration();
|
||||
// The builder should be Debug.
|
||||
println!("{:?}", builder);
|
||||
builder.build().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_builder_no_roots() {
|
||||
// Trying to create a client verifier builder with no trust anchors should fail at build time
|
||||
|
|
|
@ -2,7 +2,7 @@ use alloc::sync::Arc;
|
|||
use alloc::vec::Vec;
|
||||
|
||||
use pki_types::{CertificateDer, CertificateRevocationListDer, ServerName, UnixTime};
|
||||
use webpki::{CertRevocationList, RevocationCheckDepth, UnknownStatusPolicy};
|
||||
use webpki::{CertRevocationList, ExpirationPolicy, RevocationCheckDepth, UnknownStatusPolicy};
|
||||
|
||||
use crate::crypto::{CryptoProvider, WebPkiSupportedAlgorithms};
|
||||
#[cfg(feature = "logging")]
|
||||
|
@ -28,6 +28,7 @@ pub struct ServerCertVerifierBuilder {
|
|||
crls: Vec<CertificateRevocationListDer<'static>>,
|
||||
revocation_check_depth: RevocationCheckDepth,
|
||||
unknown_revocation_policy: UnknownStatusPolicy,
|
||||
revocation_expiration_policy: ExpirationPolicy,
|
||||
supported_algs: WebPkiSupportedAlgorithms,
|
||||
}
|
||||
|
||||
|
@ -41,6 +42,7 @@ impl ServerCertVerifierBuilder {
|
|||
crls: Vec::new(),
|
||||
revocation_check_depth: RevocationCheckDepth::Chain,
|
||||
unknown_revocation_policy: UnknownStatusPolicy::Deny,
|
||||
revocation_expiration_policy: ExpirationPolicy::Ignore,
|
||||
supported_algs,
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +85,19 @@ impl ServerCertVerifierBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
/// Enforce the CRL nextUpdate field (i.e. expiration)
|
||||
///
|
||||
/// If CRLs are provided with [`with_crls`][Self::with_crls] and the verification time is
|
||||
/// beyond the time in the CRL nextUpdate field, it is expired and treated as an error condition.
|
||||
/// Overrides the default behavior where expired CRLs are not treated as an error condition.
|
||||
///
|
||||
/// If no CRLs are provided then this setting has no effect as revocation status checks
|
||||
/// are not performed.
|
||||
pub fn enforce_revocation_expiration(mut self) -> Self {
|
||||
self.revocation_expiration_policy = ExpirationPolicy::Enforce;
|
||||
self
|
||||
}
|
||||
|
||||
/// Build a server certificate verifier, allowing control over the root certificates to use as
|
||||
/// trust anchors, and to control how server certificate revocation checking is performed.
|
||||
///
|
||||
|
@ -107,6 +122,7 @@ impl ServerCertVerifierBuilder {
|
|||
parse_crls(self.crls)?,
|
||||
self.revocation_check_depth,
|
||||
self.unknown_revocation_policy,
|
||||
self.revocation_expiration_policy,
|
||||
self.supported_algs,
|
||||
)
|
||||
.into())
|
||||
|
@ -121,6 +137,7 @@ pub struct WebPkiServerVerifier {
|
|||
crls: Vec<CertRevocationList<'static>>,
|
||||
revocation_check_depth: RevocationCheckDepth,
|
||||
unknown_revocation_policy: UnknownStatusPolicy,
|
||||
revocation_expiration_policy: ExpirationPolicy,
|
||||
supported: WebPkiSupportedAlgorithms,
|
||||
}
|
||||
|
||||
|
@ -167,6 +184,7 @@ impl WebPkiServerVerifier {
|
|||
Vec::default(),
|
||||
RevocationCheckDepth::Chain,
|
||||
UnknownStatusPolicy::Allow,
|
||||
ExpirationPolicy::Ignore,
|
||||
supported_algs,
|
||||
)
|
||||
}
|
||||
|
@ -187,6 +205,7 @@ impl WebPkiServerVerifier {
|
|||
crls: Vec<CertRevocationList<'static>>,
|
||||
revocation_check_depth: RevocationCheckDepth,
|
||||
unknown_revocation_policy: UnknownStatusPolicy,
|
||||
revocation_expiration_policy: ExpirationPolicy,
|
||||
supported: WebPkiSupportedAlgorithms,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -194,6 +213,7 @@ impl WebPkiServerVerifier {
|
|||
crls,
|
||||
revocation_check_depth,
|
||||
unknown_revocation_policy,
|
||||
revocation_expiration_policy,
|
||||
supported,
|
||||
}
|
||||
}
|
||||
|
@ -234,6 +254,7 @@ impl ServerCertVerifier for WebPkiServerVerifier {
|
|||
.unwrap()
|
||||
.with_depth(self.revocation_check_depth)
|
||||
.with_status_policy(self.unknown_revocation_policy)
|
||||
.with_expiration_policy(self.revocation_expiration_policy)
|
||||
.build(),
|
||||
)
|
||||
};
|
||||
|
@ -413,4 +434,18 @@ test_for_each_provider! {
|
|||
println!("{:?}", builder);
|
||||
builder.build().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_server_verifier_enforce_expiration() {
|
||||
// We should be able to build a server cert. verifier that allows unknown revocation
|
||||
// status.
|
||||
let builder = WebPkiServerVerifier::builder_with_provider(
|
||||
test_roots(),
|
||||
provider::default_provider().into(),
|
||||
)
|
||||
.enforce_revocation_expiration();
|
||||
// The builder should be Debug.
|
||||
println!("{:?}", builder);
|
||||
builder.build().unwrap();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue