Update

Since this article was written, there is a new initiative in broadening the adoption of HTTPS/SSL across the web: LetsEncrypt. They provide free, automated SSL certificates that actually work.

Defining the Problem

I encountered a peculiar problem with my signed SSL certificates the other day. In the latest versions of Firefox and Chrome, the SSL certificate was being trusted and worked just fine. However, in Chrome in iPad (and likely other browsers with similarly limited capabilities), the certificate was deemed "untrusted."

I ran an SSL Test on the domain with which I was having the problem. This yielded a bit of very useful information:

Chain issues     Incomplete

This gave me what I needed to further debug the problem. I discovered that I needed to have the server send a "Certificate Chain" with the initial SSL hand shake in order for browsers that do not support "certificate discovery" to find the root certificate.

For additional information, see Intermediate Certificate Authorities.

Fixing the Problem

First, you will need to search your Certificate Authority's (CA) website to download their Intermediate CA (or "Certificate Chain") file. This file will contain the concatenated chain of trusted CA certificates needed to reach the root certificate. Once you find and download the chain file, you will need to upload it to your server and configure your web server to provide it to clients during SSL handshakes.

Configuring nginx

In your site's server configuration add the following:

ssl_certificate /path/to/full-certificate-chain.pem;
ssl_trusted_certificate /path/to/certificate-chain.pem;
  • certificate-chain.pem - This file should contain the CA certificate chain (in descending order).
  • full-certificate-chain.pem - This should contain the same chain of certificates as the certificate-chain.pem file, but with the addition of your site's certificate at the top of the file.

After you're done modifying your site's configuration file, test the changes with the following command:

nginx -t

If everything's ok, it's safe to reload all nginx configurations:

service nginx reload

It's not necessary to do a full restart.

Configuring Apache

In your website's virtual host for port 443, edit the following line:

#SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt

Uncomment the line and have it reference the path to the chain file you just uploaded to the server:

SSLCACertificateFile /path/to/full-certificate-chain.pem;
  • full-certificate-chain.pem - This file should contain your site's certificate along with every CA's certificate added in descending order.

Restart Apache.

Is the Problem Fixed?

Run the SSL Test again. If all is well, the chain issue should be resolved. If not, you can further debug the problem by using the following command in a terminal window on your local machine (not on the server with the SSL issue):

openssl s_client -showcerts -verify 32 -connect domain-name:443
  • You will need to have openssl installed to run this command
  • Be sure to replace domain-name with the domain that is having the SSL issue

The output of this command is quite dense and can be difficult to sort through. You will want to first find the top of the output, and then search for something like this:

verify error:num=20:unable to get local issuer certificate