6daba0
From 91d04f991f8b9910efea7bbe5aecb0fea2bbd5fa Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Sun, 24 Oct 2021 17:50:18 +0900
6daba0
Subject: [PATCH 1/8] cipher: update test_ciphers
6daba0
6daba0
Do not attempt to actually use all algorithms. Not all algorithms listed
6daba0
in OpenSSL::Cipher.ciphers are always available.
6daba0
---
6daba0
 test/openssl/test_cipher.rb | 13 +++++--------
6daba0
 1 file changed, 5 insertions(+), 8 deletions(-)
6daba0
6daba0
diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb
6daba0
index 6d18c0c8..b5fdf0b3 100644
6daba0
--- a/test/openssl/test_cipher.rb
6daba0
+++ b/test/openssl/test_cipher.rb
6daba0
@@ -135,14 +135,11 @@ def test_ctr_if_exists
6daba0
   end
6daba0
 
6daba0
   def test_ciphers
6daba0
-    OpenSSL::Cipher.ciphers.each{|name|
6daba0
-      next if /netbsd/ =~ RUBY_PLATFORM && /idea|rc5/i =~ name
6daba0
-      begin
6daba0
-        assert_kind_of(OpenSSL::Cipher, OpenSSL::Cipher.new(name))
6daba0
-      rescue OpenSSL::Cipher::CipherError => e
6daba0
-        raise unless /wrap/ =~ name and /wrap mode not allowed/ =~ e.message
6daba0
-      end
6daba0
-    }
6daba0
+    ciphers = OpenSSL::Cipher.ciphers
6daba0
+    assert_kind_of Array, ciphers
6daba0
+    assert_include ciphers, "aes-128-cbc"
6daba0
+    assert_include ciphers, "aes128" # alias of aes-128-cbc
6daba0
+    assert_include ciphers, "aes-128-gcm"
6daba0
   end
6daba0
 
6daba0
   def test_AES
6daba0
6daba0
From 6a60c7b2e7b6afe8b8c98d864ef2740094d86e1d Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Sat, 11 Dec 2021 16:27:42 +0900
6daba0
Subject: [PATCH 2/8] hmac: fix wrong usage of EVP_DigestSignFinal()
6daba0
6daba0
According to the manpage, the "siglen" parameter must be initialized
6daba0
beforehand.
6daba0
---
6daba0
 ext/openssl/ossl_hmac.c | 4 ++--
6daba0
 1 file changed, 2 insertions(+), 2 deletions(-)
6daba0
6daba0
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c
6daba0
index f89ff2f9..bfe3a74b 100644
6daba0
--- a/ext/openssl/ossl_hmac.c
6daba0
+++ b/ext/openssl/ossl_hmac.c
6daba0
@@ -175,7 +175,7 @@ static VALUE
6daba0
 ossl_hmac_digest(VALUE self)
6daba0
 {
6daba0
     EVP_MD_CTX *ctx;
6daba0
-    size_t buf_len;
6daba0
+    size_t buf_len = EVP_MAX_MD_SIZE;
6daba0
     VALUE ret;
6daba0
 
6daba0
     GetHMAC(self, ctx);
6daba0
@@ -200,7 +200,7 @@ ossl_hmac_hexdigest(VALUE self)
6daba0
 {
6daba0
     EVP_MD_CTX *ctx;
6daba0
     unsigned char buf[EVP_MAX_MD_SIZE];
6daba0
-    size_t buf_len;
6daba0
+    size_t buf_len = EVP_MAX_MD_SIZE;
6daba0
     VALUE ret;
6daba0
 
6daba0
     GetHMAC(self, ctx);
6daba0
6daba0
From 46995816392a79d037df5550b2fb226652c06f42 Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Sat, 11 Dec 2021 16:30:30 +0900
6daba0
Subject: [PATCH 3/8] hmac: skip test_dup on OpenSSL 3.0 for now
6daba0
6daba0
EVP_MD_CTX_copy() doesn't seem to work as intended on HMAC EVP_MD_CTX
6daba0
on OpenSSL 3.0.0 and causes a double free. I haven't found the root
6daba0
problem yet, but let's skip the test case for now.
6daba0
---
6daba0
 test/openssl/test_hmac.rb | 1 +
6daba0
 1 file changed, 1 insertion(+)
6daba0
6daba0
diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb
6daba0
index 2f53a813..47cb3718 100644
6daba0
--- a/test/openssl/test_hmac.rb
6daba0
+++ b/test/openssl/test_hmac.rb
6daba0
@@ -19,6 +19,7 @@ def test_hmac
6daba0
   end
6daba0
 
6daba0
   def test_dup
6daba0
+    pend "HMAC#initialize_copy is currently broken on OpenSSL 3.0.0" if openssl?(3, 0, 0)
6daba0
     h1 = OpenSSL::HMAC.new("KEY", "MD5")
6daba0
     h1.update("DATA")
6daba0
     h = h1.dup
6daba0
6daba0
From 69a27d8de4bd291cb4eb21a4d715b197e7da5a06 Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Thu, 15 Apr 2021 00:51:58 +0900
6daba0
Subject: [PATCH 4/8] engine: disable OpenSSL::Engine on OpenSSL 3.0
6daba0
6daba0
The entire ENGINE API is deprecated in OpenSSL 3.0 in favor of the new
6daba0
"Provider" concept.
6daba0
6daba0
OpenSSL::Engine will not be defined when compiled with OpenSSL 3.0.
6daba0
We would need a way to interact with providers from Ruby programs, but
6daba0
since the concept is completely different from the ENGINE API, it will
6daba0
not be through the current OpenSSL::Engine interface.
6daba0
---
6daba0
 ext/openssl/openssl_missing.c | 3 ---
6daba0
 ext/openssl/ossl.h            | 8 +++++---
6daba0
 ext/openssl/ossl_engine.c     | 3 ++-
6daba0
 ext/openssl/ossl_pkey.c       | 4 ++++
6daba0
 4 files changed, 11 insertions(+), 7 deletions(-)
6daba0
6daba0
diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c
6daba0
index 8b93cba6..4415703d 100644
6daba0
--- a/ext/openssl/openssl_missing.c
6daba0
+++ b/ext/openssl/openssl_missing.c
6daba0
@@ -10,9 +10,6 @@
6daba0
 #include RUBY_EXTCONF_H
6daba0
 
6daba0
 #include <string.h> /* memcpy() */
6daba0
-#if !defined(OPENSSL_NO_ENGINE)
6daba0
-# include <openssl/engine.h>
6daba0
-#endif
6daba0
 #include <openssl/x509_vfy.h>
6daba0
 
6daba0
 #include "openssl_missing.h"
6daba0
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h
6daba0
index 3a0ab1e5..4b512689 100644
6daba0
--- a/ext/openssl/ossl.h
6daba0
+++ b/ext/openssl/ossl.h
6daba0
@@ -18,6 +18,7 @@
6daba0
 #include <ruby/io.h>
6daba0
 #include <ruby/thread.h>
6daba0
 #include <openssl/opensslv.h>
6daba0
+
6daba0
 #include <openssl/err.h>
6daba0
 #include <openssl/asn1.h>
6daba0
 #include <openssl/x509v3.h>
6daba0
@@ -30,9 +31,6 @@
6daba0
   #include <openssl/ts.h>
6daba0
 #endif
6daba0
 #include <openssl/crypto.h>
6daba0
-#if !defined(OPENSSL_NO_ENGINE)
6daba0
-#  include <openssl/engine.h>
6daba0
-#endif
6daba0
 #if !defined(OPENSSL_NO_OCSP)
6daba0
 #  include <openssl/ocsp.h>
6daba0
 #endif
6daba0
@@ -54,6 +52,10 @@
6daba0
       (LIBRESSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12))
6daba0
 #endif
6daba0
 
6daba0
+#if !defined(OPENSSL_NO_ENGINE) && !OSSL_OPENSSL_PREREQ(3, 0, 0)
6daba0
+# define OSSL_USE_ENGINE
6daba0
+#endif
6daba0
+
6daba0
 /*
6daba0
  * Common Module
6daba0
  */
6daba0
diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c
6daba0
index 661a1368..1abde7f7 100644
6daba0
--- a/ext/openssl/ossl_engine.c
6daba0
+++ b/ext/openssl/ossl_engine.c
6daba0
@@ -9,7 +9,8 @@
6daba0
  */
6daba0
 #include "ossl.h"
6daba0
 
6daba0
-#if !defined(OPENSSL_NO_ENGINE)
6daba0
+#ifdef OSSL_USE_ENGINE
6daba0
+# include <openssl/engine.h>
6daba0
 
6daba0
 #define NewEngine(klass) \
6daba0
     TypedData_Wrap_Struct((klass), &ossl_engine_type, 0)
6daba0
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
6daba0
index 7030be3c..94760d32 100644
6daba0
--- a/ext/openssl/ossl_pkey.c
6daba0
+++ b/ext/openssl/ossl_pkey.c
6daba0
@@ -9,6 +9,10 @@
6daba0
  */
6daba0
 #include "ossl.h"
6daba0
 
6daba0
+#ifdef OSSL_USE_ENGINE
6daba0
+# include <openssl/engine.h>
6daba0
+#endif
6daba0
+
6daba0
 /*
6daba0
  * Classes
6daba0
  */
6daba0
6daba0
From b1ee2f23b28c2d0b14fd9b4b9fef13e870370746 Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Wed, 17 Nov 2021 11:39:06 +0900
6daba0
Subject: [PATCH 5/8] ssl: add constants for new SSL_OP_* flags
6daba0
6daba0
Add all SSL_OP_* constants defined in OpenSSL 3.0.0 which are not
6daba0
specific to DTLS.
6daba0
---
6daba0
 ext/openssl/ossl_ssl.c | 35 +++++++++++++++++++++++++++++------
6daba0
 1 file changed, 29 insertions(+), 6 deletions(-)
6daba0
6daba0
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
6daba0
index 3b425ca7..9a0682a7 100644
6daba0
--- a/ext/openssl/ossl_ssl.c
6daba0
+++ b/ext/openssl/ossl_ssl.c
6daba0
@@ -2941,13 +2941,28 @@ Init_ossl_ssl(void)
6daba0
     rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE));
6daba0
 
6daba0
     rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL));
6daba0
+#ifdef SSL_OP_CLEANSE_PLAINTEXT /* OpenSSL 3.0 */
6daba0
+    rb_define_const(mSSL, "OP_CLEANSE_PLAINTEXT", ULONG2NUM(SSL_OP_CLEANSE_PLAINTEXT));
6daba0
+#endif
6daba0
     rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT));
6daba0
+#ifdef SSL_OP_ENABLE_KTLS /* OpenSSL 3.0 */
6daba0
+    rb_define_const(mSSL, "OP_ENABLE_KTLS", ULONG2NUM(SSL_OP_ENABLE_KTLS));
6daba0
+#endif
6daba0
 #ifdef SSL_OP_TLSEXT_PADDING /* OpenSSL 1.0.1h and OpenSSL 1.0.2 */
6daba0
     rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING));
6daba0
 #endif
6daba0
 #ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG /* OpenSSL 1.0.1f and OpenSSL 1.0.2 */
6daba0
     rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG));
6daba0
 #endif
6daba0
+#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF /* OpenSSL 3.0 */
6daba0
+    rb_define_const(mSSL, "OP_IGNORE_UNEXPECTED_EOF", ULONG2NUM(SSL_OP_IGNORE_UNEXPECTED_EOF));
6daba0
+#endif
6daba0
+#ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION /* OpenSSL 3.0 */
6daba0
+    rb_define_const(mSSL, "OP_ALLOW_CLIENT_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_CLIENT_RENEGOTIATION));
6daba0
+#endif
6daba0
+#ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */
6daba0
+    rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES));
6daba0
+#endif
6daba0
 #ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */
6daba0
     rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX));
6daba0
 #endif
6daba0
@@ -2959,13 +2974,15 @@ Init_ossl_ssl(void)
6daba0
 #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */
6daba0
     rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC));
6daba0
 #endif
6daba0
-    rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
6daba0
-    rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
6daba0
-#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
6daba0
-    rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
6daba0
+#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1 */
6daba0
+    rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT));
6daba0
+#endif
6daba0
+#ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1 */
6daba0
+    rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA));
6daba0
+#endif
6daba0
+#ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1 */
6daba0
+    rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY));
6daba0
 #endif
6daba0
-    rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
6daba0
-
6daba0
     rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3));
6daba0
     rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1));
6daba0
     rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1));
6daba0
@@ -2973,6 +2990,12 @@ Init_ossl_ssl(void)
6daba0
 #ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */
6daba0
     rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3));
6daba0
 #endif
6daba0
+    rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE));
6daba0
+    rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG));
6daba0
+#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */
6daba0
+    rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION));
6daba0
+#endif
6daba0
+    rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG));
6daba0
 
6daba0
     /* SSL_OP_* flags for DTLS */
6daba0
 #if 0
6daba0
6daba0
From e168df0f3570709bfb38e9a39838bd0a7e78164c Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Sun, 12 Dec 2021 00:47:35 +0900
6daba0
Subject: [PATCH 6/8] ssl: update test_options_disable_versions
6daba0
6daba0
Use the combination of TLS 1.2 and TLS 1.3 instead of TLS 1.1 and TLS
6daba0
1.2 so that will the test case will be run on latest platforms.
6daba0
---
6daba0
 test/openssl/test_ssl.rb | 75 +++++++++++++++++++++-------------------
6daba0
 1 file changed, 40 insertions(+), 35 deletions(-)
6daba0
6daba0
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
6daba0
index 22691292..2abade06 100644
6daba0
--- a/test/openssl/test_ssl.rb
6daba0
+++ b/test/openssl/test_ssl.rb
6daba0
@@ -1180,46 +1180,51 @@ def test_minmax_version
6daba0
   end
6daba0
 
6daba0
   def test_options_disable_versions
6daba0
-    # Note: Use of these OP_* flags has been deprecated since OpenSSL 1.1.0.
6daba0
+    # It's recommended to use SSLContext#{min,max}_version= instead in real
6daba0
+    # applications. The purpose of this test case is to check that SSL options
6daba0
+    # are properly propagated to OpenSSL library.
6daba0
     supported = check_supported_protocol_versions
6daba0
+    if !defined?(OpenSSL::SSL::TLS1_3_VERSION) ||
6daba0
+        !supported.include?(OpenSSL::SSL::TLS1_2_VERSION) ||
6daba0
+        !supported.include?(OpenSSL::SSL::TLS1_3_VERSION) ||
6daba0
+        !defined?(OpenSSL::SSL::OP_NO_TLSv1_3) # LibreSSL < 3.4
6daba0
+      pend "this test case requires both TLS 1.2 and TLS 1.3 to be supported " \
6daba0
+        "and enabled by default"
6daba0
+    end
6daba0
 
6daba0
-    if supported.include?(OpenSSL::SSL::TLS1_1_VERSION) &&
6daba0
-        supported.include?(OpenSSL::SSL::TLS1_2_VERSION)
6daba0
-      # Server disables ~ TLS 1.1
6daba0
-      ctx_proc = proc { |ctx|
6daba0
-        ctx.options |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 |
6daba0
-          OpenSSL::SSL::OP_NO_TLSv1 | OpenSSL::SSL::OP_NO_TLSv1_1
6daba0
-      }
6daba0
-      start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
6daba0
-        # Client only supports TLS 1.1
6daba0
-        ctx1 = OpenSSL::SSL::SSLContext.new
6daba0
-        ctx1.min_version = ctx1.max_version = OpenSSL::SSL::TLS1_1_VERSION
6daba0
-        assert_handshake_error { server_connect(port, ctx1) { } }
6daba0
+    # Server disables TLS 1.2 and earlier
6daba0
+    ctx_proc = proc { |ctx|
6daba0
+      ctx.options |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3 |
6daba0
+        OpenSSL::SSL::OP_NO_TLSv1 | OpenSSL::SSL::OP_NO_TLSv1_1 |
6daba0
+        OpenSSL::SSL::OP_NO_TLSv1_2
6daba0
+    }
6daba0
+    start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
6daba0
+      # Client only supports TLS 1.2
6daba0
+      ctx1 = OpenSSL::SSL::SSLContext.new
6daba0
+      ctx1.min_version = ctx1.max_version = OpenSSL::SSL::TLS1_2_VERSION
6daba0
+      assert_handshake_error { server_connect(port, ctx1) { } }
6daba0
 
6daba0
-        # Client only supports TLS 1.2
6daba0
-        ctx2 = OpenSSL::SSL::SSLContext.new
6daba0
-        ctx2.min_version = ctx2.max_version = OpenSSL::SSL::TLS1_2_VERSION
6daba0
-        assert_nothing_raised { server_connect(port, ctx2) { } }
6daba0
-      }
6daba0
+      # Client only supports TLS 1.3
6daba0
+      ctx2 = OpenSSL::SSL::SSLContext.new
6daba0
+      ctx2.min_version = ctx2.max_version = OpenSSL::SSL::TLS1_3_VERSION
6daba0
+      assert_nothing_raised { server_connect(port, ctx2) { } }
6daba0
+    }
6daba0
 
6daba0
-      # Server only supports TLS 1.1
6daba0
-      ctx_proc = proc { |ctx|
6daba0
-        ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_1_VERSION
6daba0
-      }
6daba0
-      start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
6daba0
-        # Client disables TLS 1.1
6daba0
-        ctx1 = OpenSSL::SSL::SSLContext.new
6daba0
-        ctx1.options |= OpenSSL::SSL::OP_NO_TLSv1_1
6daba0
-        assert_handshake_error { server_connect(port, ctx1) { } }
6daba0
+    # Server only supports TLS 1.2
6daba0
+    ctx_proc = proc { |ctx|
6daba0
+      ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
6daba0
+    }
6daba0
+    start_server(ctx_proc: ctx_proc, ignore_listener_error: true) { |port|
6daba0
+      # Client doesn't support TLS 1.2
6daba0
+      ctx1 = OpenSSL::SSL::SSLContext.new
6daba0
+      ctx1.options |= OpenSSL::SSL::OP_NO_TLSv1_2
6daba0
+      assert_handshake_error { server_connect(port, ctx1) { } }
6daba0
 
6daba0
-        # Client disables TLS 1.2
6daba0
-        ctx2 = OpenSSL::SSL::SSLContext.new
6daba0
-        ctx2.options |= OpenSSL::SSL::OP_NO_TLSv1_2
6daba0
-        assert_nothing_raised { server_connect(port, ctx2) { } }
6daba0
-      }
6daba0
-    else
6daba0
-      pend "TLS 1.1 and TLS 1.2 must be supported; skipping"
6daba0
-    end
6daba0
+      # Client supports TLS 1.2 by default
6daba0
+      ctx2 = OpenSSL::SSL::SSLContext.new
6daba0
+      ctx2.options |= OpenSSL::SSL::OP_NO_TLSv1_3
6daba0
+      assert_nothing_raised { server_connect(port, ctx2) { } }
6daba0
+    }
6daba0
   end
6daba0
 
6daba0
   def test_ssl_methods_constant
6daba0
6daba0
From ccdb6f7bfa5f988a07beecedbf2b6205b6ab8492 Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Sat, 20 Mar 2021 23:16:41 +0900
6daba0
Subject: [PATCH 7/8] pkey: assume a pkey always has public key components on
6daba0
 OpenSSL 3.0
6daba0
6daba0
OpenSSL 3.0's EVP_PKEY_get0() returns NULL for provider-backed pkeys.
6daba0
This causes segfault because it was supposed to never return NULL
6daba0
before.
6daba0
6daba0
We can't check the existence of public key components in this way on
6daba0
OpenSSL 3.0. Let's just skip it for now.
6daba0
---
6daba0
 ext/openssl/ossl_pkey.c | 11 +++++++++++
6daba0
 1 file changed, 11 insertions(+)
6daba0
6daba0
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
6daba0
index 94760d32..09d45d85 100644
6daba0
--- a/ext/openssl/ossl_pkey.c
6daba0
+++ b/ext/openssl/ossl_pkey.c
6daba0
@@ -428,9 +428,19 @@ ossl_pkey_s_generate_key(int argc, VALUE *argv, VALUE self)
6daba0
     return pkey_generate(argc, argv, self, 0);
6daba0
 }
6daba0
 
6daba0
+/*
6daba0
+ * TODO: There is no convenient way to check the presence of public key
6daba0
+ * components on OpenSSL 3.0. But since keys are immutable on 3.0, pkeys without
6daba0
+ * these should only be created by OpenSSL::PKey.generate_parameters or by
6daba0
+ * parsing DER-/PEM-encoded string. We would need another flag for that.
6daba0
+ */
6daba0
 void
6daba0
 ossl_pkey_check_public_key(const EVP_PKEY *pkey)
6daba0
 {
6daba0
+#if OSSL_OPENSSL_PREREQ(3, 0, 0)
6daba0
+    if (EVP_PKEY_missing_parameters(pkey))
6daba0
+        ossl_raise(ePKeyError, "parameters missing");
6daba0
+#else
6daba0
     void *ptr;
6daba0
     const BIGNUM *n, *e, *pubkey;
6daba0
 
6daba0
@@ -466,6 +476,7 @@ ossl_pkey_check_public_key(const EVP_PKEY *pkey)
6daba0
 	return;
6daba0
     }
6daba0
     ossl_raise(ePKeyError, "public key missing");
6daba0
+#endif
6daba0
 }
6daba0
 
6daba0
 EVP_PKEY *
6daba0
6daba0
From d6535d13d174cd87ae99f3e60e97f7a00e1474e5 Mon Sep 17 00:00:00 2001
6daba0
From: Kazuki Yamaguchi <k@rhe.jp>
6daba0
Date: Mon, 12 Apr 2021 10:43:46 +0900
6daba0
Subject: [PATCH 8/8] pkey: use EVP_PKEY_CTX_new_from_name() on OpenSSL 3.0
6daba0
6daba0
Replace EVP_PKEY_CTX_new_id() with the new EVP_PKEY_CTX_new_from_name()
6daba0
which takes the algorithm name in a string instead of in an NID.
6daba0
---
6daba0
 ext/openssl/ossl_pkey.c | 6 ++++++
6daba0
 1 file changed, 6 insertions(+)
6daba0
6daba0
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
6daba0
index 09d45d85..2a4835a2 100644
6daba0
--- a/ext/openssl/ossl_pkey.c
6daba0
+++ b/ext/openssl/ossl_pkey.c
6daba0
@@ -315,6 +315,11 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam)
6daba0
             ossl_raise(ePKeyError, "EVP_PKEY_CTX_new");
6daba0
     }
6daba0
     else {
6daba0
+#if OSSL_OPENSSL_PREREQ(3, 0, 0)
6daba0
+        ctx = EVP_PKEY_CTX_new_from_name(NULL, StringValueCStr(alg), NULL);
6daba0
+        if (!ctx)
6daba0
+            ossl_raise(ePKeyError, "EVP_PKEY_CTX_new_from_name");
6daba0
+#else
6daba0
         const EVP_PKEY_ASN1_METHOD *ameth;
6daba0
         ENGINE *tmpeng;
6daba0
         int pkey_id;
6daba0
@@ -333,6 +338,7 @@ pkey_generate(int argc, VALUE *argv, VALUE self, int genparam)
6daba0
         ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL/* engine */);
6daba0
         if (!ctx)
6daba0
             ossl_raise(ePKeyError, "EVP_PKEY_CTX_new_id");
6daba0
+#endif
6daba0
     }
6daba0
 
6daba0
     if (genparam && EVP_PKEY_paramgen_init(ctx) <= 0) {