Connecting using https to a server with a certificate signed by a CA I created

12,597

Solution 1

I assume that your Tomcat doesn't like the protocol version that Ruby tries to negotiate. Ruby uses SSLv23 by default, but I've heard other cases where this was a problem for Java-based web servers. The error message you are getting indicates that the handshake fails while setting up the connection and trying to read the server's response. Try adding either

http.ssl_version = :TLSv1

or

http.ssl_version = :SSLv3

and see if that already helps.

If this does not fix the problem yet, it would be very interesting to see why your server rejects the connection attempt. Try running your Tomcat with -Djavax.net.debug=ssl and please post the relevant parts (connection information, exception stacktrace) as to why the attempt fails.

Solution 2

I am using ruby 1.9.3 and faced the same error while using nokogiri to parse some secure urls.

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: (null)

The above answer provided by emboss is correct but make sure the ssl error generated is this one that is mentioned above. I have followed the same and found a solution like this mentioned below.

uri = URI(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.ssl_version = :SSLv3
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
response = http.get(url)

now the response is having the correct html parsed for the secured url that is passed to the codes in the url .

Share:
12,597
Jonathan
Author by

Jonathan

Updated on June 05, 2022

Comments

  • Jonathan
    Jonathan almost 2 years

    I have a test environment that uses Ruby to drive a server over an https connection. Since the latest versions of Ruby refuse to connect to an https server with an invalid certificate (see this earlier question of mine) and I would like to start using a newer version of Ruby, I am trying to set up a valid certificate.

    I have created a CA certificate to use (there are multiple servers being tested so this seems the easier way), and have successfully used it to sign a new certificate which has been installed on a server and is being used. I have added the CA certificate to the browser store and it (the browser) will now connect to the server without complaint. So I am confident my certificates are valid and set up correctly.

    I know that Ruby does not use the same store as the browser. I have used the CA file available here to test connecting to other (public) servers (set using the Net::HTTP#ca_file= method) and this also works.

    What I cannot get to work is Ruby connecting to my server using my certificate. I have tried various ways of pointing it at my certificate (including adding my certificate to the file linked above) and it always gives the same error:

    SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A (OpenSSL::SSL::SSLError)
    

    What do I have to do to convince Ruby to accept my certificate and connect to my server?

    The code I am using is:

    require 'net/https'
    
    uri = URI.parse("https://hostname/index.html")
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    http.ca_file = "My CA cert file"
    request = Net::HTTP::Get.new(uri.path)
    response = http.request(request)
    

    I'm assuming this is wrong somehow. What I want to know is, what should I do to use my CA certificate?

  • emboss
    emboss about 12 years
    This doesn't matter. Ruby can deal with (bundled) PEM certificate files as well as with DER-encoded certificates. That's one of its convenient features actually, you don't need to care what format your certificates have.
  • gioele
    gioele about 12 years
    The documentation says otherwise ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/… but I will believe you, I never tried with non-PEM certificates.
  • Jonathan
    Jonathan about 12 years
    This works! Thank you so much. I knew it had to be something simple I was missing!
  • emboss
    emboss about 12 years
    Oops, I'm sorry, then I need to update the documentation :) My bad, can you do a micro edit, so that I can take the downvote away?
  • emboss
    emboss about 12 years
    You're welcome! Actually, you could help me, too. I need to figure out whether this is a real bug on the Java side. Using SSLv23 on the client side is like telling the server "I can do any protocol you want me to, just name it", so Tomcat shouldn't have rejected in the first place. What exact Tomcat version are you using, which JDK?
  • Jonathan
    Jonathan about 12 years
    Out of interest, if you happen to know, was this default changed recently? This problem only occurs with the latest releases (1.8.7-p352 and 1.9.2p290). Earlier versions are fine.
  • Jonathan
    Jonathan about 12 years
    Java version is 1.6.0_05-b13. Tomcat version is 6.0.35.
  • gioele
    gioele about 12 years
    I added a link to the documentation (I should have added it right from the beginning).
  • emboss
    emboss about 12 years
    @Jonathan Hmm, not that I know. Git blame says we use SSLv23 since 2003: github.com/ruby/ruby/blame/trunk/ext/openssl/ossl_ssl.c, L149. Could it be that you changed OpenSSL itself in the meantime?
  • emboss
    emboss about 12 years
    @Jonathan Thanks for the version infos!