Console9

How to verify a certificate chain with OpenSSL

Validate that a server's certificate chain is complete and trusted by verifying each link from leaf to root CA with OpenSSL.

Validate that an SSL/TLS certificate chain is complete, properly ordered, and trusted from the leaf certificate through intermediates to a root CA using OpenSSL's verify and s_client subcommands.

Prerequisites

  • OpenSSL installed
  • The certificate files to verify (PEM format), or the server hostname to test remotely
  • Terminal access

Step-by-Step: Verify a Certificate Chain with OpenSSL

1. Verify a Remote Server's Chain with OpenSSL s_client

OpenSSL's s_client connects to a server and displays the certificate chain with verification status:

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

Look for the Verify return code at the end of the output. A code of 0 (ok) means the full chain verified successfully against the system CA bundle.

2. Display All Certificates in the Chain

Add the -showcerts flag to see every certificate the server presents:

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

OpenSSL displays each certificate as a PEM block. A valid chain typically contains 2–3 certificates: the leaf (server) certificate, one or more intermediate CA certificates, and optionally the root CA.

3. Verify a Local Certificate File Against a CA Bundle

OpenSSL's verify subcommand checks a certificate file against a CA bundle and intermediate chain:

openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt server.crt

The -CAfile flag specifies the trusted root CA certificates. The -untrusted flag provides intermediate certificates that are not in the CA bundle but are needed to complete the chain. OpenSSL reports server.crt: OK if the chain is valid.

4. Check That the Key Matches the Certificate

Verify the private key corresponds to the certificate by comparing modulus hashes:

openssl x509 -noout -modulus -in server.crt | openssl md5
openssl rsa -noout -modulus -in server.key | openssl md5

Both commands must output the same MD5 hash. A mismatch means the key and certificate were generated separately and do not form a valid pair.

How to Verify the Chain Is Complete

A complete chain contains every certificate needed to link the leaf to a trusted root. Count the certificates in the server's chain:

openssl s_client -connect example.com:443 -showcerts </dev/null 2>/dev/null | grep -c "BEGIN CERTIFICATE"

A count of 1 means only the leaf certificate is present — the server is missing the intermediate. A count of 2 or 3 indicates a properly configured chain.

Common Issues When Verifying Certificate Chains with OpenSSL

OpenSSL returns "unable to get local issuer certificate"— The intermediate CA certificate is missing from the chain. The server must send both the leaf and intermediate certificates. See OpenSSL: unable to get local issuer certificate.

OpenSSL returns "certificate has expired"— One or more certificates in the chain have passed their notAfter date. Check each certificate's dates individually. Renew expired certificates with Certbot.

Key modulus mismatch— The private key was generated for a different certificate. Regenerate the CSR and certificate using the same key, or generate a new key pair.