Compare commits

..
Author SHA1 Message Date
Ian Graham Martinez 9204017cf1 Give each CA its own CRL path
A verifier that cached the CRL of an earlier CA would otherwise apply it to a re-minted one.
2026-10-22 11:00:59 -04:00
ian-at-strixandIan Graham Martinez 7cafa16cc4 Hold the CA key in the TPM on Windows (#9)
* Hold the CA key in the TPM on Windows

A non-exportable machine key in the TPM, or in software where there is
none, signs as the Secure Enclave key does on macOS.

* Require the TPM for the Windows CA key

A failure to open the TPM fell back to a software key, which minted a new CA
and kept it for good. Fail instead, as macOS does without a Secure Enclave.

* Use the windows crate for the TPM key

---------

Co-authored-by: Ian Graham Martinez <[email protected]>
2026-10-22 10:53:51 -04:00
2 changed files with 16 additions and 0 deletions

No files matched your search

+7
View File
@@ -1,4 +1,5 @@
use rama::error::BoxError;
use rama::tls::boring::core::sha::sha256;
use rama::tls::boring::core::x509::X509;
use rcgen::{
BasicConstraints, CertificateParams, CertificateRevocationListParams, DistinguishedName,
@@ -39,6 +40,12 @@ impl CertificateAuthority {
(held == signer.subject_public_key_info()).then_some(ca)
}
/// Unique to this CA, so a verifier's cached CRL from an earlier one never applies to it.
pub fn crl_path(&self) -> String {
let digest = sha256(self.pem.as_bytes());
format!("/{}.crl", digest[..8].iter().map(|b| format!("{b:02x}")).collect::<String>())
}
fn new(pem: String) -> Result<Self, BoxError> {
Ok(Self { crt: X509::from_pem(pem.as_bytes())?, pem })
}
+9
View File
@@ -50,3 +50,12 @@ fn ca_signs_an_empty_crl() {
let crl = mitm::crl(&["registry.npmjs.org", "pypi.org"], &signer()).expect("sign a crl");
assert_eq!(crl[0], 0x30, "a DER SEQUENCE");
}
/// A re-minted CA must not inherit the old one's CRL from a verifier's cache.
#[test]
fn each_ca_names_its_own_crl() {
let signer = signer();
let npm = mitm::CertificateAuthority::generate(&["registry.npmjs.org"], &signer).expect("mint a ca");
let pypi = mitm::CertificateAuthority::generate(&["pypi.org"], &signer).expect("mint a ca");
assert_ne!(npm.crl_path(), pypi.crl_path());
}