diff --git a/src/name/verify.rs b/src/name/verify.rs index 6082c19e..5b895e65 100644 --- a/src/name/verify.rs +++ b/src/name/verify.rs @@ -70,10 +70,7 @@ pub fn check_name_constraints( if !inner.peek(subtrees_tag.into()) { return Ok(None); } - let subtrees = der::nested(inner, subtrees_tag, Error::BadDer, |tagged| { - der::expect_tag_and_get_value(tagged, der::Tag::Sequence) - })?; - Ok(Some(subtrees)) + der::expect_tag_and_get_value(inner, subtrees_tag).map(Some) } let permitted_subtrees = parse_subtrees(input, der::Tag::ContextSpecificConstructed0)?; @@ -167,6 +164,10 @@ fn check_presented_id_conforms_to_constraints_in_subtree( dns_name::presented_id_matches_constraint(name, base).ok_or(Error::BadDer) } + (GeneralName::DirectoryName(name), GeneralName::DnsName(base)) => { + common_name(name).map(|cn| cn == base) + } + (GeneralName::DirectoryName(name), GeneralName::DirectoryName(base)) => Ok( presented_directory_name_matches_constraint(name, base, subtrees), ), @@ -326,3 +327,18 @@ fn general_name<'a>(input: &mut untrusted::Reader<'a>) -> Result }; Ok(name) } + +static COMMON_NAME: untrusted::Input = untrusted::Input::from(&[85, 4, 3]); + +fn common_name(input: untrusted::Input) -> Result { + let inner = &mut untrusted::Reader::new(input); + der::nested(inner, der::Tag::Set, Error::BadDer, |tagged| { + der::nested(tagged, der::Tag::Sequence, Error::BadDer, |tagged| { + let value = der::expect_tag_and_get_value(tagged, der::Tag::OID)?; + if value != COMMON_NAME { + return Err(Error::BadDer); + } + der::expect_tag_and_get_value(tagged, der::Tag::UTF8String) + }) + }) +} diff --git a/tests/integration.rs b/tests/integration.rs index 598641d3..f47402a1 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -53,6 +53,25 @@ pub fn netflix() { ); } +#[cfg(feature = "alloc")] +#[test] +pub fn wpt() { + let ee: &[u8] = include_bytes!("wpt/ee.der"); + let ca = include_bytes!("wpt/ca.der"); + + let anchors = vec![webpki::TrustAnchor::try_from_cert_der(ca).unwrap()]; + let anchors = webpki::TlsServerTrustAnchors(&anchors); + + #[allow(clippy::unreadable_literal)] // TODO: Make this clear. + let time = webpki::Time::from_seconds_since_unix_epoch(1619256684); + + let cert = webpki::EndEntityCert::try_from(ee).unwrap(); + assert_eq!( + Ok(()), + cert.verify_is_valid_tls_server_cert(ALL_SIGALGS, &anchors, &[], time) + ); +} + #[test] pub fn ed25519() { let ee: &[u8] = include_bytes!("ed25519/ee.der"); diff --git a/tests/wpt/ca.der b/tests/wpt/ca.der new file mode 100644 index 00000000..f7d00160 Binary files /dev/null and b/tests/wpt/ca.der differ diff --git a/tests/wpt/ee.der b/tests/wpt/ee.der new file mode 100644 index 00000000..7160db5a Binary files /dev/null and b/tests/wpt/ee.der differ