Pre-issuance weak-key & compromised-key gate¶
secsy-pki runs a fail-closed key-quality gate on every certificate issuance, rejecting weak and known-compromised subject public keys before the HSM signs anything. It implements CA/Browser Forum Baseline Requirements §6.1.1.3 ("the CA SHALL reject a certificate request if … the Key is a known weak Key").
The gate runs on every issuance surface — REST/gRPC, ACME, EST, SCEP, CMP,
and SPIFFE — because it lives in the shared ca.buildLeaf signing path, and on
the Task 113 dry-run preview (POST …/certificates:preview,
secsy-ca issue --dry-run) through the same evaluator, so a preview verdict can
never drift from what real issuance enforces.
Scope: the gate inspects the subject public key a caller asks the CA to certify. CA signing keys are generated inside the HSM and are covered by the key provider and the FIPS policy, not this gate.
What it checks¶
| Check | What it rejects | Applies to |
|---|---|---|
| ROCA / CVE-2017-15361 | RSA moduli carrying the Infineon RSALib fingerprint (private key recoverable via Coppersmith). Detected by a discrete-log fingerprint over small primes — no factoring. | RSA |
| RSA exponent policy | Public exponent e < 65537 or an even e (a valid RSA exponent is odd; the BRs require ≥ 65537). |
RSA |
| RSA modulus sanity | An even modulus, or one below the minimum bit length (2048 by default). | RSA |
| Debian weak keys (CVE-2008-0166) | Keys whose fingerprint is in an operator-supplied blocklist (no blob is vendored). | any |
| Operator compromised-key blocklist | Keys an operator has explicitly blocked (secsy-ca blocked-keys). |
any |
| Duplicate / reused subject key (opt-in) | A subject public key already certified for a different subject. | any |
A healthy ECDSA or Ed25519 key passes the RSA-specific checks (they simply do not apply) and is still subject to the two blocklists and duplicate detection.
Configuration¶
Per-profile policy lives in each profile's key_checks block. The gate is on by
default in enforce mode — a profile that omits the block still enforces it.
# Deployment-wide inputs to the gate.
keychecks:
# Optional Debian OpenSSL / operator weak-key blocklist(s). Files or directories
# of fingerprints: hex SHA-256/SHA-1 of the DER SubjectPublicKeyInfo, or a
# "SHA256:<base64>" fingerprint; '#' comments and blank lines are ignored.
# A configured path that does not exist is a FATAL startup error (fail-closed).
weak_key_blocklist_paths:
- /etc/secsy-pki/weak-keys/
profiles:
- name: server
# ... key_usages, ext_key_usages, validity ...
key_checks:
mode: enforce # enforce (default) | warn
# disabled: true # turn the gate off for this profile (discouraged)
detect_duplicates: true # flag a subject key reused across subjects
# min_rsa_bits: 3072 # override the 2048-bit floor
mode: warnrecords findings (audit event + metric) but issues anyway — an escape hatch for a migration window, not a steady state.detect_duplicatescosts one indexed inventory lookup per issuance and is off by default because a key intentionally shared across subjects is occasionally legitimate. A renewal (same key, same subject) is never flagged.
Operator compromised-key blocklist¶
Blocklist entries are keyed by the SubjectPublicKeyInfo SHA-256 fingerprint
(SHA256:<base64>, the same textual form as an OpenSSH SHA-256 fingerprint). The
store holds no key material.
# Block a leaked/compromised key (from a cert, CSR, public key, or fingerprint):
secsy-ca blocked-keys add -cert leaked.pem -reason "key compromise, INC-1234"
secsy-ca blocked-keys add -csr device.csr -reason "weak vendor key"
secsy-ca blocked-keys add -key pub.pem -reason "reported compromised"
secsy-ca blocked-keys add -fingerprint SHA256:abc… -reason "from CT/discovery"
secsy-ca blocked-keys list
secsy-ca blocked-keys remove SHA256:abc…
Blocking a key is a natural step in a key-compromise incident: after
mass-revoking the affected certificates, block the key so
it can never be re-certified. Every add/remove is audited (key.block /
key.unblock).
Observability¶
- Audit:
cert.keycheck— one event per issuance that produced findings (ResultErrorwhen it blocked,ResultSuccesswhen warn-mode). The detail carries the profile, key fingerprint, and finding codes. - Metrics:
secsy_certificate_key_checks_total{result=pass|warn|fail}andsecsy_certificate_key_check_findings_total{code,mode}(codes:roca,weak_exponent,small_modulus,even_modulus,debian_weak_key,blocked_key,duplicate_key). - Doctor:
secsy-ca doctorrunskeychecks.blocklist(the weak-key file loads; the operator blocklist size) andkeychecks.profiles(any profile that has weakened the gate).
Design notes¶
- Fail-closed. A blocklist/inventory read error, or a configured-but-missing weak-key file at startup, refuses issuance / refuses to start — never silently disables the check. See ADR 0003.
- No vendored blob. The Debian weak-key list (millions of fingerprints) is operator-supplied so the binary stays small and the operator controls the trust basis.
- Not a factoring service. The gate is a structural + blocklist gate. It does not attempt small-factor, Fermat-close-prime, or batch-GCD analysis.