Every TLS handshake, every signed document, every code-signing check starts with the same artifact: an X.509 certificate. Most engineers can openssl x509 -text one, but far fewer can say what a validator is actually checking. This guide walks the structure from the outside in.
The anatomy of a certificate
A certificate is three things stapled together: a TBSCertificate (the data being certified — subject, public key, validity window, extensions), a signature algorithm identifier, and the signature itself, produced by the issuer’s private key. Everything a validator cares about lives in the TBS block; the signature merely proves the issuer vouched for it.
# dump the full structure of a certificate
openssl x509 -in server.crt -text -noout
# just the validity window and subject
openssl x509 -in server.crt -noout -subject -dates
Extensions do the real work
Modern validation logic lives almost entirely in extensions. basicConstraints says whether a certificate may act as a CA. keyUsage and extendedKeyUsage restrict what the key may sign. subjectAltName — not the Common Name — is where hostnames are matched. Get an extension wrong at issuance and no amount of correct cryptography saves you.
Chains, roots and path building
A validator does not trust your certificate; it trusts a root in its store and tries to build a signed path from that root to your leaf. Path building is where deployments break: missing intermediates, cross-signed roots, expired anchors. Always ship the full chain — leaf first, then each intermediate in order.
What a validator really checks
Signature chain, validity window, name match against SAN, key usage, revocation status, and — in browsers — Certificate Transparency proof. Each check fails independently, which is why “it works in curl but not Chrome” is such a common bug report.