SSL Certificate Validation Using OpenSSL Command

SSL Certificate Validation Using OpenSSL Command

Securing communication between a client and a server is paramount in today’s internet landscape. SSL/TLS certificates play a crucial role in this security, providing authentication and encryption. The OpenSSL command-line tool is a powerful and versatile Swiss Army knife for managing and validating SSL certificates. This article provides a detailed walkthrough of how to validate SSL certificates using OpenSSL, covering various scenarios and options.

Prerequisites:

  • OpenSSL Installation: Ensure OpenSSL is installed on your system. Most Linux distributions include it by default. On Windows, you might need to download and install it from the official OpenSSL website or use a package manager like Chocolatey (choco install openssl). On macOS, you can use Homebrew (brew install openssl).
  • Basic Terminal/Command Prompt Knowledge: Familiarity with navigating directories and executing commands is assumed.

1. Basic Certificate Validation:

The most fundamental command to check a certificate’s validity connects directly to the server and retrieves the certificate chain:

bash
openssl s_client -connect example.com:443 -showcerts

  • openssl s_client: This is the command for connecting as a client to a server using SSL/TLS.
  • -connect example.com:443: Specifies the server’s hostname (example.com) and port (443 is the standard HTTPS port). Replace example.com with the actual domain you want to check.
  • -showcerts: This crucial option displays the entire certificate chain presented by the server. Without this, you’ll only see limited certificate information.

Output Analysis (Important Sections):

The output will be verbose, but here are the key sections to examine:

  • CONNECTED(...): Indicates a successful connection. If you see errors here, it could be a network issue or the server isn’t serving SSL/TLS on that port.
  • Certificate chain: This section lists the certificates, starting with the server’s certificate (typically labeled s: for “subject” and i: for “issuer”) and working up through any intermediate certificates to the root certificate. Each certificate in the chain is presented.
  • depth=: Indicates the level in the certificate chain. depth=0 is the server’s certificate, depth=1 is usually the intermediate certificate, and higher numbers represent further up the chain towards the root.
  • subject=: The “subject” of the certificate, usually the Common Name (CN), which should match the hostname you’re connecting to (or be a valid wildcard, like *.example.com). Mismatch here indicates a potential security issue (e.g., hostname mismatch).
  • issuer=: The “issuer” of the certificate, which should match the “subject” of the next certificate in the chain, linking the certificates together.
  • notBefore= and notAfter=: The validity period of the certificate. An expired certificate (notAfter is in the past) or a certificate that is not yet valid (notBefore is in the future) will cause validation to fail.
  • Verify return code:: This is crucially important.
    • 0 (ok): Indicates that the certificate chain validated successfully.
    • 18 (self signed certificate): The certificate is self-signed (not issued by a trusted CA). While technically valid, browsers will not trust this by default.
    • 19 (self signed certificate in certificate chain): A self-signed certificate is present in the chain, not necessarily at the root.
    • 20 (unable to get local issuer certificate): OpenSSL couldn’t find the issuer’s certificate in its trust store. This is a common issue and often requires adding intermediate or root certificates to your system’s trust store (explained later).
    • 21 (unable to verify the first certificate): Similar to 20, but specifically refers to the server’s certificate.
    • Other error codes: Refer to the OpenSSL documentation for specific error codes. There are many possible issues, including expired certificates, revoked certificates, and problems with the certificate chain.

2. Specifying a CA Bundle (Trust Store):

If you encounter the unable to get local issuer certificate (error code 20) error, OpenSSL can’t find the necessary CA certificates to validate the chain. You can provide a CA bundle (a file containing multiple trusted CA certificates) using the -CAfile option:

bash
openssl s_client -connect example.com:443 -showcerts -CAfile /path/to/ca-bundle.crt

  • -CAfile /path/to/ca-bundle.crt: Specifies the path to a file containing a list of trusted CA certificates in PEM format. You can download CA bundles from various sources, such as your operating system’s certificate store or the CA’s website (e.g., Let’s Encrypt’s root certificates). You may need to convert certificates from other formats (like .cer or .p7b) to PEM using OpenSSL.

3. Specifying a CA Directory (Trust Store):

Alternatively, you can point OpenSSL to a directory containing individual CA certificate files using the -CApath option. OpenSSL expects the files in this directory to have specific names based on the certificate’s hash:

bash
openssl s_client -connect example.com:443 -showcerts -CApath /path/to/ca-directory/

  • -CApath /path/to/ca-directory/: Specifies the directory containing individual CA certificate files. The files must be named according to the certificate’s hash, which you can obtain using openssl x509 -hash -in cert.pem. You usually have to create symbolic links with the correct hash names.
  • Example of creating the hash link (assuming your certificate is cert.pem and the destination directory is /path/to/ca-directory/)
    bash
    HASH=$(openssl x509 -hash -noout -in cert.pem)
    ln -s cert.pem /path/to/ca-directory/$HASH.0

4. Ignoring Specific Errors (Caution!):

In some testing or debugging scenarios, you might want to ignore specific errors. This is strongly discouraged for production use, as it bypasses security checks. However, for understanding the certificate chain even with errors, these options can be useful (but dangerous if misused):

  • -verify_return_error: Prints the verification error, but still proceeds with the connection.
  • -no_verify_hostname: Disables hostname verification (checking if the certificate’s CN matches the hostname). This is extremely risky and should never be used in production.

5. Checking a Local Certificate File:

You can also validate a certificate file directly, without connecting to a server:

bash
openssl x509 -in cert.pem -text -noout

  • openssl x509: This command is used for working with X.509 certificates (the standard format for SSL/TLS certificates).
  • -in cert.pem: Specifies the input certificate file (replace cert.pem with your file).
  • -text: Prints the certificate details in a human-readable format.
  • -noout: Prevents the certificate itself from being printed (only the decoded information).

This command displays the certificate’s contents, including the subject, issuer, validity period, and extensions. You can also verify the signature against a CA certificate:

bash
openssl verify -CAfile /path/to/ca-bundle.crt cert.pem

  • openssl verify: Verifies the signature of the certificate.
  • -CAfile /path/to/ca-bundle.crt: Specifies the CA bundle (or -CApath for a directory).
  • cert.pem: The certificate file to verify.

6. Checking for Specific Certificate Extensions:

You can examine specific certificate extensions using OpenSSL:

bash
openssl x509 -in cert.pem -noout -ext subjectAltName

  • -ext subjectAltName: Prints the Subject Alternative Name (SAN) extension, which lists additional hostnames or IP addresses covered by the certificate. This is important for multi-domain and wildcard certificates. You can replace subjectAltName with other extension names (e.g., basicConstraints, keyUsage, extendedKeyUsage).

7. Checking for Certificate Revocation (OCSP):

Certificate revocation is a mechanism to invalidate a certificate before its expiration date. OpenSSL can check revocation using the Online Certificate Status Protocol (OCSP):

bash
openssl ocsp -issuer issuer.pem -cert cert.pem -url http://ocsp.example.com -respout ocsp_response.der

  • openssl ocsp: The command for OCSP checking.
  • -issuer issuer.pem: The issuer’s certificate (needed to verify the OCSP response).
  • -cert cert.pem: The certificate you’re checking.
  • -url http://ocsp.example.com: The OCSP responder URL (obtained from the certificate’s “Authority Information Access” extension).
  • -respout ocsp_response.der: saves the response in binary DER format.

Then to check the validity:
bash
openssl ocsp -issuer issuer.pem -cert cert.pem -respin ocsp_response.der -CAfile ca-bundle.crt

  • -respin ocsp_response.der: The saved DER response file.
  • -CAfile ca-bundle.crt: Your trusted CA bundle.
    This is a simplified example. OCSP stapling (where the server provides the OCSP response directly) is a more efficient method.

8. Example: Checking Let’s Encrypt Certificate and Intermediate

Let’s say you want to validate the certificate for www.example.com, which uses Let’s Encrypt.

  1. Get the chain:
    bash
    openssl s_client -connect www.example.com:443 -showcerts < /dev/null > chain.pem

    (The < /dev/null prevents OpenSSL from waiting for input after the connection, which would hang indefinitely.)

  2. Split the chain (optional, but good practice):
    The chain.pem file contains all the certificates. You can split them into individual files if you need them separately:
    bash
    csplit -s -f cert- chain.pem '/-----BEGIN CERTIFICATE-----/' '{*}'

    This will create files named cert-00, cert-01, etc. cert-00 is usually the server certificate, cert-01 the intermediate, and so on.

  3. Verify the server certificate against the intermediate:
    bash
    openssl verify -CAfile cert-01 cert-00

    (Assuming cert-01 is the intermediate certificate). This verifies that the server’s certificate (cert-00) is signed by the intermediate. You should see cert-00: OK.

  4. Verify the intermediate certificate against the root (if needed):
    You’ll need Let’s Encrypt’s root certificate (e.g., ISRG Root X1). Download it from Let’s Encrypt’s website (it’s in PEM format) and save it as letsencrypt-root.pem.
    bash
    openssl verify -CAfile letsencrypt-root.pem cert-01

    This verifies that the intermediate certificate is signed by the trusted root. You should see cert-01: OK.

Conclusion:

OpenSSL is a powerful tool for validating SSL/TLS certificates. Understanding how to use it effectively is essential for diagnosing certificate issues, ensuring secure communication, and maintaining the integrity of your online services. This article has covered the most common scenarios and commands. Always refer to the OpenSSL documentation for the most up-to-date and complete information. Remember that proper certificate validation is crucial for security, and incorrectly configured or ignored errors can lead to significant vulnerabilities.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top