While using the Faraday gem with the default net/http adapter, we are passing an explicit ssl_version to net/http, however we still received handshake warnings from the server suggesting that the ssl_version was not getting down to the OpenSSL layer. After realizing that the Typhoeus adapter works just fine, I decided to dig deeper into Net::Http.
The Net::Http#connect method passes the ssl_version to OpenSSL::SSL::SSLContext via the set_params method. This appears to be problematic. The only case I can get to work as expected calls ssl_version= without calling set_params at all. I believe the error revolves around the set_params calling setters for all params (always includes an ssl_version).
This has become quite a problem due to POODLE and the systematic phasing out of SSLv3 support from many of the APIs we use in production.
We use the following abstracted gems that sit atop net/http & openssl:
RestClient
Typhoeus
Both suffer the same handshake problems. If this is actually not a problem and I am misdiagnosing it, let me know how it should work and I will update the documentation / tests.
The following code works fine on my box (x86_64-linux):
deftest_allow_tls_v1_for_client# server does not support SSLv2 / SSLv3ctx_proc=Proc.new{|ctx|ctx.options=OpenSSL::SSL::OP_ALL|OpenSSL::SSL::OP_NO_SSLv3|OpenSSL::SSL::OP_NO_SSLv2}start_server_version(:TLSv1_1,ctx_proc){|server,port|ctx=OpenSSL::SSL::SSLContext.new# It appears that explicitly calling 'ssl_version=' directly# is required rather than allowing `set_params` to call it via `__send__`ctx.set_params(ssl_version: :TLSv1_1,# soils the ssl_versionverify_mode: OpenSSL::SSL::VERIFY_NONE)assert_nothing_raised(*HANDSHAKE_ERRORS){server_connect(port,ctx){|ssl|}}}end
I had to add verify_mode: to bypass certificate verification.
As commented at the GitHub PR, there doesn't seem to be anything wrong. ssl_socket.set_params(ssl_version: :TLSv1) should be equivalent to ssl_socket.set_params; ssl_socket.ssl_version = :TLSv1.