TLS certificates, trust, and time

Certificate validation depends on the chain, the name, and the verifier's clock.

A TLS client accepts a server certificate only if all of these hold:

  • The chain verifies. Each certificate is signed by the next, up to a root in the client's trust store. Missing intermediates are a common server-side mistake.
  • The name matches. The hostname the client asked for appears in the certificate's Subject Alternative Names.
  • The time is inside the validity window, between notBefore and notAfter, according to the client's clock.

The last point surprises people. A client whose clock is wrong rejects a perfectly valid certificate. If it runs ahead, the certificate looks expired. If it runs behind, a freshly issued certificate looks "not yet valid". When one site reports expiry and everyone else is fine, check that site's clock and its time synchronisation (timedatectl, chronyc tracking) before touching the certificate.

Useful checks:

  • openssl s_client -connect HOST:443 -servername HOST -showcerts shows what the server actually presents.
  • openssl x509 -noout -dates -subject -ext subjectAltName reads a certificate's validity and names.
  • openssl verify -CAfile ROOT.pem -untrusted INTERMEDIATE.pem LEAF.pem checks the chain. The -attime option evaluates it at a chosen moment.

Never "fix" a validation error by disabling verification (curl -k, verify=False). That removes the protection the certificate exists for and hides the next real problem.