Suffix

Ruby and OpenSSL certificates

Fixing the Ruby 1.9 “certificate verify failed” error.

I recently upgraded to Mountain Lion and reinstalled Ruby 1.9.3 with RVM. Today I needed some SSL connections to interface with a payment gateway in a Rails application and this error showed up:

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

The OpenSSL library can’t verify the Certificate Authority (CA) the certificate from the responding server is signed against and breaks. Certificates are verified using a chain of trust. The certificate should be verified by his parent, which, in his turn should be verified by his parent until you reach a root certificate.

SSL::VERIFY_NONE

A lot of resources on the web seem to take the easy route: not verifying certificates with OpenSSL::SSL::VERIFY_NONE. While this works, it’s insecure. Why use SSL if you don’t intend to use its advantages? Not verifying a certificate means you simply trust the remote server is whom he claims to be, not who he really is. That might be acceptable for your personal website but not for a payment gateway. James Golick wrote a nice article explaining his fight against SSL::VERIFY_NONE.

The Certificate Authority (CA) bundle

You’ll need a CA bundle. The cURL website maintains a version of the Mozilla CA bundle in PEM format. Grab one of their certificates.

Once dowloaded you can tell Net::HTTP to use this certificate:

require "net/https"
https = Net::HTTP.new("encrypted.google.com", 443)
https.use_ssl = true
https.ca_file = "path_to_certificate";
https.request_get("/")

Or, my prefered way, you can use an environment variable and not have hardcoded paths:

export SSL_CERT_FILE="path_to_certificate"