diff --git a/src/verify_cert.rs b/src/verify_cert.rs index d9f60745..657926dd 100644 --- a/src/verify_cert.rs +++ b/src/verify_cert.rs @@ -446,18 +446,14 @@ impl KeyUsage { /// /// As specified in , this does not require the certificate to specify the eKU extension. pub const fn server_auth() -> Self { - Self { - inner: ExtendedKeyUsage::RequiredIfPresent(EKU_SERVER_AUTH), - } + KeyUsage::required_if_present(EKU_SERVER_AUTH) } /// Construct a new [`KeyUsage`] as appropriate for client certificate authentication. /// /// As specified in <>, this does not require the certificate to specify the eKU extension. pub const fn client_auth() -> Self { - Self { - inner: ExtendedKeyUsage::RequiredIfPresent(EKU_CLIENT_AUTH), - } + KeyUsage::required_if_present(EKU_CLIENT_AUTH) } /// Construct a new [`KeyUsage`] requiring a certificate to support the specified OID. @@ -466,6 +462,13 @@ impl KeyUsage { inner: ExtendedKeyUsage::Required(KeyPurposeId::new(oid)), } } + + /// Construct a new [`KeyUsage`] requiring a certificate to support the specified OID, if the certificate has EKUs. + pub const fn required_if_present(oid: &'static [u8]) -> Self { + Self { + inner: ExtendedKeyUsage::RequiredIfPresent(KeyPurposeId::new(oid)), + } + } } /// Extended Key Usage (EKU) of a certificate. @@ -543,10 +546,10 @@ impl Eq for KeyPurposeId {} // id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } // id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } -const EKU_SERVER_AUTH: KeyPurposeId = KeyPurposeId::new(&oid!(1, 3, 6, 1, 5, 5, 7, 3, 1)); +const EKU_SERVER_AUTH: &[u8] = &oid!(1, 3, 6, 1, 5, 5, 7, 3, 1); // id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } -const EKU_CLIENT_AUTH: KeyPurposeId = KeyPurposeId::new(&oid!(1, 3, 6, 1, 5, 5, 7, 3, 2)); +const EKU_CLIENT_AUTH: &[u8] = &oid!(1, 3, 6, 1, 5, 5, 7, 3, 2); fn loop_while_non_fatal_error<'a, V: 'a>( default_error: Error, @@ -705,8 +708,10 @@ mod tests { #[test] fn eku_key_purpose_id() { - assert!(ExtendedKeyUsage::RequiredIfPresent(EKU_SERVER_AUTH) - .key_purpose_id_equals(EKU_SERVER_AUTH.oid_value)) + assert!( + ExtendedKeyUsage::RequiredIfPresent(KeyPurposeId::new(EKU_SERVER_AUTH)) + .key_purpose_id_equals(KeyPurposeId::new(EKU_SERVER_AUTH).oid_value) + ) } #[cfg(feature = "alloc")] diff --git a/tests/custom_ekus.rs b/tests/custom_ekus.rs index 3c6bd7b3..9d4465ca 100644 --- a/tests/custom_ekus.rs +++ b/tests/custom_ekus.rs @@ -61,3 +61,18 @@ pub fn verify_custom_eku_client() { check_cert(ee, ca, KeyUsage::client_auth(), time, Ok(())); check_cert(ee, ca, KeyUsage::server_auth(), time, Ok(())); } + +#[test] +pub fn verify_custom_eku_required_if_present() { + let time = UnixTime::since_unix_epoch(Duration::from_secs(0x1fed_f00d)); + + let eku = KeyUsage::required_if_present(&[43, 6, 1, 5, 5, 7, 3, 2]); + + let ee = include_bytes!("client_auth/cert_with_no_eku_accepted_for_client_auth.ee.der"); + let ca = include_bytes!("client_auth/cert_with_no_eku_accepted_for_client_auth.ca.der"); + check_cert(ee, ca, eku, time, Ok(())); + + let ee = include_bytes!("client_auth/cert_with_both_ekus_accepted_for_client_auth.ee.der"); + let ca = include_bytes!("client_auth/cert_with_both_ekus_accepted_for_client_auth.ca.der"); + check_cert(ee, ca, eku, time, Ok(())); +}