SSL certificate chains

SSL certificate verification

Your browser knows a list of Certificate Authorities (CAs) that it trusts; this list is called the "trust store". On Firefox 41 you can find it at Preferences / Advanced / Certificates / View Certificates / Authorities.

When connecting to a web site via HTTPS, the web server sends the public part of the web site's SSL certificate to your browser. The browser then checks if the certificate is signed by one of the CAs in its trust store.

 Browser -----[asks]----> Trust store
           +----------------------+          +-------------+
           |   SSL certificate    |          |Do we trust  |
           |valid for: example.org|          | 0x123456789 |
           |signed by: 0x123456789|          |           ? |
           +----------------------+          +-------------+
]]>

If it finds the certificate in the trust store, all is fine and the green lock icon is shown. If it does not find a trusted CA certificate, a warning is shown:

This Connection is Untrusted

You have asked Firefox to connect securely to example.org, but we can't confirm that your connection is secure.

Normally, when you try to connect securely, sites will present trusted identification to prove that you are going to the right place. However, this site's identity can't be verified.

What Should I Do?

If you usually connect to this site without problems, this error could mean that someone is trying to impersonate the site, and you shouldn't continue.

example.org uses an invalid security certificate.

The certificate is not trusted because the issuer certificate is unknown. The server might not be sending the appropriate intermediate certificates. An additional root certificate may need to be imported.

(Error code: sec_error_unknown_issuer)

What is a SSL certificate chain?

In reality, the web site's certificate will not be signed by the CA's certificate directly.

Web site certificate signing at CAs is done automatically these days. Imagine what happens when the CA's certificate gets stolen - the certificate's new owners would be able to issue certificates for all domain names, and the CA could do nothing against it - except telling browser vendors to remove its certificate from the trust store, which would mean that the CA could close its doors.

Instead, the certificate authority's main certificate (root certificate) is locked away on some offline storage medium in a safe. It was only used to sign some intermediate certificates, which have a limited life span, and which can be distrusted and revoked in case they get compromised.

|valid for: signing      |--->|valid for: signing    |
|signed by: 0x112345678|    |signed by: 0x223456789  |    |in browser trust store|
+----------------------+    +------------------------+    +----------------------+
]]>

Missing links

These intermediate certificates are used to sign web site certificates - but the browsers do not know about them. If your web server only sends out the domain's SSL certificate, the browser will show the "untrusted connection" warning, because it does only see that the certificate is signed by the intermediate certificate - which it does not know anything about it; it cannot make the connection to the CA's root certificate.

The solution to this problem is to send a certificate chain that contains both the web site's certificate as well as the intermediate certificate. With that information, the browser can follow the trust chain from the web site's certificate via the intermediate certificate up to the root certificate which is has in its trust store.

The Mozilla Certificate Authority FAQ writes about this :

Why does SSL handshake fail due to missing intermediate certificate?

This type of error indicates that the web server is incorrectly configured. The web server itself has to send the intermediate certificate along with their own SSL cert to complete the certificate chain. Only root certificates or trust anchors are included in the Mozilla root store.

Web server configuration

Apache

Since Apache 2.4.8 you can use the SSLCertificateFile directive to point to a file that contains both the web site's certificate and the intermediate certificate. Versions lower than 2.4.8 have to use the SSLCertificateChainFile directive.

Simply concatenate first the website certificate, then the intermediate certificate into the file:

$ cat /path/to/example.org.pem > /path/to/example.org-chain.pem
$ cat /path/to/intermediate.pem >> /path/to/example.org-chain.pem

Then add the following code to your virtual host configuration:

SSLCertificateFile    "/path/to/example.org-chain.pem"
SSLCertificateKeyFile "/path/to/example.org.key"

Written by Christian Weiske.

Comments? Please send an e-mail.