Skip to content

Commit

Permalink
webpki-ccadb: distrust any CA with a distrust after date
Browse files Browse the repository at this point in the history
This commit update the CCADB codegen to consider any root CA with
a distrust for TLS after date as not trusted, irrespective of the
distrust date.

The rustls/webpki ecosystem this crate supports does not have the
capability to enforce a "active distrust" of a TLS trust anchor in the
Mozilla root program that has a "Distrust for TLS After Date" date in
CCADB. Given this constraint we choose to remove roots immediately when
they are given a distrust after date. This is _more_ aggressive than the
Mozilla root program but requires no new features implemented in
downstream crates. Users needing more nuanced root program enforcement
should consider using the rustls-platform-verifier crate.
  • Loading branch information
cpu authored and djc committed Jun 12, 2024
1 parent c9de4d6 commit d541a7d
Showing 1 changed file with 10 additions and 14 deletions.
24 changes: 10 additions & 14 deletions webpki-ccadb/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::cmp::Ordering;
use std::collections::{BTreeMap, HashSet};

use chrono::{NaiveDate, Utc};
use chrono::NaiveDate;
use num_bigint::BigUint;
use pki_types::CertificateDer;
use serde::Deserialize;
Expand Down Expand Up @@ -58,7 +58,7 @@ pub async fn fetch_ccadb_roots() -> BTreeMap<String, CertificateMetadata> {
// Filter for just roots with the TLS trust bit that are not distrusted as of today's date.
let trusted_tls_roots = metadata
.into_iter()
.filter(|root| root.trusted_for_tls(&Utc::now().naive_utc().date()))
.filter(CertificateMetadata::trusted_for_tls)
.collect::<Vec<CertificateMetadata>>();

// Create an ordered BTreeMap of the roots, panicking for any duplicates.
Expand Down Expand Up @@ -103,26 +103,22 @@ pub struct CertificateMetadata {

impl CertificateMetadata {
/// Returns true iff the certificate has valid TrustBits that include TrustBits::Websites,
/// and the certificate has no distrust for TLS after date, or has a valid distrust
/// for TLS after date that is in the future compared to `now`. In all other cases this function
/// and the certificate has no distrust for TLS after date. In all other cases this function
/// returns false.
fn trusted_for_tls(&self, now: &NaiveDate) -> bool {
///
/// Notably this means a trust anchor with a distrust after date _in the future_ is treated
/// as untrusted irrespective of the distrust after date. An end-to-end distrust after solution
/// is NYI: https://github.com/rustls/webpki/issues/259
fn trusted_for_tls(&self) -> bool {
let has_tls_trust_bit = self.trust_bits().contains(&TrustBits::Websites);

match (has_tls_trust_bit, self.tls_distrust_after()) {
// No website trust bit - not trusted for tls.
(false, _) => false,
// Trust bit, populated distrust after - not trusted for tls.
(true, Some(_)) => false,
// Has website trust bit, no distrust after - trusted for tls.
(true, None) => true,
// Trust bit, populated distrust after - need to check date to decide.
(true, Some(tls_distrust_after)) => {
match now.cmp(&tls_distrust_after).is_ge() {
// We're past the distrust date - skip.
true => false,
// We haven't yet reached the distrust date - include.
false => true,
}
}
}
}

Expand Down

0 comments on commit d541a7d

Please sign in to comment.