blob: e0d8f2ef7b7cf45d31224f750a8bcd1a759fd8ad [file] [log] [blame]
// Copyright 2022 Joseph Birr-Pixton.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#![cfg(feature = "alloc")]
use webpki::KeyUsage;
static ALL_SIGALGS: &[&webpki::SignatureAlgorithm] = &[
&webpki::ECDSA_P256_SHA256,
&webpki::ECDSA_P256_SHA384,
&webpki::ECDSA_P384_SHA256,
&webpki::ECDSA_P384_SHA384,
&webpki::ED25519,
&webpki::RSA_PKCS1_2048_8192_SHA256,
&webpki::RSA_PKCS1_2048_8192_SHA384,
&webpki::RSA_PKCS1_2048_8192_SHA512,
&webpki::RSA_PKCS1_3072_8192_SHA384,
];
fn check_cert(
ee: &[u8],
ca: &[u8],
valid_names: &[&str],
invalid_names: &[&str],
) -> Result<(), webpki::Error> {
let anchors = [webpki::TrustAnchor::try_from_cert_der(ca).unwrap()];
let time = webpki::Time::from_seconds_since_unix_epoch(0x1fed_f00d);
let cert = webpki::EndEntityCert::try_from(ee).unwrap();
cert.verify_for_usage(
ALL_SIGALGS,
&anchors,
&[],
time,
KeyUsage::server_auth(),
&[],
)?;
for valid in valid_names {
let name = webpki::SubjectNameRef::try_from_ascii_str(valid).unwrap();
assert_eq!(cert.verify_is_valid_for_subject_name(name), Ok(()));
}
for invalid in invalid_names {
let name = webpki::SubjectNameRef::try_from_ascii_str(invalid).unwrap();
assert_eq!(
cert.verify_is_valid_for_subject_name(name),
Err(webpki::Error::CertNotValidForName)
);
}
Ok(())
}
// DO NOT EDIT BELOW: generated by tests/generate.py
#[test]
fn no_name_constraints() {
let ee = include_bytes!("tls_server_certs/no_name_constraints.ee.der");
let ca = include_bytes!("tls_server_certs/no_name_constraints.ca.der");
assert_eq!(
check_cert(ee, ca, &["dns.example.com"], &["subject.example.com"]),
Ok(())
);
}
#[test]
fn additional_dns_labels() {
let ee = include_bytes!("tls_server_certs/additional_dns_labels.ee.der");
let ca = include_bytes!("tls_server_certs/additional_dns_labels.ca.der");
assert_eq!(
check_cert(
ee,
ca,
&["host1.example.com", "host2.example.com"],
&["subject.example.com"]
),
Ok(())
);
}
#[test]
fn disallow_subject_common_name() {
let ee = include_bytes!("tls_server_certs/disallow_subject_common_name.ee.der");
let ca = include_bytes!("tls_server_certs/disallow_subject_common_name.ca.der");
assert_eq!(
check_cert(ee, ca, &[], &[]),
Err(webpki::Error::NameConstraintViolation)
);
}
#[test]
fn disallow_dns_san() {
let ee = include_bytes!("tls_server_certs/disallow_dns_san.ee.der");
let ca = include_bytes!("tls_server_certs/disallow_dns_san.ca.der");
assert_eq!(
check_cert(ee, ca, &[], &[]),
Err(webpki::Error::NameConstraintViolation)
);
}
#[test]
fn allow_subject_common_name() {
let ee = include_bytes!("tls_server_certs/allow_subject_common_name.ee.der");
let ca = include_bytes!("tls_server_certs/allow_subject_common_name.ca.der");
assert_eq!(check_cert(ee, ca, &[], &["allowed.example.com"]), Ok(()));
}
#[test]
fn allow_dns_san() {
let ee = include_bytes!("tls_server_certs/allow_dns_san.ee.der");
let ca = include_bytes!("tls_server_certs/allow_dns_san.ca.der");
assert_eq!(check_cert(ee, ca, &["allowed.example.com"], &[]), Ok(()));
}
#[test]
fn allow_dns_san_and_subject_common_name() {
let ee = include_bytes!("tls_server_certs/allow_dns_san_and_subject_common_name.ee.der");
let ca = include_bytes!("tls_server_certs/allow_dns_san_and_subject_common_name.ca.der");
assert_eq!(
check_cert(
ee,
ca,
&["allowed-san.example.com"],
&["allowed-cn.example.com"]
),
Ok(())
);
}
#[test]
fn allow_dns_san_and_disallow_subject_common_name() {
let ee =
include_bytes!("tls_server_certs/allow_dns_san_and_disallow_subject_common_name.ee.der");
let ca =
include_bytes!("tls_server_certs/allow_dns_san_and_disallow_subject_common_name.ca.der");
assert_eq!(
check_cert(ee, ca, &[], &[]),
Err(webpki::Error::NameConstraintViolation)
);
}
#[test]
fn disallow_dns_san_and_allow_subject_common_name() {
let ee =
include_bytes!("tls_server_certs/disallow_dns_san_and_allow_subject_common_name.ee.der");
let ca =
include_bytes!("tls_server_certs/disallow_dns_san_and_allow_subject_common_name.ca.der");
assert_eq!(
check_cert(ee, ca, &[], &[]),
Err(webpki::Error::NameConstraintViolation)
);
}
#[test]
fn we_incorrectly_ignore_name_constraints_on_name_in_subject() {
let ee = include_bytes!(
"tls_server_certs/we_incorrectly_ignore_name_constraints_on_name_in_subject.ee.der"
);
let ca = include_bytes!(
"tls_server_certs/we_incorrectly_ignore_name_constraints_on_name_in_subject.ca.der"
);
assert_eq!(check_cert(ee, ca, &[], &[]), Ok(()));
}
#[test]
fn reject_constraints_on_unimplemented_names() {
let ee = include_bytes!("tls_server_certs/reject_constraints_on_unimplemented_names.ee.der");
let ca = include_bytes!("tls_server_certs/reject_constraints_on_unimplemented_names.ca.der");
assert_eq!(
check_cert(ee, ca, &[], &[]),
Err(webpki::Error::NameConstraintViolation)
);
}
#[test]
fn we_ignore_constraints_on_names_that_do_not_appear_in_cert() {
let ee = include_bytes!(
"tls_server_certs/we_ignore_constraints_on_names_that_do_not_appear_in_cert.ee.der"
);
let ca = include_bytes!(
"tls_server_certs/we_ignore_constraints_on_names_that_do_not_appear_in_cert.ca.der"
);
assert_eq!(
check_cert(ee, ca, &["notexample.com"], &["example.com"]),
Ok(())
);
}
#[test]
fn wildcard_san_accepted_if_in_subtree() {
let ee = include_bytes!("tls_server_certs/wildcard_san_accepted_if_in_subtree.ee.der");
let ca = include_bytes!("tls_server_certs/wildcard_san_accepted_if_in_subtree.ca.der");
assert_eq!(
check_cert(
ee,
ca,
&["bob.example.com", "jane.example.com"],
&["example.com", "uh.oh.example.com"]
),
Ok(())
);
}
#[test]
fn wildcard_san_rejected_if_in_excluded_subtree() {
let ee = include_bytes!("tls_server_certs/wildcard_san_rejected_if_in_excluded_subtree.ee.der");
let ca = include_bytes!("tls_server_certs/wildcard_san_rejected_if_in_excluded_subtree.ca.der");
assert_eq!(
check_cert(ee, ca, &[], &[]),
Err(webpki::Error::NameConstraintViolation)
);
}
#[test]
fn ip4_address_san_rejected_if_in_excluded_subtree() {
let ee =
include_bytes!("tls_server_certs/ip4_address_san_rejected_if_in_excluded_subtree.ee.der");
let ca =
include_bytes!("tls_server_certs/ip4_address_san_rejected_if_in_excluded_subtree.ca.der");
assert_eq!(
check_cert(ee, ca, &[], &[]),
Err(webpki::Error::NameConstraintViolation)
);
}
#[test]
fn ip4_address_san_allowed_if_outside_excluded_subtree() {
let ee = include_bytes!(
"tls_server_certs/ip4_address_san_allowed_if_outside_excluded_subtree.ee.der"
);
let ca = include_bytes!(
"tls_server_certs/ip4_address_san_allowed_if_outside_excluded_subtree.ca.der"
);
assert_eq!(check_cert(ee, ca, &["12.34.56.78"], &[]), Ok(()));
}
#[test]
fn ip4_address_san_rejected_if_excluded_is_sparse_cidr_mask() {
let ee = include_bytes!(
"tls_server_certs/ip4_address_san_rejected_if_excluded_is_sparse_cidr_mask.ee.der"
);
let ca = include_bytes!(
"tls_server_certs/ip4_address_san_rejected_if_excluded_is_sparse_cidr_mask.ca.der"
);
assert_eq!(
check_cert(ee, ca, &[], &[]),
Err(webpki::Error::InvalidNetworkMaskConstraint)
);
}
#[test]
fn ip4_address_san_allowed() {
let ee = include_bytes!("tls_server_certs/ip4_address_san_allowed.ee.der");
let ca = include_bytes!("tls_server_certs/ip4_address_san_allowed.ca.der");
assert_eq!(
check_cert(
ee,
ca,
&["12.34.56.78"],
&[
"12.34.56.77",
"12.34.56.79",
"0000:0000:0000:0000:0000:ffff:0c22:384e"
]
),
Ok(())
);
}
#[test]
fn ip6_address_san_rejected_if_in_excluded_subtree() {
let ee =
include_bytes!("tls_server_certs/ip6_address_san_rejected_if_in_excluded_subtree.ee.der");
let ca =
include_bytes!("tls_server_certs/ip6_address_san_rejected_if_in_excluded_subtree.ca.der");
assert_eq!(
check_cert(ee, ca, &[], &[]),
Err(webpki::Error::NameConstraintViolation)
);
}
#[test]
fn ip6_address_san_allowed_if_outside_excluded_subtree() {
let ee = include_bytes!(
"tls_server_certs/ip6_address_san_allowed_if_outside_excluded_subtree.ee.der"
);
let ca = include_bytes!(
"tls_server_certs/ip6_address_san_allowed_if_outside_excluded_subtree.ca.der"
);
assert_eq!(
check_cert(ee, ca, &["2001:0db9:0000:0000:0000:0000:0000:0001"], &[]),
Ok(())
);
}
#[test]
fn ip6_address_san_allowed() {
let ee = include_bytes!("tls_server_certs/ip6_address_san_allowed.ee.der");
let ca = include_bytes!("tls_server_certs/ip6_address_san_allowed.ca.der");
assert_eq!(
check_cert(
ee,
ca,
&["2001:0db9:0000:0000:0000:0000:0000:0001"],
&["12.34.56.78"]
),
Ok(())
);
}
#[test]
fn ip46_mixed_address_san_allowed() {
let ee = include_bytes!("tls_server_certs/ip46_mixed_address_san_allowed.ee.der");
let ca = include_bytes!("tls_server_certs/ip46_mixed_address_san_allowed.ca.der");
assert_eq!(
check_cert(
ee,
ca,
&["12.34.56.78", "2001:0db9:0000:0000:0000:0000:0000:0001"],
&[
"12.34.56.77",
"12.34.56.79",
"0000:0000:0000:0000:0000:ffff:0c22:384e"
]
),
Ok(())
);
}
#[test]
fn permit_directory_name_not_implemented() {
let ee = include_bytes!("tls_server_certs/permit_directory_name_not_implemented.ee.der");
let ca = include_bytes!("tls_server_certs/permit_directory_name_not_implemented.ca.der");
assert_eq!(
check_cert(ee, ca, &[], &[]),
Err(webpki::Error::NameConstraintViolation)
);
}
#[test]
fn exclude_directory_name_not_implemented() {
let ee = include_bytes!("tls_server_certs/exclude_directory_name_not_implemented.ee.der");
let ca = include_bytes!("tls_server_certs/exclude_directory_name_not_implemented.ca.der");
assert_eq!(
check_cert(ee, ca, &[], &[]),
Err(webpki::Error::NameConstraintViolation)
);
}
#[test]
fn invalid_dns_name_matching() {
let ee = include_bytes!("tls_server_certs/invalid_dns_name_matching.ee.der");
let ca = include_bytes!("tls_server_certs/invalid_dns_name_matching.ca.der");
assert_eq!(check_cert(ee, ca, &["dns.example.com"], &[]), Ok(()));
}