Inspect TLS
Read a certificate
Decode a PEM certificate and inspect its subject, issuer, validity, names, key, and extensions.
A certificate is a small signed document. It says “this public key belongs to this name”, and an issuer signs that statement. Everything a client checks during verification lives inside it: who the certificate is for, who vouched for it, and when it stops being valid. You can decode all of it yourself.
We need a certificate file to work with. Let’s grab the one a live server sends and save it as server.crt:
openssl s_client -connect flaviocopes.com:443 -servername flaviocopes.com </dev/null 2>/dev/null | openssl x509 -out server.crt
The x509 command reads the first certificate in the s_client output and writes it as PEM, a text format with -----BEGIN CERTIFICATE----- markers.
Now ask for the fields we care about:
openssl x509 -in server.crt -noout -subject -issuer -dates -ext subjectAltName
-noout suppresses the encoded certificate itself, so you only get the decoded fields you asked for:
subject=CN=flaviocopes.com
issuer=C=US, O=Google Trust Services, CN=WE1
notBefore=Aug 17 14:33:28 2026 GMT
notAfter=Nov 15 15:33:25 2026 GMT
X509v3 Subject Alternative Name:
DNS:flaviocopes.com
Read them in order. subject is the identity the certificate claims. issuer is the authority that signed it. notBefore and notAfter are the validity window, always in GMT. The last block lists the hostnames this certificate covers.
That last block is the Subject Alternative Name (SAN) extension. Modern clients check hostnames there, not in the subject line. If the name you typed in the URL is not in the SAN list, verification fails, whatever the subject says.
When you need everything, dump the full decode:
openssl x509 -in server.crt -noout -text
That adds the serial number, the public key type and size (id-ecPublicKey, 256 bit, for this site), the signature algorithm, and extensions like Key Usage and Basic Constraints. It’s more than you usually need. But it’s the view that ends every argument about what a certificate does or does not contain.
A mistake I see often: inspecting the wrong file. Leaf certificates, intermediates, and bundles all look the same from the outside. If subject shows a CA name instead of your hostname, you decoded a CA certificate, not the leaf. Check -ext basicConstraints too: a leaf says CA:FALSE.
One more thing. A certificate is public. You can commit it, email it, or paste it in a ticket. The matching private key is secret. Keep the two files apart, and give them different permissions.
Lesson completed