Most TLS outages I have been called into did not start with a dramatic key leak. They started with a certificate someone never really read: a missing Subject Alternative Name, an incomplete chain file, a leaf that looked fine in a browser on one machine and failed everywhere else. Browser UIs hide the details. openssl x509 -text does not. Once you can walk a certificate by hand, half of "SSL is broken" tickets become a five-minute diagnosis instead of a day of guessing.

I wrote this with help from AI tools and checked every command and example myself against current OpenSSL behaviour. I build PixelValut, a set of free browser-based developer and network tools, and this is Part 2 of the series on Web PKI and certificate forensics. Part 1 covered leaked private keys and rotation. Here we slow down and learn to read what a certificate actually asserts.

📚 Series Roadmap — Web PKI & Certificate Forensics in Practice

  • Part 1: Leaked TLS Private Keys: Proving Compromise, Finding Every Affected Cert & Rotating Safely
  • Part 2 (This Post): Reading X.509 Certificates by Hand: SANs, Key Usage, Chains & Intermediates
  • Part 3: Certificate Revocation in 2026: CRLs, the Decline of OCSP & Short-Lived Certificates
  • Part 4: Certificate Transparency Monitoring: Catching Unexpected Certificates for Your Domains
  • Part 5: ACME Automation Failures: Renewal Outages, Rate Limits & DNS-01 Pitfalls
  • Part 6: Mutual TLS for Internal APIs: Private CAs, Rotation & Pinning Trade-offs

Related: Subdomain Takeover & Dangling DNS Reconnaissance

How do you read an X.509 TLS certificate by hand?

Direct answer: Dump the leaf with openssl x509 -text, confirm Subject and Issuer, verify every hostname lives in the Subject Alternative Name extension, check Key Usage and Extended Key Usage for server auth, then walk the chain until you reach a trusted root. Most production failures are a missing intermediate or a hostname that never made it into the SAN list.

Pull the leaf and read it

Fetch what the server actually presents, not what you think is on disk:

openssl s_client -connect example.com:443 -servername example.com \ -showcerts </dev/null 2>/dev/null \ | openssl x509 -noout -text 

Or inspect a PEM file from your load balancer:

openssl x509 -in leaf.pem -noout -text 

You want the same fields every time. An SSL certificate checker is useful for a quick browser-side view of issuer, SANs and expiry; the OpenSSL dump is what you use when you need exact extension flags.

Subject and Issuer

Subject: CN = example.com Issuer: C = US, O = Let's Encrypt, CN = R11 

Subject is who the certificate claims to be. Issuer is who signed it. For publicly trusted TLS, the Issuer is almost always an intermediate, not the root. If Subject and Issuer are identical, you are looking at a self-signed certificate, which is fine for lab work and wrong for a public site.

SAN vs CN (the hostname trap)

Browsers and modern clients match hostnames against the Subject Alternative Name (SAN) extension, not against the Common Name. A certificate with CN=example.com and no SAN will fail hostname verification in current clients even when the CN "looks right."

openssl x509 -in leaf.pem -noout -ext subjectAltName 

Expect something like:

X509v3 Subject Alternative Name: DNS:example.com, DNS:www.example.com 

If api.example.com is missing from that list, clients talking to api.example.com will reject the certificate regardless of how clean the chain looks. Wildcard SANs (DNS:*.example.com) cover one label only; they do not cover a.b.example.com.

Key Usage and Extended Key Usage

These extensions constrain what the key is allowed to do:

openssl x509 -in leaf.pem -noout -ext keyUsage,extendedKeyUsage 

For a public HTTPS leaf you typically want:

Extension Expected on HTTPS leaf Red flag
Key Usage Digital Signature, Key Encipherment (RSA) or Digital Signature (ECDSA) Certificate Sign / CRL Sign on a leaf
Extended Key Usage TLS Web Server Authentication Client Auth only, or empty when a client enforces EKU
basicConstraints CA:FALSE CA:TRUE on a leaf (mis-issued or wrong file)

A leaf marked CA:TRUE is either a serious CA mistake or, more often, you opened an intermediate by accident and thought it was the site certificate.

basicConstraints and path length

openssl x509 -in intermediate.pem -noout -ext basicConstraints 

Intermediates should say CA:TRUE. Leaves should say CA:FALSE or omit CA entirely depending on profile. PathLen constraints on intermediates limit how deep a chain may go; you rarely edit these by hand, but you need to recognize them when a private CA chain fails to validate.

A dark terminal screen and keyboard in a quiet server room, representing hands-on OpenSSL certificate inspection, AI-generated
AI-generated image.

Building and verifying the chain

TLS clients need a path from the leaf to a trust anchor they already have. Servers must send the leaf and every intermediate. They should not send the root; clients already have roots.

# Show the full chain the server sends openssl s_client -connect example.com:443 -servername example.com \ -showcerts </dev/null 2>/dev/null | sed -n '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' 

Verify locally once you have leaf + intermediates in one PEM:

openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt \ -untrusted intermediates.pem leaf.pem 

-untrusted is where intermediates go. If verification fails with "unable to get local issuer certificate," the usual cause is a missing intermediate in what you serve, not a broken root store.

Setup What client receives Typical symptom
Leaf only Site cert, no intermediate Works on some Android/desktop caches, fails elsewhere
Leaf + correct intermediate Complete path to a public root Clean verify
Leaf + wrong intermediate Chain that does not link unable to get local issuer certificate
Leaf + intermediate + root Extra root in handshake Usually tolerated; wastes bytes; some scanners warn
Expired intermediate Path that ends early Sudden multi-region outage after a quiet period

Missing intermediates are still one of the most common production TLS failures, especially after a manual renewal where someone uploaded only cert.pem and forgot fullchain.pem.

Good vs broken setups at a glance

Check Healthy Broken
Hostname Appears in SAN Only in CN, or wrong name
Chain Leaf + intermediates, no required root Leaf alone
EKU Server Auth present Missing where policy requires it
Not After Days or weeks of validity left Expired, or expires tonight with no automation
Signature SHA-256 (or stronger) with expected key type Legacy MD5/SHA-1 on anything public
Key size RSA ≥ 2048 or P-256/P-384 ECDSA RSA 1024

For a related attack surface where DNS and certificates interact, see the earlier note on dangling DNS and certificate reconnaissance. Wrong SANs also show up there when an abandoned hostname still has a live certificate.

Diagnostic checklist

  1. Does openssl s_client show the certificate you expect for this hostname?
  2. Is every served hostname listed in Subject Alternative Name?
  3. Is Issuer an intermediate you recognize, not a mystery private CA on a public site?
  4. Is basicConstraints CA:FALSE (or equivalent) on the leaf?
  5. Do Key Usage / EKU allow server authentication?
  6. Does the server send intermediates (fullchain), not leaf-only?
  7. Does openssl verify succeed with your platform trust store?
  8. Are Not Before / Not After in a sensible window (clock skew included)?
  9. Does the public key type and size match your policy?
  10. Did you compare the live handshake to the files on disk after the last deploy?

Browse more developer TLS and network tools when you need a second view without pasting private keys anywhere.

FAQ

Why does my browser show a padlock when openssl verify fails?

Browsers sometimes cache intermediates, fetch missing ones, or use a different trust store. Command-line verify against the system store is the harsher, more portable check. Trust the stricter result for server configuration.

Is the Common Name still required?

Profiles vary. Many CAs still set CN for compatibility, but hostname matching is SAN-based. Never rely on CN alone.

What is the difference between cert.pem and fullchain.pem?

cert.pem is usually the leaf. fullchain.pem is leaf plus intermediates. Almost every reverse proxy should be pointed at the full chain file.

Can I ignore Extended Key Usage?

Not if your clients enforce it. Mutual TLS and some enterprise proxies are strict. For public HTTPS leaves, Server Auth should be present.

Why did renewal break only mobile clients?

Often a missing intermediate: desktop browsers had it cached; mobile clients did not. Always test with a clean openssl s_client after renewal.

Should I pin intermediates?

Prefer pinning sparingly and prefer monitoring Certificate Transparency (covered in Part 4). Intermediate replacements by public CAs are normal; hard pins without a backup plan cause outages.

Next in this series, Part 3 covers revocation in 2026: CRLs, why OCSP is fading for many clients, and how short-lived certificates change the incident playbook.

Follow & Connect