UPDATE: After having seen this quite a few times over the last few months, a quick update: This is an incompatibility between how OpenSSL 0.98 and 1.x treat TLS errors: http://sourceforge.net/p/curl/bugs/1037/?page=1

Moneyquote:

This problem has to do with the TLS SNI extension.
If curl sends an SNI hostname that the server does not recognize, the server will send back a TLS Alert record with Level 1 (Warning) and Code 112 (Unrecognized name) to notify the client that the server may not do what the client is expecting (that's what reason(1112) is referring to).
In the case of Apache, if your VirtualHost does not contain a ServerName or ServerAlias statement which explicitly matches the specified domain name, Apache will send back this TLS Alert.

And this means:

So it looks like openssl 0.9.8 will fail if it receives any TLS Alert records while waiting for the Server Hello record. openssl 1.0.0 has been updated to ignore TLS Alerts that are Warnings:
http://cvs.openssl.org/chngview?cn=14772

Original post:

I ran into a strange ‘bug’ that was a little bit more annoying to debug.
Apparently OpenSSL 1.x that is getting installed by brew doesn’t seem to be 100% compatible with Ruby, at least when you install it using RVM.

I ran into a reproducible problem when trying to connect to a salesforce sandbox account. This could be distilled down to this snipped:

1
2
3
4
5
6
7
8
require 'net/http'
require 'openssl'

h = Net::HTTP.new('test.salesforce.com', 443).tap do |http|
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
h.post('/test' ,'')

Which resulted in this sad exception after 30 seconds or so:

Errno::ECONNRESET: Connection reset by peer - SSL_connect
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:799:in `connect'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:799:in `block in connect'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/timeout.rb:54:in `timeout'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/timeout.rb:99:in `timeout'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:799:in `connect'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:755:in `do_start'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:744:in `start'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:1284:in `request'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:1307:in `send_entity'
from /Users/mseeger/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/net/http.rb:1096:in `post'

It turns out that RVM can also install openssl, and it decides to go for version 0.9.8:

$ rvm pkg install openssl
Fetching openssl-0.9.8t.tar.gz to /Users/mseeger/.rvm/archives
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 3690k  100 3690k    0     0   394k      0  0:00:09  0:00:09 --:--:--  456k
Extracting openssl-0.9.8t.tar.gz to /Users/mseeger/.rvm/src
Configuring openssl in /Users/mseeger/.rvm/src/openssl-0.9.8t.
Compiling openssl in /Users/mseeger/.rvm/src/openssl-0.9.8t.
Installing openssl to /Users/mseeger/.rvm/usr
$ 

After that I just reinstalled Ruby and pointed it at the openssl version just to make extra sure:

rvm reinstall 1.9.3-p194 --with-openssl-dir=~/.rvm/usr

After that, the snipped ends up with a 404 as expected.

Comments