Skip to content

Commit

Permalink
Permit trusted self-signed certificates
Browse files Browse the repository at this point in the history
Self-signed certificates are both an end-entity as well as a certificate
authority in the eyes of webpki - since we have ultimate trust in the
supplied trust anchors, a certificate supplied with the same subject as a
trust anchor and is directly signed by the same trust anchor should also
be valid, even though the certificate supplied might still be a CA.
  • Loading branch information
Ichbinjoe committed Jan 9, 2021
1 parent 28951a0 commit 04caeca
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 2 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ include = [

"tests/dns_name_tests.rs",
"tests/integration.rs",
"tests/misc/selfsigned.der",
"tests/misc/serial_neg.der",
"tests/misc/serial_zero.der",
"tests/netflix/ca.der",
Expand Down
16 changes: 14 additions & 2 deletions src/verify_cert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@ pub fn build_chain(
) -> Result<(), Error> {
let used_as_ca = used_as_ca(&cert.ee_or_ca);

check_issuer_independent_properties(
let must_be_self_signed = match check_issuer_independent_properties(
cert,
time,
used_as_ca,
sub_ca_count,
required_eku_if_present,
)?;
) {
Ok(()) => false,
Err(Error::CAUsedAsEndEntity) => true,
Err(e) => return Err(e),
};

// TODO: HPKP checks.

Expand Down Expand Up @@ -71,6 +75,10 @@ pub fn build_chain(

check_signatures(supported_sig_algs, cert, trust_anchor_spki)?;

if must_be_self_signed && trust_anchor_subject != cert.subject {
return Err(Error::CAUsedAsEndEntity);
}

Ok(())
}) {
Ok(()) => {
Expand All @@ -81,6 +89,10 @@ pub fn build_chain(
}
}

if must_be_self_signed {
return Err(Error::CAUsedAsEndEntity);
}

loop_while_non_fatal_error(intermediate_certs, |cert_der| {
let potential_issuer =
cert::parse_cert(untrusted::Input::from(*cert_der), EndEntityOrCA::CA(&cert))?;
Expand Down
17 changes: 17 additions & 0 deletions tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ fn read_root_with_neg_serial() {
.expect("idcat cert should parse as anchor");
}

#[test]
fn selfsigned() {
let cert = include_bytes!("misc/selfsigned.der");

let anchors = vec![webpki::trust_anchor_util::cert_der_as_trust_anchor(cert).unwrap()];
let anchors = webpki::TLSServerTrustAnchors(&anchors);

#[allow(clippy::unreadable_literal)] // TODO: Make this clear.
let time = webpki::Time::from_seconds_since_unix_epoch(1610233207);

let cert = webpki::EndEntityCert::from(cert).unwrap();
assert_eq!(
Ok(()),
cert.verify_is_valid_tls_server_cert(ALL_SIGALGS, &anchors, &[], time)
);
}

#[cfg(feature = "std")]
#[test]
fn time_constructor() {
Expand Down
Binary file added tests/misc/selfsigned.der
Binary file not shown.

0 comments on commit 04caeca

Please sign in to comment.