diff --git a/src/cert.rs b/src/cert.rs index 5c15628e..4dc8dd25 100644 --- a/src/cert.rs +++ b/src/cert.rs @@ -95,35 +95,33 @@ pub(crate) fn parse_cert_internal<'a>( subject_alt_name: None, }; - // mozilla::pkix allows the extensions to be omitted. However, since - // the subjectAltName extension is mandatory, the extensions are - // mandatory too, and we enforce that. Also, mozilla::pkix includes - // special logic for handling critical Netscape Cert Type extensions. - // That has been intentionally omitted. - - der::nested( - tbs, - der::Tag::ContextSpecificConstructed3, - Error::MissingOrMalformedExtensions, - |tagged| { - der::nested_of_mut( - tagged, - der::Tag::Sequence, - der::Tag::Sequence, - Error::BadDer, - |extension| { - let extn_id = der::expect_tag_and_get_value(extension, der::Tag::OID)?; - let critical = der::optional_boolean(extension)?; - let extn_value = - der::expect_tag_and_get_value(extension, der::Tag::OctetString)?; - match remember_extension(&mut cert, extn_id, extn_value)? { - Understood::No if critical => Err(Error::UnsupportedCriticalExtension), - _ => Ok(()), - } - }, - ) - }, - )?; + if !tbs.at_end() { + der::nested( + tbs, + der::Tag::ContextSpecificConstructed3, + Error::MalformedExtensions, + |tagged| { + der::nested_of_mut( + tagged, + der::Tag::Sequence, + der::Tag::Sequence, + Error::BadDer, + |extension| { + let extn_id = der::expect_tag_and_get_value(extension, der::Tag::OID)?; + let critical = der::optional_boolean(extension)?; + let extn_value = + der::expect_tag_and_get_value(extension, der::Tag::OctetString)?; + match remember_extension(&mut cert, extn_id, extn_value)? { + Understood::No if critical => { + Err(Error::UnsupportedCriticalExtension) + } + _ => Ok(()), + } + }, + ) + }, + )?; + } Ok(cert) }) diff --git a/src/error.rs b/src/error.rs index 7333f3d8..47961ab9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -74,12 +74,12 @@ pub enum Error { /// is malformed. UnsupportedCertVersion, - /// The certificate extensions are missing or malformed. + /// The certificate extensions are malformed. /// /// In particular, webpki requires the DNS name(s) be in the subjectAltName /// extension as required by the CA/Browser Forum Baseline Requirements /// and as recommended by RFC6125. - MissingOrMalformedExtensions, + MalformedExtensions, /// The certificate contains an unsupported critical extension. UnsupportedCriticalExtension, diff --git a/tests/cert_without_extensions.rs b/tests/cert_without_extensions.rs index 075f331f..cf31022f 100644 --- a/tests/cert_without_extensions.rs +++ b/tests/cert_without_extensions.rs @@ -20,8 +20,5 @@ fn cert_without_extensions_test() { // `openssl x509 -in cert_without_extensions.der -inform DER -text -noout` const CERT_WITHOUT_EXTENSIONS_DER: &[u8] = include_bytes!("cert_without_extensions.der"); - assert_eq!( - Some(webpki::Error::MissingOrMalformedExtensions), - webpki::EndEntityCert::try_from(CERT_WITHOUT_EXTENSIONS_DER).err() - ); + assert!(webpki::EndEntityCert::try_from(CERT_WITHOUT_EXTENSIONS_DER).is_ok()); }