Product SiteDocumentation Site

2.7.2. Ruby libraries using OpenSSL

There are several libraries that build on top of OpenSSL. Depending on how a library uses SSLContext, users may encounter exception from OpenSSL code saying the certificate verification failed:
>> ssl_client.connect
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
from (irb):7:in `connect'
from (irb):7
This usually happens when verify_mode is set to check the certificate, but the certificate store used does not contain trusted certificate required to verify the SSL sent by the server.


The worst advice that can be found on internet on how to fix SSL is to set
This redefines constant OpenSSL::SSL::VERIFY_PEER to have the same effect as OpenSSL::SSL::VERIFY_PEER, effectively globally disabling certificate checking.
Take Net::IMAP as example (the code below refers to Ruby 1.9.3): initialize method for creating a new IMAP connection has takes the following arguments:
def initialize(host, port_or_options = {},
            usessl = false, certs = nil, verify = true)
When SSL connection is used but certs and verify arguments are left to be assigned defaults values, SSLError may be thrown when certificate sent by server cannot be verified.


The correct solution is to always make sure certificate store used by SSLContext contains a trusted certificate that can be used to verify the certificate sent by the server. Behaviour in different Ruby versions

Default behaviour differs across Ruby versions: in Ruby 1.8, SSL enabled libraries usually falled back to VERIFY_NONE mode. The above mentioned Net::IMAP#initialize looks like this:
def initialize(host, port = PORT, usessl = false, certs = nil, verify = false)
Starting from Ruby 1.9, standard library defaults to VERIFY_PEER mode.