Ruby 1.8.7 and Net :: HTTP: creating a SSL GET request with a client certificate?

I am trying to get a resource over SSL using Net::HTTP . Here is the relevant code snippet:

 req = Net::HTTP::Get.new(ContentURI.path) https = Net::HTTP.new(ContentURI.host, ContentURI.port) https.use_ssl = true https.cert = OpenSSL::X509::Certificate.new(@cert_raw) https.key = OpenSSL::PKey::RSA.new(@cert_key_raw) https.verify_mode = OpenSSL::SSL::VERIFY_PEER https.ca_file = File.join(TestDataPath, 'cacert.pem') resp = https.start { |cx| cx.request(req) } 

or with an alternative last line:

 resp = https.get(ContentURI.path) 

I checked that the various bits (cert, key, CA cert, etc.) are correct.

The problem is that cx.request(req) throws an exception:

 OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv3 read server session ticket A 

The Apache SSL error log on the server contains the following:

 [Tue Jan 24 11:47:26 2012] [debug] ssl_engine_kernel.c(1876): OpenSSL: Loop: SSLv3 read finished A [Tue Jan 24 11:47:26 2012] [debug] ssl_engine_kernel.c(1905): OpenSSL: Exit: error in SSLv3 write session ticket A [Tue Jan 24 11:47:26 2012] [debug] ssl_engine_kernel.c(1905): OpenSSL: Exit: error in SSLv3 write session ticket A [Tue Jan 24 11:47:26 2012] [info] [client 10.11.88.53] SSL handshake interrupted by system [Hint: Stop button pressed in browser?!] [Tue Jan 24 11:47:26 2012] [info] [client 10.11.88.53] Connection closed to child 0 with abortive shutdown (server _SERVERNAME_:443 

The certified file cert, key and CA work with this SSL host using other tools; I'm just having trouble reproducing this success using Net::HTTP[S] .

Thanks to everyone who can determine what I'm doing wrong!

+8
ruby certificate ssl client-certificates
source share
1 answer

I would say this is a question of your Apache installation, not a problem with Ruby itself.

Check this:

 $ curl https://palladium.wejn.cz/sslcerttest/ curl: (56) SSL read: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure, errno 0 $ curl https://palladium.wejn.cz/sslcerttest/ -E client.pem <pre>Yop.</pre> 

And then:

 #!/usr/bin/ruby require 'net/http' require 'net/https' require 'openssl' require 'uri' ContentURI = URI.parse("https://palladium.wejn.cz/sslcerttest/") @cert_raw = File.read('client.pem') @cert_key_raw = @cert_raw TestDataPath = '.' req = Net::HTTP::Get.new(ContentURI.path) https = Net::HTTP.new(ContentURI.host, ContentURI.port) https.use_ssl = true https.cert = OpenSSL::X509::Certificate.new(@cert_raw) https.key = OpenSSL::PKey::RSA.new(@cert_key_raw) https.verify_mode = OpenSSL::SSL::VERIFY_PEER https.ca_file = File.join(TestDataPath, 'cacert.pem') resp = https.start { |cx| cx.request(req) } p resp p resp.body 

leads to:

 $ ruby a.rb #<Net::HTTPOK 200 OK readbody=true> "<pre>Yop.</pre>\n" $ dpkg -l ruby1.8 | tail -n1 | awk '{print $3}' 1.8.7.302-2squeeze1 $ ruby -v ruby 1.8.7 (2010-08-16 patchlevel 302) [x86_64-linux] 

Of course, the apache configuration in question:

 <Directory /var/www/sslcerttest/> SSLVerifyClient require SSLVerifyDepth 5 SSLCACertificateFile /var/www/sslcerttest/cacert.pem SSLCACertificatePath /var/www/sslcerttest/ SSLOptions +FakeBasicAuth SSLRequireSSL SSLRequire %{SSL_CLIENT_S_DN_O} eq "Wejn sro" and %{SSL_CLIENT_S_DN_OU} eq "Server Certificate" </Directory> 

Perhaps posting additional information (apache configuration for verification) will be useful in tracking this issue ...

+5
source

All Articles