[前][次][番号順一覧][スレッド一覧]

ruby-changes:65579

From: Kazuki <ko1@a...>
Date: Tue, 16 Mar 2021 20:39:05 +0900 (JST)
Subject: [ruby-changes:65579] a3f97007bb (master): [ruby/openssl] test: adjust test cases for LibreSSL 3.2.4

https://git.ruby-lang.org/ruby.git/commit/?id=a3f97007bb

From a3f97007bbd1012a4b7662b8166118b81b52527a Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@r...>
Date: Thu, 25 Feb 2021 17:28:23 +0900
Subject: [ruby/openssl] test: adjust test cases for LibreSSL 3.2.4

LibreSSL 3.2.4 made the certificate verification logic back closer to
pre-3.2.2 one, which is more compatible with OpenSSL.

Part of the fixes added by commit a0e98d48c91f ("Enhance TLS 1.3 support
on LibreSSL 3.2/3.3", 2020-12-03) is required for 3.2.2 and 3.2.3 only
(and ~3.3.1, however 3.3 does not have a stable release yet). Since both
releases are security fix, it should be safe to remove those special
treatment from our test suite.

While we are at it, TestSSL#test_ecdh_curves is split into TLS 1.2 and
TLS 1.3 variants for clarity.

https://github.com/ruby/openssl/commit/a9954bac22
---
 test/openssl/test_ssl.rb       | 44 +++++++++++++++++++++++++++---------------
 test/openssl/test_ts.rb        |  2 --
 test/openssl/test_x509store.rb | 37 ++++++++++++++---------------------
 test/openssl/utils.rb          |  8 ++++++++
 4 files changed, 51 insertions(+), 40 deletions(-)

diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 750d64f..50a1602 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -458,11 +458,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L458
       ssl.sync_close = true
       begin
         assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }
-        assert_include(
-          [
-            OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN,
-            OpenSSL::X509::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
-          ], ssl.verify_result)
+        assert_equal(OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN, ssl.verify_result)
       ensure
         ssl.close
       end
@@ -930,7 +926,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L926
         ["keyUsage", "keyEncipherment,digitalSignature", true],
         ["subjectAltName", san],
       ]
- 
+
       ctx.cert = issue_cert(@svr, @svr_key, 4, exts, @ca_cert, @ca_key)
       ctx.key = @svr_key
     }
@@ -1015,7 +1011,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L1011
     start_server(ignore_listener_error: true) { |port|
       ctx = OpenSSL::SSL::SSLContext.new
       ctx.set_params
-      assert_raise_with_message(OpenSSL::SSL::SSLError, /self signed|unable to get local issuer certificate/) {
+      assert_raise_with_message(OpenSSL::SSL::SSLError, /self signed/) {
         server_connect(port, ctx)
       }
     }
@@ -1617,13 +1613,13 @@ end https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L1613
     end
   end
 
-  def test_ecdh_curves
+  def test_ecdh_curves_tls12
     pend "EC is disabled" unless defined?(OpenSSL::PKey::EC)
 
     ctx_proc = -> ctx {
       # Enable both ECDHE (~ TLS 1.2) cipher suites and TLS 1.3
-      ctx.ciphers = "DEFAULT:!kRSA:!kEDH"
-      ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION if libressl?(3, 2, 0)
+      ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
+      ctx.ciphers = "kEECDH"
       ctx.ecdh_curves = "P-384:P-521"
     }
     start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
@@ -1632,13 +1628,9 @@ end https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L1628
 
       server_connect(port, ctx) { |ssl|
         cs = ssl.cipher[0]
-        if /\ATLS/ =~ cs # Is TLS 1.3 is used?
+        assert_match (/\AECDH/), cs
+        if ssl.respond_to?(:tmp_key)
           assert_equal "secp384r1", ssl.tmp_key.group.curve_name
-        else
-          assert_match (/\AECDH/), cs
-          if ssl.respond_to?(:tmp_key)
-            assert_equal "secp384r1", ssl.tmp_key.group.curve_name
-          end
         end
         ssl.puts "abc"; assert_equal "abc\n", ssl.gets
       }
@@ -1662,6 +1654,26 @@ end https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L1654
     end
   end
 
+  def test_ecdh_curves_tls13
+    pend "EC is disabled" unless defined?(OpenSSL::PKey::EC)
+    pend "TLS 1.3 not supported" unless tls13_supported?
+
+    ctx_proc = -> ctx {
+      # Assume TLS 1.3 is enabled and chosen by default
+      ctx.ecdh_curves = "P-384:P-521"
+    }
+    start_server(ctx_proc: ctx_proc, ignore_listener_error: true) do |port|
+      ctx = OpenSSL::SSL::SSLContext.new
+      ctx.ecdh_curves = "P-256:P-384" # disable P-521
+
+      server_connect(port, ctx) { |ssl|
+        assert_equal "TLSv1.3", ssl.ssl_version
+        assert_equal "secp384r1", ssl.tmp_key.group.curve_name
+        ssl.puts "abc"; assert_equal "abc\n", ssl.gets
+      }
+    end
+  end
+
   def test_security_level
     ctx = OpenSSL::SSL::SSLContext.new
     begin
diff --git a/test/openssl/test_ts.rb b/test/openssl/test_ts.rb
index 5c2d43e..8e31a7d 100644
--- a/test/openssl/test_ts.rb
+++ b/test/openssl/test_ts.rb
@@ -387,7 +387,6 @@ _end_of_pem_ https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ts.rb#L387
   end
 
   def test_verify_ee_wrong_root_no_intermediate
-    pend "LibreSSL 3.2.2 Timestamp Issue" if libressl?(3, 2, 2)
     assert_raise(OpenSSL::Timestamp::TimestampError) do
       ts, req = timestamp_ee
       ts.verify(req, intermediate_store)
@@ -395,7 +394,6 @@ _end_of_pem_ https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ts.rb#L394
   end
 
   def test_verify_ee_wrong_root_wrong_intermediate
-    pend "LibreSSL 3.2.2 Timestamp Issue" if libressl?(3, 2, 2)
     assert_raise(OpenSSL::Timestamp::TimestampError) do
       ts, req = timestamp_ee
       ts.verify(req, intermediate_store, [ca_cert])
diff --git a/test/openssl/test_x509store.rb b/test/openssl/test_x509store.rb
index 897f0f8..d6c0e70 100644
--- a/test/openssl/test_x509store.rb
+++ b/test/openssl/test_x509store.rb
@@ -32,17 +32,15 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase https://github.com/ruby/ruby/blob/trunk/test/openssl/test_x509store.rb#L32
     assert_equal true, store.verify(cert1)
     assert_equal true, store.verify(cert2)
 
-    unless libressl?(3, 2, 2)
-      # X509::Store#add_path
-      Dir.mktmpdir do |dir|
-        hash1 = "%08x.%d" % [cert1_subj.hash, 0]
-        File.write(File.join(dir, hash1), cert1.to_pem)
-        store = OpenSSL::X509::Store.new
-        store.add_path(dir)
-
-        assert_equal true, store.verify(cert1)
-        assert_equal false, store.verify(cert2)
-      end
+    # X509::Store#add_path
+    Dir.mktmpdir do |dir|
+      hash1 = "%08x.%d" % [cert1_subj.hash, 0]
+      File.write(File.join(dir, hash1), cert1.to_pem)
+      store = OpenSSL::X509::Store.new
+      store.add_path(dir)
+
+      assert_equal true, store.verify(cert1)
+      assert_equal false, store.verify(cert2)
     end
 
     # OpenSSL < 1.1.1 leaks an error on a duplicate certificate
@@ -77,8 +75,8 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase https://github.com/ruby/ruby/blob/trunk/test/openssl/test_x509store.rb#L75
     # Nothing trusted
     store = OpenSSL::X509::Store.new
     assert_equal(false, store.verify(ee1_cert, [ca2_cert, ca1_cert]))
-    assert_include([OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN, OpenSSL::X509::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY], store.error)
-    assert_match(/self.signed|unable to get local issuer certificate/i, store.error_string)
+    assert_equal(OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN, store.error)
+    assert_match(/self.signed/i, store.error_string)
 
     # CA1 trusted, CA2 missing
     store = OpenSSL::X509::Store.new
@@ -188,7 +186,7 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase https://github.com/ruby/ruby/blob/trunk/test/openssl/test_x509store.rb#L186
     store.purpose = OpenSSL::X509::PURPOSE_CRL_SIGN
     store.add_cert(ca1_cert)
     assert_equal(true, store.verify(ca1_cert))
-    assert_equal(libressl?(3, 2, 2), store.verify(ee1_cert))
+    assert_equal(false, store.verify(ee1_cert))
   end
 
   def test_verify_validity_period
@@ -284,7 +282,7 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase https://github.com/ruby/ruby/blob/trunk/test/openssl/test_x509store.rb#L282
     store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK
     store.add_cert(ca1_cert)
     assert_equal(false, store.verify(ca2_cert))
-    assert_include([OpenSSL::X509::V_ERR_UNABLE_TO_GET_CRL, OpenSSL::X509::V_ERR_UNSPECIFIED], store.error)
+    assert_equal(OpenSSL::X509::V_ERR_UNABLE_TO_GET_CRL, store.error)
 
     # Intermediate CA revoked EE2
     store = OpenSSL::X509::Store.new
@@ -324,14 +322,9 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase https://github.com/ruby/ruby/blob/trunk/test/openssl/test_x509store.rb#L322
     store.add_cert(ca2_cert)
     store.add_crl(ca1_crl1)
     store.add_crl(ca2_crl2) # issued by ca2 but expired
-    if libressl?(3, 2, 2)
-      assert_equal(false, store.verify(ca2_cert))
-      assert_include([OpenSSL::X509::V_ERR_CRL_SIGNATURE_FAILURE, OpenSSL::X509::V_ERR_UNSPECIFIED], store.error)
-    else
-      assert_equal(true, store.verify(ca2_cert))
-    end
+    assert_equal(true, store.verify(ca2_cert))
     assert_equal(false, store.verify(ee1_cert))
-    assert_include([OpenSSL::X509::V_ERR_CRL_HAS_EXPIRED, OpenSSL::X509::V_ERR_UNSPECIFIED], store.error)
+    assert_equal(OpenSSL::X509::V_ERR_CRL_HAS_EXPIRED, store.error)
     assert_equal(false, store.verify(ee2_cert))
   end
 
diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb
index c1d737b..8ee0116 100644
--- a/test/openssl/utils.rb
+++ b/test/openssl/utils.rb
@@ -196,6 +196,14 @@ class OpenSSL::SSLTestCase < OpenSSL::TestCase https://github.com/ruby/ruby/blob/trunk/test/openssl/utils.rb#L196
   rescue
   end
 
+  def tls13_supported?
+    return false unless defined?(OpenSSL::SSL::TLS1_3_VERSION)
+    ctx = OpenSSL::SSL::SSLContext.new
+    ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_3_VERSION
+    true
+  rescue
+  end
+
   def readwrite_loop(ctx, ssl)
     while line = (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]