PKI & Certificate Chains
This module starts with a disagreement rather than a mechanism. OpenSSL and BoringSSL both ship a file called crypto/x509/x509_vfy, differing by one letter of extension, and they do not agree about what verify depth means: OpenSSL permits one more certificate than you configured — deliberately, so that exceeding the limit can be reported as a named error — while BoringSSL permits two more, because its depth excludes both the leaf and the trust anchor. The difference is bigger than the one certificate it looks like, because BoringSSL never raises that error at all: it stops extending the chain, and the failure arrives as 'no trusted issuer found' instead. The same over-long chain is a named error in one library and a silent dead end in the other, which is why a depth quoted without a library name cannot be acted on. Depth also counts intermediates rather than certificates, and zero is both legal and instructive — a leaf signed directly by a root. From there the module walks the checks people believe verification performs and it does not. Revocation is opt-in and CRL-only: the chain verifier returns success before doing anything unless a flag is set, and OCSP is application code rather than a stricter setting of the same knob. Even with the flag, the default scope is the leaf alone, so a revoked intermediate passes the common configuration — the exact case a CA compromise produces, and the count of unchecked certificates rises with the depth you chose. Stapling removes a round trip and validates nothing, with the library warning in its own header that the bytes it hands you are not guaranteed to be well formed, and the staleness bound optional on both sides so an affirmatively-good response of any age is accepted unless you ask for a maximum. Certificate lifetime is policy rather than code: nothing in either tree computes the span between notBefore and notAfter, so a ten-year certificate verifies cleanly and a browser refuses it, and the ceiling is 398 days for certificates issued on or after 2020-09-01. Hostname matching is a short-circuit rather than a preference — one subjectAltName entry of the requested type silences the Common Name entirely, which is why adding one irrelevant name breaks the hostname the certificate was issued for, and nothing in either tree caps how many names it will walk. Certificate Transparency runs backwards from the intuition: the CA submits a poisoned precertificate during issuance and embeds the promises the logs return, so the log entries predate both your handshake and the certificate, and an SCT from a log you lack the key for is unverifiable rather than invalid — with no clock-skew tolerance whatsoever on a timestamp in the future, which makes the verifying host's clock a certificate failure mode. And pinning is where the names mislead most: the function that reads exactly like 'hash the public key' digests the bit string without the algorithm identifier, giving a perfectly plausible 32-byte value that can never match a published pin. Change the chain depth, the revocation strategy, the key algorithm, the lifetime, the name count, cross-signing and the pin scope, and watch the server-computed cascade across certificate structure, chain building, revocation, CT logging and pinning — including the combination that is only broken jointly, a root pin on a cross-signed chain, where which anchor terminates the chain becomes a property of the verifier's search rather than of anything you serve. Validated against OpenSSL 3.5.7 and BoringSSL source, with every citation naming its library because the two disagree.
- All current + future modules
- Full kata library
- Progress dashboard + weak area analysis
Cancel anytime. Billed annually.