diff options
author | rhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-05-30 09:30:38 +0000 |
---|---|---|
committer | rhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-05-30 09:30:38 +0000 |
commit | fdd59e1e3915332fd7db35953988350dca4fd958 (patch) | |
tree | 4a798f0604e2c2a87bbd93955cd87ed754c2133f /test/openssl/test_pair.rb | |
parent | 157f4f8bd6be81a0131c372da0e7de31e9fe297d (diff) | |
download | ruby-fdd59e1e3915332fd7db35953988350dca4fd958.tar.gz |
openssl: add SSLContext#ecdh_curves=
* ext/openssl/ossl_ssl.c (ossl_sslctx_s_alloc): Enable the automatic
curve selection for ECDH by calling SSL_CTX_set_ecdh_auto(). With
this a TLS server automatically selects a curve which both the client
and the server support to use in ECDH. This changes the default
behavior but users can still disable ECDH by excluding 'ECDH' cipher
suites from the cipher list (with SSLContext#ciphers=). This commit
also deprecate #tmp_ecdh_callback=. It was added in Ruby 2.3.0. It
wraps SSL_CTX_set_tmp_ecdh_callback() which will be removed in OpenSSL
1.1.0. Its callback receives two values 'is_export' and 'keylength'
but both are completely useless for determining a curve to use in
ECDH. The automatic curve selection was introduced to replace this.
(ossl_sslctx_setup): Deprecate SSLContext#tmp_ecdh_callback=. Emit a
warning if this is in use.
(ossl_sslctx_set_ecdh_curves): Add SSLContext#ecdh_curves=. Wrap
SSL_CTX_set1_curves_list(). If it is not available, this falls back
to SSL_CTX_set_tmp_ecdh().
(Init_ossl_ssl): Define SSLContext#ecdh_curves=.
* ext/openssl/extconf.rb: Check the existence of EC_curve_nist2nid(),
SSL_CTX_set1_curves_list(), SSL_CTX_set_ecdh_auto() and
SSL_CTX_set_tmp_ecdh_callback().
* ext/openssl/openssl_missing.[ch]: Implement EC_curve_nist2nid() if
missing.
* test/openssl/test_pair.rb (test_ecdh_callback): Use
EnvUtil.suppress_warning to suppress deprecated warning.
(test_ecdh_curves): Test that SSLContext#ecdh_curves= works.
* test/openssl/utils.rb (start_server): Use SSLContext#ecdh_curves=.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55214 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/openssl/test_pair.rb')
-rw-r--r-- | test/openssl/test_pair.rb | 87 |
1 files changed, 59 insertions, 28 deletions
diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb index 38b33a4622..d9341ad123 100644 --- a/test/openssl/test_pair.rb +++ b/test/openssl/test_pair.rb @@ -372,41 +372,73 @@ module OpenSSL::TestPairM end def test_ecdh_callback - called = false - ctx2 = OpenSSL::SSL::SSLContext.new - ctx2.ciphers = "ECDH" - ctx2.tmp_ecdh_callback = ->(*args) { - called = true - OpenSSL::PKey::EC.new "prime256v1" - } + return unless OpenSSL::SSL::SSLContext.instance_methods.include?(:tmp_ecdh_callback) + EnvUtil.suppress_warning do # tmp_ecdh_callback is deprecated (2016-05) + begin + called = false + ctx2 = OpenSSL::SSL::SSLContext.new + ctx2.ciphers = "ECDH" + ctx2.tmp_ecdh_callback = ->(*args) { + called = true + OpenSSL::PKey::EC.new "prime256v1" + } + + sock1, sock2 = tcp_pair + + s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2) + ctx1 = OpenSSL::SSL::SSLContext.new + ctx1.ciphers = "ECDH" + + s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1) + th = Thread.new do + begin + rv = s1.connect_nonblock(exception: false) + case rv + when :wait_writable + IO.select(nil, [s1], nil, 5) + when :wait_readable + IO.select([s1], nil, nil, 5) + end + end until rv == s1 + end + + accepted = s2.accept + assert called, 'ecdh callback should be called' + rescue OpenSSL::SSL::SSLError => e + if e.message =~ /no cipher match/ + skip "ECDH cipher not supported." + else + raise e + end + ensure + th.join if th + s1.close if s1 + s2.close if s2 + sock1.close if sock1 + sock2.close if sock2 + end + end + end + def test_ecdh_curves sock1, sock2 = tcp_pair - s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2) ctx1 = OpenSSL::SSL::SSLContext.new ctx1.ciphers = "ECDH" - + ctx1.ecdh_curves = "P-384:P-224" s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1) - th = Thread.new do - begin - rv = s1.connect_nonblock(exception: false) - case rv - when :wait_writable - IO.select(nil, [s1], nil, 5) - when :wait_readable - IO.select([s1], nil, nil, 5) - end - end until rv == s1 - end - accepted = s2.accept + ctx2 = OpenSSL::SSL::SSLContext.new + ctx2.ciphers = "ECDH" + ctx2.ecdh_curves = "P-256:P-384" + s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2) - assert called, 'ecdh callback should be called' - rescue OpenSSL::SSL::SSLError => e - if e.message =~ /no cipher match/ - skip "ECDH cipher not supported." - else - raise e + th = Thread.new { s1.accept } + s2.connect + + assert s2.cipher[0].start_with?("AECDH"), "AECDH should be used" + if s2.respond_to?(:tmp_key) + assert_equal "secp384r1", s2.tmp_key.group.curve_name end ensure th.join if th @@ -414,7 +446,6 @@ module OpenSSL::TestPairM s2.close if s2 sock1.close if sock1 sock2.close if sock2 - accepted.close if accepted.respond_to?(:close) end def test_connect_accept_nonblock_no_exception |