May 8, 2014 by Daniel P. Clark

Ruby SSL with Twitter failed on cert OpenSSL issue on Windows 7

I’ve searched high and low for an answer to this. Many people have their own answers. None of them have worked for me. I’ll provide the situation.

So I want to access twitter and upon using net:HTTP’s post function I get this error.

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

 Yes I know everyone gets this message.

Here are viable solutions I found.

First; manually set the cert file:

#!/usr/bin/env ruby
require 'net/https'
require 'uri'

uri = URI.parse( ARGV[0] || 'https://localhost/' )
http = Net::HTTP.new(uri.host, uri.port)

if uri.scheme =="https"
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
  http.ca_file = File.join(File.dirname(__FILE__),"cacert.pem")
end

http.start {
  http.request_get(uri.path){|res|
    print res.body
  }
}

 

This was provided by Ariejan de Vroom at this link http://blog.kabisa.nl/2009/12/04/ruby-and-ssl-certificate-validation/

Many people have given a similar answer to this. This did not work for me.

Then I found something that brought me along the right path. This guy Mislav Marohnićhttp://mislav.uniqpath.com/2013/07/ruby-openssl/ nailed the area of concern. It has to do with OpenSSL::X509::DEFAULT_CERT_FILE and OpenSSL::X509::DEFAULT_CERT_DIR . Which turns out are hard coded into my Ruby 1.9.3 through it’s source code. Mislav gives his work around like so:

require 'https'

http = Net::HTTP.new('example.com',443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER

http.cert_store = OpenSSL::X509::Store.new
http.cert_store.set_default_paths
http.cert_store.add_file('/path/to/cacert.pem')# ...or:
cert = OpenSSL::X509::Certificate.new(File.read('mycert.pem'))
http.cert_store.add_cert(cert)

 

I dabbled around with this and I would always get this error

OpenSSL::X509::StoreError: cert already in hash table

 Bah humbug and all that stuff!

If you know how the inner code is written for OpenSSL::X509 I suppose you could overwrite the code with your own ruby functions/methods/classes/modules/etc. It’s a project.

I should also mention he has written a script that should help debug what’s going on. It may help you, but not in my case. The link is on his page.

Oh yeah. I also set

ENV['SSL_CERT_FILE']
ENV['SSL_CERT_DIR']

 in my ruby code without success.

Then I proceeded to set the environment variables in windows by Start -> Control Panel -> System ->Advanced System Settings -> Advanced(tab) -> Environment Variables -> System variables Newand added the SSL_CERT_DIR and SSL_CERT_FILE. This didn’t work either.

And the certified gem didn’t work for me… https://github.com/stevegraham/certified

So I will now provide you with my hack answer for all you Windows 7 users out there below.


So I dug around and basically stared at the hard coded path of the certs. By typing this at the command line

ruby -ropenssl -e 'puts OpenSSL::X509::DEFAULT_CERT_FILE'

I got the following…

c:/Users/Luis/Code/openknapsack/knap-build/var/knapsack/software/x86-windows/openssl/1.0.0k/ssl/cert.pem

So my solution was to first download cacert.pem from http://curl.haxx.se/ca/cacert.pem to c:\ . (Caution: Twitter recommends getting your certs from authoritative sources such as Verisign.) Then open up Windows Control Panel -> Administrative Tools -> Windows PowerShell Modules. Then I proceeded to type out:

cd \
cd users
mkdir Luis
cd Luis
mkdir Code
cd Code
mkdir openknapsack
cd openknapsack
mkdir knap-build
cd knap-build
mkdir var
cd var
mkdir knapsack
cd knapsack
mkdir software
cd software
mkdir x86-windows
cd x86-windows
mkir openssl
cd openssl
mkdir 1.0.0k
cd 1.0.0k
mkdir ssl
cd ssl
cp c:\cacert.pem .\cert.pem

And now everything works! Yes it’s a cheap hack and it’s ugly. But now both you and I can get back to doing serious coding and not worry about pesky problems. I know it’s not a great fix, but it’s the only thing that worked for me, and it should for you too. If some one would like to write a PowerShell script to auto install the cert file into this directory then you could more easily deploy your Ruby project to Windows 7. Just a thought. By the way, you can duplicate this process for any operating system should the need arise. Just find the path the cert file belongs in with:

ruby -ropenssl -e 'puts OpenSSL::X509::DEFAULT_CERT_FILE'

And be sure to rename the file as it appears in the output!

Please comment, share, subscribe to my RSS Feed,and follow me on twitter @6ftdan!

God Bless! – Daniel P. Clark

#cert#https#openssl#programming#ruby#secure#ssl#twitter#uri#Windows#Windows 7

Leave a Reply

Your email address will not be published / Required fields are marked *