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