I'm trying to fetch a resource via SSL using Net::HTTP
. Here is the relevant code fragment:
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 the alternate last line:
resp = https.get(ContentURI.path)
I have verified that the various bits (cert, key, CA cert, etc.) are correct.
The problem is that the 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 cert, key, and CA cert file work with this SSL host through other tools; I'm just having trouble reproducing that success programatically using Net::HTTP[S]
.
Thanks to anyone who can identify what I'm doing wrong!
I'd say this is matter of your Apache setup rather than problem with Ruby itself.
Check this out:
$ 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
results in:
$ 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 config in question is:
<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 s.r.o." and %{SSL_CLIENT_S_DN_OU} eq "Server Certificate"
</Directory>
Maybe posting additional details (apache config to test against) would be of some help when tracking this issue down...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With