A certificate chain is an ordered list of certificates, containing an SSL/TLS Certificate and Certificate Authority (CA) Certificates, that enable the receiver to verify that the sender and all CA's are trustworthy.
The chain or path begins with the SSL/TLS certificate, and each certificate in the chain is signed by the entity identified by the next certificate in the chain.
The certificate chain refers to our TLS/SSL certificate and how it is linked back to a trusted Certificate Authority. In order for an TLS certificate to be trusted, it has to be traceable back to the trust root it was signed off, meaning all certificates in the chain—server, intermediate and root—need to be properly trusted.
Understanding Root Intermediate Server Certificate
Root Certificate. A root certificate is a digital certificate that belongs to the issuing Certificate Authority. It comes pre-downloaded in most browsers and is stored in what is called a “trust store.” The root certificates are closely guarded by CAs.
Intermediate Certificate. Intermediate certificates branch off root certificates like branches of trees. They act as middle-men between the protected root certificates and the server certificates issued out to the public. There will always be at least one intermediate certificate in a chain, but there can be more than one.
Server Certificate. The server certificate is the one issued to the specific domain the user is needing coverage for.
How do Certificate Chains work?
When we install our TLS certificate, we also be sent an intermediate root certificate or bundle.
When a browser downloads our website’s TLS certificate upon arriving at our homepage, it begins chaining that certificate back to its root. It will begin by following the chain to the intermediate that has been installed, from there it continues tracing backwards until it arrives at a trusted root certificate.
If the certificate is valid and can be chained back to a trusted root, it will be trusted. If it can’t be chained back to a trusted root, the browser will issue a warning about the certificate.
Example of Certificate Chain
We can use the following command to shows the certificate chain.
openssl s_client -connect server_name:port -showcerts </dev/null
server_name is the server name
port is the port where SSL is listening, normally 443
openssl s_client -connect google.com:443 -showcerts </dev/null
CONNECTED(00000005) depth=3 C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA verify return:1 depth=2 C = US, O = Google Trust Services LLC, CN = GTS Root R1 verify return:1 depth=1 C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 verify return:1 depth=0 CN = *.google.com verify return:1
We can see that there are four certificates in this certificate chain.
Check Certificate Chain Subject and Issuer
We should notice the following:
The Subject of the intermediate certificate matches the Issuer of the entity certificate.
The Subject of the root certificate matches the Issuer of the intermediate certificate.
The Subject and Issuer are the same in the root certificate.
[root@ tmp]# openssl crl2pkcs7 -nocrl -certfile test | openssl pkcs7 -print_certs -noout subject=/C=US/ST=California/L=San Jose/O=test Systems, Inc./CN=test.com issuer=/C=US/O=HydrantID (Avalanche Cloud Corporation)/CN=HydrantID SSL ICA G2 [root@ tmp]# openssl crl2pkcs7 -nocrl -certfile hydssl.cer | openssl pkcs7 -print_certs -noout subject=/C=US/O=IdenTrust/OU=HydrantID Trusted Certificate Service/CN=HydrantID Server CA O1 issuer=/C=US/O=IdenTrust/CN=IdenTrust Commercial Root CA 1 [root@ tmp]# openssl crl2pkcs7 -nocrl -certfile idtrca.cer | openssl pkcs7 -print_certs -noout subject=/C=US/O=IdenTrust/CN=IdenTrust Commercial Root CA 1 issuer=/C=US/O=IdenTrust/CN=IdenTrust Commercial Root CA 1
Check Certificate Chain subject and issuer hash
It is always a good practice to verify the hash sequence of certificates as it can help in identifying issues such as the Common Name (CN) of the certificate having unwanted space or special characters.
Run the following OpenSSL command to get the hash sequence for each certificate in the chain from entity to root and verify that they form a proper certificate chain.
openssl x509 -hash -issuer_hash -noout -in certificate
openssl x509 -in entity.pem -hash -issuer_hash -noout c54c66ba #this is subject hash 99bdd351 #this is issuer hash
openssl x509 -in intermediate.pem -hash -issuer_hash -noout 99bdd351 4a6481c9
openssl x509 -in root.pem -hash -issuer_hash -noout 4a6481c9 4a6481c9
In the example shown above, notice the following:
The subject hash of the intermediate certificate matches the issuer hash of the entity certificate.
The subject hash of the root certificate matches the issuer hash of the issuer certificate.
The subject and issuer hash are the same in the root certificate.
Verify Certificate Chain with openssl
To verify a certificate and its chain for a given website, run the following command:
openssl verify -CAfile chain.pem www.example.org.pem
To verify the intermediates and root separately, use the -untrusted flag. Note that -untrusted can be used once for a certificate chain bundle of intermediates, or can be used more than once for each intermediate in a separate file.
openssl verify -CAfile root.pem -untrusted intermediate.pem www.example.org.pem
Add the -show_chain flag to output the certificate chain and corresponding depth of each certificate in the chain.
openssl verify -show_chain -CAfile chain.pem www.example.org.pem
Ordering of Certificate Chain
If we are using intermediate certificate(s), we will need to make sure that the application using the certificate is sending the complete chain (server certificate and intermediate certificate).
This depends on the application we are using that uses the certificate (always check the documentation), but usually we have to create a file containing the server certificate file and the intermediate certificate file. It is required to put the server certificate file first, and then the intermediate certificate file(s).
When using the files in our example, we can create the correct file for the chain using the following command:
$ cat server.pem intermediate.pem > chain.pem
Always double check if everything went well, we can do so by using this command which will list each certificate in order with the issuer and subject.
$ openssl crl2pkcs7 -nocrl -certfile chain.pem | openssl pkcs7 -print_certs -noout subject=/C=Countrycode/ST=State/O=Organization/CN=FQDN issuer=/C=Countrycode/ST=State/O=Organization/CN=the name of the intermediate CA subject=/C=Countrycode/ST=State/O=Organization/CN=the name of the intermediate CA issuer=/C=Countrycode/ST=State/O=Organization/CN=the name of the CA