See this StackOverflow post, but the gist of it is this:
PS C:\> C:\Ruby192\bin\pry.bat
pry(main)> require 'open-uri'
=> true
pry(main)> open('https://www.gmail.com')
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
from C:/RailsInstaller/Ruby1.9.2/lib/ruby/1.9.1/net/http.rb:678:in `connect'
pry(main)>
This also affects things like the savon gem and httparty, or really, any SSL URL. Is there something I'm missing on my end to make this work?
This is happening because your system is lacking a cert bundle, this
will happen also if you try to use curl from the command line.
If you look at RubyInstaller own code, we manage to connect to SSL
connections setting the proper SSL cert:
https://github.com/oneclick/rubyinstaller/blob/master/rake/contrib/uri_ext.rb#L287-295
You can download cURL pem certs from here:
http://curl.haxx.se/docs/caextract.html
Then, you should try setting SSL_CERT_FILE environment variable to
point to the full path of the file.
I've seen some threads about this on the web with links to things like:
https://gist.github.com/867550
And
https://gist.github.com/767249
Let us know if that solves your issue.
--
Luis Lavena
AREA 17
-
Perfection in design is achieved not when there is nothing more to add,
but rather when there is nothing more to take away.
Antoine de Saint-Exupéry
I get the same thing when I try the following on a freshly downloaded 1.9.2-p290:
C:\Users\Jon\Documents>irb
irb(main):001:0> p RUBY_DESCRIPTION
"ruby 1.9.2p290 (2011-07-09) [i386-mingw32]"
=> "ruby 1.9.2p290 (2011-07-09) [i386-mingw32]"
irb(main):002:0> ENV['SSL_CERT_FILE'] = 'C:/tools/cacert.pem'
=> "C:/tools/cacert.pem"
irb(main):003:0> require 'open-uri'
=> true
irb(main):004:0> f = open 'https://www.gmail.com'
OpenSSL::SSL::SSLError: hostname was not match with the server certificate
from C:/ruby192/lib/ruby/1.9.1/openssl/ssl-internal.rb:121:in `post_connection_check'
from C:/ruby192/lib/ruby/1.9.1/net/http.rb:680:in `connect'
...
irb(main):005:0> OpenSSL::OPENSSL_VERSION
=> "OpenSSL 1.0.0d 8 Feb 2011"
...but on a recently built 1.9.3 from our master branch I get:
C:\Users\Jon\Documents\RubyDev>ripl
>> p RUBY_DESCRIPTION
"ruby 1.9.3dev (2011-09-16 revision 33281) [i386-mingw32]"
=> "ruby 1.9.3dev (2011-09-16 revision 33281) [i386-mingw32]"
>> ENV['SSL_CERT_FILE'] = 'C:/tools/cacert.pem'
=> "C:/tools/cacert.pem"
>> require 'open-uri'
=> true
>> f = open 'https://www.gmail.com'
=> #<File:C:/Users/Jon/AppData/Local/Temp/open-uri20110916-4256-1dirmt1>
>> f.read(100)
=> "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <title>Gmail: Email from Google"
>> OpenSSL::OPENSSL_VERSION
=> "OpenSSL 1.0.0e 6 Sep 2011"
Jon
---
blog: http://jonforums.github.com/
twitter: @jonforums
"Anyone who can only think of one way to spell a word obviously lacks imagination." - Mark Twain
That will fail, www.gmail.com redirects you to mail.google.com, so the
cert is not for gmail.com but for mail.google.com:
>> r = open("https://www.gmail.com"); nil
OpenSSL::SSL::SSLError: hostname was not match with the server certificate
>> r = open("https://mail.google.com"); nil
=> nil
>> r.read
=> "<html><head><meta http-equiv=\"Refresh\"
content=\"0;URL=https://mail.google.com/mail/\" /></hea
d><body><script type=\"text/javascript\"
language=\"javascript\"><!--\nlocation.replace(\"https://ma
il.google.com/mail/\")\n--></script></body></html>"
> That seems to fail in a different way, but maybe that's supposed to fail the
> check?
Correct.
> For another application, I need to define the CA cert, certificate and key
> files, as I would do from cURL on the command-line. This can be done in
> savon like so:
For cURL, I've placed curl-ca-bundle.crt in the same directory of
cURL, and that allows me to use cURL without indicating the
certificate file every time.
> require 'savon'
> $client = Savon::Client.new do
> wsdl.document = "my-awesome-wsdl.wsdl"
> wsdl.endpoint = "https://thing.somewhere.com/xml/query"
> end
> $client.http.proxy = ENV['http_proxy']
> $client.http.auth.ssl.cert_key_file = "key.pem"
> $client.http.auth.ssl.cert_key_password = "password"
> $client.http.auth.ssl.ca_cert_file = "ca.pem"
> $client.http.auth.ssl.cert_file = "client.pem"
> $client.http.auth.ssl.verify_mode = :none
> $client.request :query_request
Can you indicate *full path* to the ca_cert_file?
Also, if you set SSL_CERT_FILE, it needs to be with full path.
> So is the SSL_CERT_FILE supposed to fix things across the board, or just for
> general uses? I've even applied a change to set the SSL_CERT_FILE to be the
> same .pem that I use for this service (set SSL_CERT_FILE=.....ca.pem), but
> that doesn't seem to change anything.
>
Hmn, works for me for open-uri, and I bet will do for Savon if you use
the full path too.
Can you try? don't have a SOAP service around to connect to for trying, sorry.
Please do "SET SSL_CERT_FILE=" from outside your script, in your
environment prior anything.
I'm not sure how that works with OpenSSL.
> require 'savon'
> require 'pry'
> cert_dir = "C:/Certificates/"
> $client = Savon::Client.new do
> wsdl.document = "my-awesome-wsdl.wsdl"
> wsdl.endpoint = "https://thing.somewhere.com/xml/query"
> http.auth.ssl.cert_key_file = "#{cert_dir}/key.pem"
> http.auth.ssl.cert_key_password = "password"
> http.auth.ssl.ca_cert_file = "#{cert_dir}/ca.pem"
> http.auth.ssl.cert_file = "${cert_dir}/client.pem"
> http.auth.ssl.verify_mode = :none
> end
Are you sure this code is correct? you're doing ${cert_dir} for your
client certificate.
Why are you having a client certificate in the first place? is not
enough verify the authenticity of the remote?
Does the ca cert bundle you have include the certificate of the remote
server you're trying to connect? It is worthless specify the CA cert
file if doesn't contain it.
> Still throws the same exception as above. I'm not terribly familiar with
> how certificates work, so I'm truly confused what I'm even reading in the
> exception. I need to find another gem/lib to test this against, but I had a
> hard enough time finding this one, so I'll get back to you if I can
> reproduce this somewhere else with another gem.
>
I'm not familiar with either Savon or Pry (which is what you're
using), what I can tell you is that OpenSSL and the lookup of certs
from the ca cert bundle by SSL_CERT_FILE doest work, as you noted
before with your open-uri attempt.
So, we can discard that is the problem.
Now, I don't know any SOAP server/service to connect with that I can
try this out and help you better, nor does Savon documentation mention
anything about SSL in their README [1] or their website [2]
I've tried to follow the method call in your example from auth here:
https://github.com/rubiii/httpi/blob/master/lib/httpi/request.rb#L67
To here:
https://github.com/rubiii/httpi/blob/master/lib/httpi/auth/config.rb#L57
And here:
https://github.com/rubiii/httpi/blob/master/lib/httpi/auth/ssl.rb#L31
Have you tried only specifying ca_cert_file?
Sorry that I'm not able to answer your questions and still ask more,
but without access to a SOAP server to help you, I'm useless.
[1] https://github.com/rubiii/savon
[2] http://savonrb.com/
Hello, you're confusing things out.
First:
RubyInstaller links against a private copy of OpenSSL, so require
"openssl" works.
The OpenSSL libs you mention above can generate segmentation fault for
programs that are linked against MSVCRT, simply because these
libraries are linked against a different version of MSVCR
See:
http://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/ms235460(v=vs.80).aspx
If you use that approach, be warned.
> I now just install these as part of any new RubyInstaller/DevKit
> installation on Windows and then the curl libraries and then the curb
> gem to be sure the installation works.
>
The curb gem and the curl headers and development libraries are tricky
but lot of developers did manage to solve, search the group.
Thank you for sharing your approach, but these comments has nothing to
solve the issue since is SOAP/SSL related and not OpenSSL related.