Reputation: 2445
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: https://www.kabisa.nl/tech/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ć https://mislav.net/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 workaround 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!
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.
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 New and 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.
Upvotes: 3
Views: 4542
Reputation: 351
just found this made by @photonstorm. Worked for me:
1 - Download R1 GlobalSign Root Certificate: https://secure.globalsign.net/cacert/Root-R1.crt
2- Save it somewhere local, so you can easily access it from a command prompt. It should save with the name Root-R1.crt
.
3- Convert to a PEM file. Here is where the post above didn't work for me, but this did: openssl x509 -in Root-R1.crt -out mycert.pem -outform PEM -inform DEF
4- Copy the new mycert.pem
file that it creates into: D:\Ruby23-x64\lib\ruby\2.3.0\rubygems\ssl_certs
<-- this path will obviously be different depending on where you've got Ruby installed!
Upvotes: 0
Reputation: 9087
If you already have downloaded Git for Windows, it has a CA-bundle which you can use.
Set SSL_CERT_DIR
to the location where Git was installed, which will be C:\Program Files\Git\mingw32\ssl\certs
(if on a 32-bit system) or C:\Program Files\Git\mingw64\ssl\certs
(if on a 64-bit system). Also, you will need to set SSL_CERT_FILE
to C:\Program Files\Git\mingw32\ssl\cert.pem
(if on a 32-bit system) or C:\Program Files\Git\mingw64\ssl\cert.pem (if on a 64-bit system).
Upvotes: 0
Reputation: 71
If you are facing this problem then download http://curl.haxx.se/ca/cacert.pem and export to your bash_profile
export SSL_CERT_FILE=PATH_TO_THe_DOWNLOADED_FILE/cacert.pem
This works for me :-)
Upvotes: 0
Reputation: 2445
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:\ . 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 ouput!
Upvotes: 7