Repository navigation
Add a blocklist covering disabled roots and compromised intermediates - #11
Merged
Merged
Conversation
Ship a blocklist alongside the trust store so callers can reject a certificate wherever it comes from, including a root supplied by the OS store. It holds every disabled root (roots/**/*.disabled) and the 16 compromised eMudhra intermediate certificates (blocked/), keyed by the SHA-256 of the certificate and of its SubjectPublicKeyInfo. - blocked(), blocked_by_spki(), blocked_by_cert(): static lookups, no runtime hashing - optional `check` feature: blocked_by_der() and check_chain() parse and hash DER chains; still no_std, no alloc, no dependencies - build.rs fingerprints each entry with a shared core-only SHA-256, requires a `# Blocked:` reason header, checks published fingerprint headers, and fails if a blocked key is also a trusted root's key - docs: README, CURATION.md, CHANGELOG-roots.md; CI covers the feature Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e DER Remove check_chain()/blocked_by_der() and the runtime DER walker. The library is back to static data and comparisons; SHA-256 moves to build_support as a build-time helper only. The DER-level tests now play the caller's role, hashing with the build helpers and querying blocked_by_spki()/blocked_by_cert(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
cacrtnow ships a blocklist of certificates that must never be trusted, wherever they come from. A caller checks every certificate in its chain, root included. A root we have disabled is then still rejected when it comes from an OS store that still trusts it, and a compromised intermediate can be blocked without killing its whole CA.What's blocked (19 certificates)
roots/**/*.disabled): emSign ECC Root CA - G3, Buypass Class 2 and Class 3. From now on, a disabled root is automatically a blocked root.blocked/2026-10-emudhra-intermediates/): the 8 compromised keys, each issued by emSign and cross-signed by Sectigo AAA. No private keys; those stay inevidence/, outside the crate.Entries are keyed by SHA-256 of the certificate and of its SPKI. Matching on the key catches cross-signs and reissues we've never seen.
API
blocked()kind(),label(),reason(), both hashesblocked_by_spki(&[u8; 32])blocked_by_cert(&[u8; 32])The caller hashes, so the library stays static data and comparisons:
no_std, noalloc, no runtime hashing. Callers are TLS libraries that already parse DER.Build-time guarantees
# Blocked: <reason>header# SHA256 fingerprint:/# SPKI SHA256:headers must match the certificate; the eMudhra ones come from the incident's JSON, which independently checks the build's SHA-256 and SPKI extractionChecks
cargo fmt, clippy, tests (including tests that play the caller: hash the DER, then query),thumbv7em-none-eabi, MSRV 1.86,cargo doc -D warnings,cacrt-tool verify,cargo package.Caveat
The blocklist protects only verifiers that call it; rustls and OpenSSL don't know about it. When a root program removes a root, we still disable the root, which also blocks it. The README,
CURATION.mdandCHANGELOG-roots.mddocument all of this.🤖 Generated with Claude Code