OpenSSL::SSL::SSLError: certificate verify failed
April 15, 2014
Sometimes you will inherit a ‘legacy system’. This particular system was running Ubuntu 8.04 LTS and Rails 2.3.18. Due to the recent Heartbleed security hole, the applications OAuth provider had updated their security certificates. This meant I was now getting an error and stacktrace, with the rescue message: ‘OpenSSL::SSL::SSLError: certificate verify failed’.
Reproduce the error
You can use the doctor.rb script by issuing the following commands ‘ruby doctor hostname’.
On the client's server https://google.com is working but https://facebook.com is returning a very strange error.
Attempt to upgrade
Normally this would utilise the package manager ‘apt’ to fix the issue. However, if you’re running Ubuntu 8.04 LTS you’re quickly going to find that the ‘Long Term Support’ is over. And all the packages are returning a 404.
You're on your own now...
Take a moment to contemplate your predicament.
Remove Ruby from the equation
At this point I want to establish if the error is limited to my installation of Ruby or whether it's a deeper problem. So I drop out the entire Ruby stack and use another application. 'wget' or 'curl' will do. I used curl.
Figure out what certificates you’re missing
In order to find out exactly which certificates are missing you'll want to utilize OpenSSL’s s_client. You’ll see the chain of certificates (or lack of them, in my case) back to the original certificate authority.
From this output you can see I'm missing the following certificates:
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3 i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
Install the certificates
For this client the digicerts are out of date. A Google search later and I’d found them: https://www.digicert.com/digicert-root-certificates.htm
I grabbed the certificates required.
Unfortunately these are encoded and need to be converted into text.
Now move these ca-certificates into your trusted /usr/share/ca-certificates folder.
In order to let Ubuntu know where to find the new certificates I add the '.crt' file's path relative to /usr/share/ca-certificates to /etc/ca-certificates.conf
With this in mind I append the contents of /etc/ca-certificates.conf with:
The final step is running c_rehash within /etc/ssl/certs to scan directories and take a hash value of each '.pem' and '.crt' file in the directory. It then creates symbolic links for each of the files named by the hash value. Programs on the system (like curl or wget) expect to find the certificates they require in this c_rehash'ed format.
I go back to the doctor.rb and run it again.
Success! We have the updated certificates available!
If you're reading this blog post and have a similar issue with a different certificate, this askubuntu post may also help: http://askubuntu.com/questions/73287/how-do-i-install-a-root-certificate