rubyhttpopensslssl-certificatenet-http

OpenSSL::SSL::SSLError while making post request with Net::HTTP


I tried different approaches(from google) to solve this error, but failed. I am unable to resolve this problem.

My code looks like this:

require 'net/http'
require 'uri'
require 'json'

uri = URI.parse "https://dev.ramble.com/v1/user/login"
uri.user = "user1"
uri.password = "mypass"
connection = Net::HTTP::new uri.host, uri.port
connection.use_ssl = true
connection.ca_file = "/usr/local/etc/openssl/cert.pem"
connection.verify_mode=OpenSSL::SSL::VERIFY_PEER
session = connection.start

It raise the following errors:

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
  from /Users/cmthakur/.rvm/rubies/ruby-2.1.4/lib/ruby/2.1.0/net/http.rb:920:in `connect'
  from /Users/cmthakur/.rvm/rubies/ruby-2.1.4/lib/ruby/2.1.0/net/http.rb:920:in `block in connect'
  from /Users/cmthakur/.rvm/rubies/ruby-2.1.4/lib/ruby/2.1.0/timeout.rb:76:in `timeout'
  from /Users/cmthakur/.rvm/rubies/ruby-2.1.4/lib/ruby/2.1.0/net/http.rb:920:in `connect'
  from /Users/cmthakur/.rvm/rubies/ruby-2.1.4/lib/ruby/2.1.0/net/http.rb:863:in `do_start'
  from /Users/cmthakur/.rvm/rubies/ruby-2.1.4/lib/ruby/2.1.0/net/http.rb:858:in `start'

I will be very thankful if anyone help me resolving this errors.


Solution

  • Finally I resolve the problem by changing ssl_version = :SSLv3 for now.

    tl;dr

    The approach browsers/system takes to verify SSL is plain. They simply come pre-equipped with a set of trusted certificates that are pre-screened and trusted according to the vendor. In case of Mac OS X, you can view those from Keychain under certificates/system certificates. In case of Linux, it should be somewhere around /etc/ssl/certs/. Frankly I don't know about Windows. But those should be there somewhere like in Mac OS X. As you might have noticed, there are many; actually too many to keep track to be valid. But that's how it works anyway!

    As for Ruby, the requirement of small to massive Ruby application is always scoped in comparison to the system/browsers. A browser must be ready to navigate to any "legitimate" web site that comes with public certificate served over HTTPS or other secure service endpoints. But in a typical Ruby application we might only have to connect with a few services that use TLS or would otherwise require certificate validation. So, the point of ruby coming pre-bundled with many many certificates like in the case of browser/system is sort of futile mostly. How does ruby do it then? Simple, Ruby does it manually!

    The discovery to the fix took longer because Yosemite comes with dated OpenSSL version. Again adding to complication, your favorite Ruby version manager compiles Ruby with different OpenSSL version. This mismatch causes lots of confusion for us and apparently to the RubyVM itself too ;)

    Please read through following links for technical nitty-gritty: https://mislav.net/2013/07/ruby-openssl/