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