Bug #10522
closedSSL_VERSION not handled properly in Net::Http, OpenSSL libraries
Description
https://github.com/ruby/ruby/pull/762/files
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).
Updated by dresselm (Matt Dressel) over 9 years ago
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.
Updated by dresselm (Matt Dressel) over 9 years ago
Who is the best person to review this? AKA who should I assign this to?
Updated by shugo (Shugo Maeda) about 9 years ago
- Status changed from Open to Feedback
Matt Dressel wrote:
What exception is raised?
The following code works fine on my box (x86_64-linux):
def test_allow_tls_v1_for_client
# server does not support SSLv2 / SSLv3
ctx_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_version
verify_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.
Updated by zzak (zzak _) about 9 years ago
- Assignee set to 7150
- Priority changed from 5 to Normal
Updated by rhenium (Kazuki Yamaguchi) over 7 years ago
- Status changed from Feedback to Rejected
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
.