OpenSSL is a robust software library that provides a rich collection of secure communications functionalities via the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols. In this post, we will focus on OpenSSL’s capabilities related to SSL/TLS certificates: validation, retrieval, and handling of certificate chains including intermediate certificates.

Validating a Certificate

To verify the validity of an SSL/TLS certificate, you can use the openssl verify command:

$ openssl verify cert.pem

This command will attempt to validate the certificate stored in cert.pem. If the root certificate authority (CA) certificate is unknown to your system, you may encounter an error:

cert.pem: C = Country, ST = State, O = Organization, CN = FQDN
error 20 at 0 depth lookup:unable to get local issuer certificate

This error message indicates that the root Certificate Authority (CA) that issued the certificate is unknown to your system, and as such, the certificate chain cannot be validated.

To find out who the issuing CA is for the certificate, use the following command:

$ openssl x509 -in cert.pem -noout -issuer

This will display the Common Name (CN) of the CA that issued the certificate in cert.pem. If the CA is an intermediate CA, we will need to follow the certificate chain to find the root CA.

Checking Certificate Chains

You can confirm that you have the correct root CA certificate by matching the subject of the root CA certificate with the issuer of the server certificate.

Here’s how to retrieve the subject of the root CA certificate:

$ openssl x509 -noout -subject -in ca.pem

The subject of the root CA certificate should match the issuer of the server certificate. If they don’t, there might be intermediate certificates to consider. You can verify the certificate chain by using the root CA certificate file:

$ openssl verify -CAfile ca.pem cert.pem

This should return cert.pem: OK if the certificate chain is correct.

Working with Intermediate Certificates

If you still encounter errors or mismatches, you may need to include an intermediate certificate. Let’s assume we have an intermediate certificate in intermediate.pem. We can confirm its subject and issuer using similar commands as above:

$ openssl x509 -in intermediate.pem -noout -subject
$ openssl x509 -in intermediate.pem -noout -issuer

These should respectively match with the issuer of the server certificate and the subject of the root CA certificate.

To verify the server certificate with an intermediate certificate, use the openssl verify -CAfile ca.pem -untrusted intermediate.pem cert.pem command.

Ordering Certificates

Applications usually require the complete certificate chain in a single file, with the server certificate first, followed by the intermediate certificates. Here’s how you can create the chain:

openssl crl2pkcs7 -nocrl -certfile chain.pem | openssl pkcs7 -print_certs -noout

This command will output the chain of certificates, each with its subject and issuer.

Real World Verification

In a real-world situation, a server certificate may not be directly issued by a root CA but instead by an intermediate CA. To validate such certificates, OpenSSL provides a way to specify both the root and intermediate certificates.

Let’s take the following command as an example:

openssl verify -CAfile rootCA.crt -untrusted intermediateCA1.crt -untrusted intermediateCA2.crt some-domain-com.crt

In this command:

  • openssl verify: The verify command in OpenSSL is used to validate certificates and certificate chains.
  • -CAfile rootCA.crt: This argument specifies the root Certificate Authority (CA) certificate file. The root CA is the top of the certificate chain and is trusted implicitly.
  • -untrusted intermediateCA1.crt and -untrusted intermediateCA2.crt: The -untrusted argument specifies intermediate CA certificates. These certificates are used to form a chain of trust from the server certificate to the root CA.
  • some-domain-com.crt: This is the end-entity certificate you are verifying. It could be a server certificate or a client certificate, in this example for some-domain.com.

Validating a Certificate Matches a Private Key

If you have a certificate and a private key, and you want to check whether they match, you can use the following command:

(openssl x509 -noout -modulus -in server.crt  | openssl md5 ; openssl rsa -noout -modulus -in server.key | openssl md5) | uniq

This command computes the MD5 hash of the modulus of both the certificate and private key. If the hashes match, it means that the private key matches the certificate.

Checking the Server’s Certificate Chain

To check the certificate chain of a server, you can use:

openssl s_client -showcerts -connect some-domain.com:443

This command will connect to the server (some-domain.com on port 443 in this example) and print the certificate chain.

Using Server Name Indication (SNI) with OpenSSL

When a server hosts multiple TLS-protected websites, it may present different certificates depending on the hostname the client is connecting to. To specify the hostname, use the -servername option:

openssl s_client -connect some-domain.com:443 -showcerts -servername some-domain.com

In this command, OpenSSL connects to the server and requests the certificate for some-domain.com.

Retrieving a Certificate from a Server

To fetch the SSL/TLS certificate from a server, use the openssl s_client command:

echo | openssl s_client -servername domain.com -connect domain.com:8443 |\
  sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > certificate.crt

This command will save the SSL/TLS certificate of domain.com running on port 8443 to certificate.crt.

OpenSSL provides a variety of functionalities that are crucial for handling SSL/TLS certificates, from validation and verification to retrieval. With OpenSSL, you can ensure that your secure communications are truly secure, with the right certificates in place and correctly configured.



Buy Me a Coffee