KomuraSoft LLC
Chapter 6

Observing with openssl and the browser

Learn to read openssl s_client output and the certificate viewer, and translate certificate errors into 'which of the three checks failed.'

Confirm in the wild what you traced on paper

Chapters 1–5 completed the mechanism. This chapter observes it live, with openssl and a browser. Two goals: know where to look in the output, and translate certificate errors into "which of Chapter 4's three checks failed."

Note: keep observation within ordinary access to servers you manage or public sites. Every command below performs one TLS connection and prints the result — the same as a normal visit.

openssl s_client — run the handshake yourself

The fundamental move of TLS investigation: perform a real handshake and print everything received.

openssl s_client -connect example.com:443 -servername example.com < /dev/null

The output is long, but the places to look are fixed:

Certificate chain (who signed whom)
s: (subject) and i: (issuer) per level. Check that the leaf's i: connects to the next level's s: — Chapter 4's chain, printed literally
Verify return code (the verdict)
0 (ok) means all three checks passed. Otherwise the reason is spelled out: certificate has expired, unable to get local issuer certificate (the chain doesn't connect), and so on
Protocol / Cipher (what is being spoken)
TLSv1.3 / TLS_AES_128_GCM_SHA256 — the negotiated version and the AEAD cipher from Chapter 5

-servername is Chapter 5's SNI. Omit it and the server may present a different default certificate — a misdiagnosis machine. Match your investigation command to the browser's conditions before reasoning from its output.

To study one certificate closely, pipe into the x509 subcommand:

openssl s_client -connect example.com:443 -servername example.com < /dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates -ext subjectAltName

notBefore / notAfter (validity) and the SAN list (names) — material for two of the three checks in one line. The browser's padlock → certificate viewer shows the same data in a GUI. Either way, the items to read are the same.

Practice 6-1 — Reading the output

Read openssl output and certificate contents by mapping them onto Chapter 4's three checks.

Q1. openssl s_client prints verify error: certificate has expired. Which of Chapter 4's three checks failed?

Q2. The certificate shows notAfter=Aug 11 23:59:59 2026 GMT. Taking today as July 12, 2026, roughly how many days remain until expiry?

days

Q3. Running openssl s_client -connect example.com:443, you forget -servername example.com (the SNI). What can happen?

Flowchart triaging certificate errors into expiry, name mismatch, and chain failure

Certificate-error triage starts with translation into "which check failed." Wordings differ; the destination boxes are these three, plus revocation.

The three-error triage table

Most certificate errors in practice land in three families, each mapping one-to-one onto Chapter 4's checks:

Failed checkTypical wordingCommon causeFirst move
Validity periodcertificate has expiredRenewal forgotten; auto-renewal brokenCheck notAfter with -dates; renew; add days-remaining monitoring
Name matchhostname mismatchAccessing a name not in the SAN; missing SNICompare the SAN list against the name being accessed and the SNI
Signature chainunable to get local issuer certificate / self-signed certificateMissing intermediate; self-signed; internal CA absent from the root storeCheck the chain the server actually sends with s_client; fix server config if the intermediate is missing

The missing intermediate deserves special mention: it shows up as the baffling "works in the browser, fails from curl / API clients." Browsers sometimes patch the gap from caches or by fetching the missing certificate. Looking at what the server actually sends via s_client is the direct route.

Before you "turn verification off," stop

Under time pressure, hands reach for curl -k or "ignore certificate errors" settings. In Chapter 1's terms this removes the authenticity check by your own hand. Encryption remains, so it looks safe — but you are now set up for a secret conversation with an impostor: Chapter 4's man-in-the-middle, welcomed in.

Meanwhile, some networks have a legitimate way into the middle: TLS-inspection proxies distribute the company's own CA into each machine's root store and re-issue site certificates under it. Verification ends at the root store (Chapter 4), so no error occurs. When "errors appear only on BYOD machines or the CI server," recall this construction — what is missing is the internal CA in that machine's root store, not verification being on.

One more browser-side guardrail: HSTS (HTTP Strict Transport Security). After receiving the HSTS header once, the browser connects to that site only over HTTPS and offers no "proceed anyway" button on certificate errors. A missing button is not a bug — it is a safety device the site itself requested.

Practice 6-2 — Triage the classic cases

Three situations you will meet repeatedly in practice. Narrow each to one cause.

Q4. A site opens fine in the browser, but curl and your own program fail certificate verification. What do you suspect first?

Q5. What is wrong with permanently using curl -k (--insecure) to get past verification errors?

Q6. A company's internal proxy decrypts TLS traffic for security inspection (TLS inspection). Why do company-issued PCs show no certificate errors?

What to take from this chapter

  • openssl s_client -connect host:443 -servername host is the basic move. Read the chain's s:/i:, the Verify return code, Protocol/Cipher
  • Translate errors into "which of the three checks failed" before acting — mapping, not memorizing
  • "Browser-only works" → suspect the missing intermediate. "Company PCs only work" → suspect the internal CA in the root store
  • Turning verification off is not a fix. Identify the failing check and repair the cause

Next is the comprehensive review: case problems spanning all six chapters, turning knowledge into something you can use.