Update OpenSSL 3 compatibility patches.
This replaces the parts of the original 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.
This commit is contained in:
parent
a0bcb33eaa
commit
2da7a540e7
630
ruby-3.1.0-Allocate-EVP_PKEY-on-initialize.patch
Normal file
630
ruby-3.1.0-Allocate-EVP_PKEY-on-initialize.patch
Normal file
@ -0,0 +1,630 @@
|
||||
From 316cb2a41f154e4663d7e7fead60cfc0bfa86af9 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Mon, 12 Apr 2021 13:55:10 +0900
|
||||
Subject: [PATCH 1/2] pkey: do not check NULL argument in ossl_pkey_new()
|
||||
|
||||
Passing NULL to ossl_pkey_new() makes no sense in the first place, and
|
||||
in fact it is ensured not to be NULL in all cases.
|
||||
---
|
||||
ext/openssl/ossl_pkey.c | 6 +-----
|
||||
ext/openssl/ossl_pkey.h | 1 +
|
||||
2 files changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
|
||||
index f9f5162e..820e4a2c 100644
|
||||
--- a/ext/openssl/ossl_pkey.c
|
||||
+++ b/ext/openssl/ossl_pkey.c
|
||||
@@ -38,12 +38,8 @@ static VALUE
|
||||
pkey_new0(EVP_PKEY *pkey)
|
||||
{
|
||||
VALUE klass, obj;
|
||||
- int type;
|
||||
|
||||
- if (!pkey || (type = EVP_PKEY_base_id(pkey)) == EVP_PKEY_NONE)
|
||||
- ossl_raise(rb_eRuntimeError, "pkey is empty");
|
||||
-
|
||||
- switch (type) {
|
||||
+ switch (EVP_PKEY_base_id(pkey)) {
|
||||
#if !defined(OPENSSL_NO_RSA)
|
||||
case EVP_PKEY_RSA: klass = cRSA; break;
|
||||
#endif
|
||||
diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h
|
||||
index 4beede22..f0476780 100644
|
||||
--- a/ext/openssl/ossl_pkey.h
|
||||
+++ b/ext/openssl/ossl_pkey.h
|
||||
@@ -35,6 +35,7 @@ extern const rb_data_type_t ossl_evp_pkey_type;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
+/* Takes ownership of the EVP_PKEY */
|
||||
VALUE ossl_pkey_new(EVP_PKEY *);
|
||||
void ossl_pkey_check_public_key(const EVP_PKEY *);
|
||||
EVP_PKEY *ossl_pkey_read_generic(BIO *, VALUE);
|
||||
|
||||
From 74f6c6175688502a5bf27ae35367616858630c0f Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Mon, 12 Apr 2021 18:32:40 +0900
|
||||
Subject: [PATCH 2/2] pkey: allocate EVP_PKEY on #initialize
|
||||
|
||||
Allocate an EVP_PKEY when the content is ready: when #initialize
|
||||
or #initialize_copy is called, rather than when a T_DATA is allocated.
|
||||
This is more natural because the lower level API has been deprecated
|
||||
and an EVP_PKEY is becoming the minimum unit of handling keys.
|
||||
---
|
||||
ext/openssl/ossl_pkey.c | 15 ++----
|
||||
ext/openssl/ossl_pkey.h | 15 ++----
|
||||
ext/openssl/ossl_pkey_dh.c | 71 +++++++++++++++++++--------
|
||||
ext/openssl/ossl_pkey_dsa.c | 93 ++++++++++++++++++++---------------
|
||||
ext/openssl/ossl_pkey_ec.c | 91 +++++++++++++++++++----------------
|
||||
ext/openssl/ossl_pkey_rsa.c | 96 ++++++++++++++++++++++---------------
|
||||
6 files changed, 218 insertions(+), 163 deletions(-)
|
||||
|
||||
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
|
||||
index 820e4a2c..ea75d63f 100644
|
||||
--- a/ext/openssl/ossl_pkey.c
|
||||
+++ b/ext/openssl/ossl_pkey.c
|
||||
@@ -54,8 +54,8 @@ pkey_new0(EVP_PKEY *pkey)
|
||||
#endif
|
||||
default: klass = cPKey; break;
|
||||
}
|
||||
- obj = NewPKey(klass);
|
||||
- SetPKey(obj, pkey);
|
||||
+ obj = rb_obj_alloc(klass);
|
||||
+ RTYPEDDATA_DATA(obj) = pkey;
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -511,16 +511,7 @@ DupPKeyPtr(VALUE obj)
|
||||
static VALUE
|
||||
ossl_pkey_alloc(VALUE klass)
|
||||
{
|
||||
- EVP_PKEY *pkey;
|
||||
- VALUE obj;
|
||||
-
|
||||
- obj = NewPKey(klass);
|
||||
- if (!(pkey = EVP_PKEY_new())) {
|
||||
- ossl_raise(ePKeyError, NULL);
|
||||
- }
|
||||
- SetPKey(obj, pkey);
|
||||
-
|
||||
- return obj;
|
||||
+ return TypedData_Wrap_Struct(klass, &ossl_evp_pkey_type, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h
|
||||
index f0476780..ed18bc69 100644
|
||||
--- a/ext/openssl/ossl_pkey.h
|
||||
+++ b/ext/openssl/ossl_pkey.h
|
||||
@@ -15,19 +15,10 @@ extern VALUE cPKey;
|
||||
extern VALUE ePKeyError;
|
||||
extern const rb_data_type_t ossl_evp_pkey_type;
|
||||
|
||||
-#define OSSL_PKEY_SET_PRIVATE(obj) rb_iv_set((obj), "private", Qtrue)
|
||||
-#define OSSL_PKEY_SET_PUBLIC(obj) rb_iv_set((obj), "private", Qfalse)
|
||||
-#define OSSL_PKEY_IS_PRIVATE(obj) (rb_iv_get((obj), "private") == Qtrue)
|
||||
+/* For ENGINE */
|
||||
+#define OSSL_PKEY_SET_PRIVATE(obj) rb_ivar_set((obj), rb_intern("private"), Qtrue)
|
||||
+#define OSSL_PKEY_IS_PRIVATE(obj) (rb_attr_get((obj), rb_intern("private")) == Qtrue)
|
||||
|
||||
-#define NewPKey(klass) \
|
||||
- TypedData_Wrap_Struct((klass), &ossl_evp_pkey_type, 0)
|
||||
-#define SetPKey(obj, pkey) do { \
|
||||
- if (!(pkey)) { \
|
||||
- rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!"); \
|
||||
- } \
|
||||
- RTYPEDDATA_DATA(obj) = (pkey); \
|
||||
- OSSL_PKEY_SET_PUBLIC(obj); \
|
||||
-} while (0)
|
||||
#define GetPKey(obj, pkey) do {\
|
||||
TypedData_Get_Struct((obj), EVP_PKEY, &ossl_evp_pkey_type, (pkey)); \
|
||||
if (!(pkey)) { \
|
||||
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
|
||||
index ca782bbe..04c11b21 100644
|
||||
--- a/ext/openssl/ossl_pkey_dh.c
|
||||
+++ b/ext/openssl/ossl_pkey_dh.c
|
||||
@@ -72,34 +72,57 @@ static VALUE
|
||||
ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
+ int type;
|
||||
DH *dh;
|
||||
- BIO *in;
|
||||
+ BIO *in = NULL;
|
||||
VALUE arg;
|
||||
|
||||
- GetPKey(self, pkey);
|
||||
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||
+ if (pkey)
|
||||
+ rb_raise(rb_eTypeError, "pkey already initialized");
|
||||
+
|
||||
/* The DH.new(size, generator) form is handled by lib/openssl/pkey.rb */
|
||||
if (rb_scan_args(argc, argv, "01", &arg) == 0) {
|
||||
dh = DH_new();
|
||||
if (!dh)
|
||||
ossl_raise(eDHError, "DH_new");
|
||||
+ goto legacy;
|
||||
}
|
||||
- else {
|
||||
- arg = ossl_to_der_if_possible(arg);
|
||||
- in = ossl_obj2bio(&arg);
|
||||
- dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
|
||||
- if (!dh){
|
||||
- OSSL_BIO_reset(in);
|
||||
- dh = d2i_DHparams_bio(in, NULL);
|
||||
- }
|
||||
- BIO_free(in);
|
||||
- if (!dh) {
|
||||
- ossl_raise(eDHError, NULL);
|
||||
- }
|
||||
+
|
||||
+ arg = ossl_to_der_if_possible(arg);
|
||||
+ in = ossl_obj2bio(&arg);
|
||||
+
|
||||
+ /*
|
||||
+ * On OpenSSL <= 1.1.1 and current versions of LibreSSL, the generic
|
||||
+ * routine does not support DER-encoded parameters
|
||||
+ */
|
||||
+ dh = d2i_DHparams_bio(in, NULL);
|
||||
+ if (dh)
|
||||
+ goto legacy;
|
||||
+ OSSL_BIO_reset(in);
|
||||
+
|
||||
+ pkey = ossl_pkey_read_generic(in, Qnil);
|
||||
+ BIO_free(in);
|
||||
+ if (!pkey)
|
||||
+ ossl_raise(eDHError, "could not parse pkey");
|
||||
+
|
||||
+ type = EVP_PKEY_base_id(pkey);
|
||||
+ if (type != EVP_PKEY_DH) {
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ rb_raise(eDHError, "incorrect pkey type: %s", OBJ_nid2sn(type));
|
||||
}
|
||||
- if (!EVP_PKEY_assign_DH(pkey, dh)) {
|
||||
- DH_free(dh);
|
||||
- ossl_raise(eDHError, NULL);
|
||||
+ RTYPEDDATA_DATA(self) = pkey;
|
||||
+ return self;
|
||||
+
|
||||
+ legacy:
|
||||
+ BIO_free(in);
|
||||
+ pkey = EVP_PKEY_new();
|
||||
+ if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) {
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ DH_free(dh);
|
||||
+ ossl_raise(eDHError, "EVP_PKEY_assign_DH");
|
||||
}
|
||||
+ RTYPEDDATA_DATA(self) = pkey;
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -110,15 +133,14 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
|
||||
DH *dh, *dh_other;
|
||||
const BIGNUM *pub, *priv;
|
||||
|
||||
- GetPKey(self, pkey);
|
||||
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
|
||||
- ossl_raise(eDHError, "DH already initialized");
|
||||
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||
+ if (pkey)
|
||||
+ rb_raise(rb_eTypeError, "pkey already initialized");
|
||||
GetDH(other, dh_other);
|
||||
|
||||
dh = DHparams_dup(dh_other);
|
||||
if (!dh)
|
||||
ossl_raise(eDHError, "DHparams_dup");
|
||||
- EVP_PKEY_assign_DH(pkey, dh);
|
||||
|
||||
DH_get0_key(dh_other, &pub, &priv);
|
||||
if (pub) {
|
||||
@@ -133,6 +155,13 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
|
||||
DH_set0_key(dh, pub2, priv2);
|
||||
}
|
||||
|
||||
+ pkey = EVP_PKEY_new();
|
||||
+ if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) {
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ DH_free(dh);
|
||||
+ ossl_raise(eDHError, "EVP_PKEY_assign_DH");
|
||||
+ }
|
||||
+ RTYPEDDATA_DATA(self) = pkey;
|
||||
return self;
|
||||
}
|
||||
|
||||
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
|
||||
index 7af00eeb..15724548 100644
|
||||
--- a/ext/openssl/ossl_pkey_dsa.c
|
||||
+++ b/ext/openssl/ossl_pkey_dsa.c
|
||||
@@ -83,50 +83,59 @@ VALUE eDSAError;
|
||||
static VALUE
|
||||
ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
- EVP_PKEY *pkey, *tmp;
|
||||
- DSA *dsa = NULL;
|
||||
- BIO *in;
|
||||
+ EVP_PKEY *pkey;
|
||||
+ DSA *dsa;
|
||||
+ BIO *in = NULL;
|
||||
VALUE arg, pass;
|
||||
+ int type;
|
||||
+
|
||||
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||
+ if (pkey)
|
||||
+ rb_raise(rb_eTypeError, "pkey already initialized");
|
||||
|
||||
- GetPKey(self, pkey);
|
||||
/* The DSA.new(size, generator) form is handled by lib/openssl/pkey.rb */
|
||||
rb_scan_args(argc, argv, "02", &arg, &pass);
|
||||
if (argc == 0) {
|
||||
dsa = DSA_new();
|
||||
if (!dsa)
|
||||
ossl_raise(eDSAError, "DSA_new");
|
||||
+ goto legacy;
|
||||
}
|
||||
- else {
|
||||
- pass = ossl_pem_passwd_value(pass);
|
||||
- arg = ossl_to_der_if_possible(arg);
|
||||
- in = ossl_obj2bio(&arg);
|
||||
-
|
||||
- tmp = ossl_pkey_read_generic(in, pass);
|
||||
- if (tmp) {
|
||||
- if (EVP_PKEY_base_id(tmp) != EVP_PKEY_DSA)
|
||||
- rb_raise(eDSAError, "incorrect pkey type: %s",
|
||||
- OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
|
||||
- dsa = EVP_PKEY_get1_DSA(tmp);
|
||||
- EVP_PKEY_free(tmp);
|
||||
- }
|
||||
- if (!dsa) {
|
||||
- OSSL_BIO_reset(in);
|
||||
-#define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
|
||||
- (d2i_of_void *)d2i_DSAPublicKey, PEM_STRING_DSA_PUBLIC, (bp), (void **)(x), (cb), (u))
|
||||
- dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
|
||||
-#undef PEM_read_bio_DSAPublicKey
|
||||
- }
|
||||
- BIO_free(in);
|
||||
- if (!dsa) {
|
||||
- ossl_clear_error();
|
||||
- ossl_raise(eDSAError, "Neither PUB key nor PRIV key");
|
||||
- }
|
||||
- }
|
||||
- if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
|
||||
- DSA_free(dsa);
|
||||
- ossl_raise(eDSAError, NULL);
|
||||
+
|
||||
+ pass = ossl_pem_passwd_value(pass);
|
||||
+ arg = ossl_to_der_if_possible(arg);
|
||||
+ in = ossl_obj2bio(&arg);
|
||||
+
|
||||
+ /* DER-encoded DSAPublicKey format isn't supported by the generic routine */
|
||||
+ dsa = (DSA *)PEM_ASN1_read_bio((d2i_of_void *)d2i_DSAPublicKey,
|
||||
+ PEM_STRING_DSA_PUBLIC,
|
||||
+ in, NULL, NULL, NULL);
|
||||
+ if (dsa)
|
||||
+ goto legacy;
|
||||
+ OSSL_BIO_reset(in);
|
||||
+
|
||||
+ pkey = ossl_pkey_read_generic(in, pass);
|
||||
+ BIO_free(in);
|
||||
+ if (!pkey)
|
||||
+ ossl_raise(eDSAError, "Neither PUB key nor PRIV key");
|
||||
+
|
||||
+ type = EVP_PKEY_base_id(pkey);
|
||||
+ if (type != EVP_PKEY_DSA) {
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
|
||||
}
|
||||
+ RTYPEDDATA_DATA(self) = pkey;
|
||||
+ return self;
|
||||
|
||||
+ legacy:
|
||||
+ BIO_free(in);
|
||||
+ pkey = EVP_PKEY_new();
|
||||
+ if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa) != 1) {
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ DSA_free(dsa);
|
||||
+ ossl_raise(eDSAError, "EVP_PKEY_assign_DSA");
|
||||
+ }
|
||||
+ RTYPEDDATA_DATA(self) = pkey;
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -136,16 +145,24 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other)
|
||||
EVP_PKEY *pkey;
|
||||
DSA *dsa, *dsa_new;
|
||||
|
||||
- GetPKey(self, pkey);
|
||||
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
|
||||
- ossl_raise(eDSAError, "DSA already initialized");
|
||||
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||
+ if (pkey)
|
||||
+ rb_raise(rb_eTypeError, "pkey already initialized");
|
||||
GetDSA(other, dsa);
|
||||
|
||||
- dsa_new = ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, (d2i_of_void *)d2i_DSAPrivateKey, (char *)dsa);
|
||||
+ dsa_new = (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey,
|
||||
+ (d2i_of_void *)d2i_DSAPrivateKey,
|
||||
+ (char *)dsa);
|
||||
if (!dsa_new)
|
||||
ossl_raise(eDSAError, "ASN1_dup");
|
||||
|
||||
- EVP_PKEY_assign_DSA(pkey, dsa_new);
|
||||
+ pkey = EVP_PKEY_new();
|
||||
+ if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa_new) != 1) {
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ DSA_free(dsa_new);
|
||||
+ ossl_raise(eDSAError, "EVP_PKEY_assign_DSA");
|
||||
+ }
|
||||
+ RTYPEDDATA_DATA(self) = pkey;
|
||||
|
||||
return self;
|
||||
}
|
||||
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
|
||||
index db80d112..71e63969 100644
|
||||
--- a/ext/openssl/ossl_pkey_ec.c
|
||||
+++ b/ext/openssl/ossl_pkey_ec.c
|
||||
@@ -114,13 +114,16 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg)
|
||||
VALUE obj;
|
||||
|
||||
obj = rb_obj_alloc(klass);
|
||||
- GetPKey(obj, pkey);
|
||||
|
||||
ec = ec_key_new_from_group(arg);
|
||||
- if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
|
||||
+ pkey = EVP_PKEY_new();
|
||||
+ if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) {
|
||||
+ EVP_PKEY_free(pkey);
|
||||
EC_KEY_free(ec);
|
||||
ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
||||
}
|
||||
+ RTYPEDDATA_DATA(obj) = pkey;
|
||||
+
|
||||
if (!EC_KEY_generate_key(ec))
|
||||
ossl_raise(eECError, "EC_KEY_generate_key");
|
||||
|
||||
@@ -141,51 +144,54 @@ ossl_ec_key_s_generate(VALUE klass, VALUE arg)
|
||||
static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
- EC_KEY *ec = NULL;
|
||||
+ EC_KEY *ec;
|
||||
+ BIO *in;
|
||||
VALUE arg, pass;
|
||||
+ int type;
|
||||
|
||||
- GetPKey(self, pkey);
|
||||
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
|
||||
- ossl_raise(eECError, "EC_KEY already initialized");
|
||||
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||
+ if (pkey)
|
||||
+ rb_raise(rb_eTypeError, "pkey already initialized");
|
||||
|
||||
rb_scan_args(argc, argv, "02", &arg, &pass);
|
||||
-
|
||||
if (NIL_P(arg)) {
|
||||
if (!(ec = EC_KEY_new()))
|
||||
- ossl_raise(eECError, NULL);
|
||||
- } else if (rb_obj_is_kind_of(arg, cEC)) {
|
||||
- EC_KEY *other_ec = NULL;
|
||||
+ ossl_raise(eECError, "EC_KEY_new");
|
||||
+ goto legacy;
|
||||
+ }
|
||||
+ else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
|
||||
+ ec = ec_key_new_from_group(arg);
|
||||
+ goto legacy;
|
||||
+ }
|
||||
|
||||
- GetEC(arg, other_ec);
|
||||
- if (!(ec = EC_KEY_dup(other_ec)))
|
||||
- ossl_raise(eECError, NULL);
|
||||
- } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) {
|
||||
- ec = ec_key_new_from_group(arg);
|
||||
- } else {
|
||||
- BIO *in = ossl_obj2bio(&arg);
|
||||
- EVP_PKEY *tmp;
|
||||
- pass = ossl_pem_passwd_value(pass);
|
||||
- tmp = ossl_pkey_read_generic(in, pass);
|
||||
- if (tmp) {
|
||||
- if (EVP_PKEY_base_id(tmp) != EVP_PKEY_EC)
|
||||
- rb_raise(eECError, "incorrect pkey type: %s",
|
||||
- OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
|
||||
- ec = EVP_PKEY_get1_EC_KEY(tmp);
|
||||
- EVP_PKEY_free(tmp);
|
||||
- }
|
||||
- BIO_free(in);
|
||||
+ pass = ossl_pem_passwd_value(pass);
|
||||
+ arg = ossl_to_der_if_possible(arg);
|
||||
+ in = ossl_obj2bio(&arg);
|
||||
|
||||
- if (!ec) {
|
||||
- ossl_clear_error();
|
||||
- ec = ec_key_new_from_group(arg);
|
||||
- }
|
||||
+ pkey = ossl_pkey_read_generic(in, pass);
|
||||
+ BIO_free(in);
|
||||
+ if (!pkey) {
|
||||
+ ossl_clear_error();
|
||||
+ ec = ec_key_new_from_group(arg);
|
||||
+ goto legacy;
|
||||
}
|
||||
|
||||
- if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
|
||||
- EC_KEY_free(ec);
|
||||
- ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
||||
+ type = EVP_PKEY_base_id(pkey);
|
||||
+ if (type != EVP_PKEY_EC) {
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
|
||||
}
|
||||
+ RTYPEDDATA_DATA(self) = pkey;
|
||||
+ return self;
|
||||
|
||||
+ legacy:
|
||||
+ pkey = EVP_PKEY_new();
|
||||
+ if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) {
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ EC_KEY_free(ec);
|
||||
+ ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
||||
+ }
|
||||
+ RTYPEDDATA_DATA(self) = pkey;
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -195,18 +201,21 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other)
|
||||
EVP_PKEY *pkey;
|
||||
EC_KEY *ec, *ec_new;
|
||||
|
||||
- GetPKey(self, pkey);
|
||||
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
|
||||
- ossl_raise(eECError, "EC already initialized");
|
||||
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||
+ if (pkey)
|
||||
+ rb_raise(rb_eTypeError, "pkey already initialized");
|
||||
GetEC(other, ec);
|
||||
|
||||
ec_new = EC_KEY_dup(ec);
|
||||
if (!ec_new)
|
||||
ossl_raise(eECError, "EC_KEY_dup");
|
||||
- if (!EVP_PKEY_assign_EC_KEY(pkey, ec_new)) {
|
||||
- EC_KEY_free(ec_new);
|
||||
- ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
||||
+
|
||||
+ pkey = EVP_PKEY_new();
|
||||
+ if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec_new) != 1) {
|
||||
+ EC_KEY_free(ec_new);
|
||||
+ ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY");
|
||||
}
|
||||
+ RTYPEDDATA_DATA(self) = pkey;
|
||||
|
||||
return self;
|
||||
}
|
||||
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
|
||||
index 8ebd3ec5..b8dbc0e1 100644
|
||||
--- a/ext/openssl/ossl_pkey_rsa.c
|
||||
+++ b/ext/openssl/ossl_pkey_rsa.c
|
||||
@@ -76,51 +76,62 @@ VALUE eRSAError;
|
||||
static VALUE
|
||||
ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
- EVP_PKEY *pkey, *tmp;
|
||||
- RSA *rsa = NULL;
|
||||
- BIO *in;
|
||||
+ EVP_PKEY *pkey;
|
||||
+ RSA *rsa;
|
||||
+ BIO *in = NULL;
|
||||
VALUE arg, pass;
|
||||
+ int type;
|
||||
+
|
||||
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||
+ if (pkey)
|
||||
+ rb_raise(rb_eTypeError, "pkey already initialized");
|
||||
|
||||
- GetPKey(self, pkey);
|
||||
/* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */
|
||||
rb_scan_args(argc, argv, "02", &arg, &pass);
|
||||
if (argc == 0) {
|
||||
rsa = RSA_new();
|
||||
if (!rsa)
|
||||
ossl_raise(eRSAError, "RSA_new");
|
||||
+ goto legacy;
|
||||
}
|
||||
- else {
|
||||
- pass = ossl_pem_passwd_value(pass);
|
||||
- arg = ossl_to_der_if_possible(arg);
|
||||
- in = ossl_obj2bio(&arg);
|
||||
-
|
||||
- tmp = ossl_pkey_read_generic(in, pass);
|
||||
- if (tmp) {
|
||||
- if (EVP_PKEY_base_id(tmp) != EVP_PKEY_RSA)
|
||||
- rb_raise(eRSAError, "incorrect pkey type: %s",
|
||||
- OBJ_nid2sn(EVP_PKEY_base_id(tmp)));
|
||||
- rsa = EVP_PKEY_get1_RSA(tmp);
|
||||
- EVP_PKEY_free(tmp);
|
||||
- }
|
||||
- if (!rsa) {
|
||||
- OSSL_BIO_reset(in);
|
||||
- rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
|
||||
- }
|
||||
- if (!rsa) {
|
||||
- OSSL_BIO_reset(in);
|
||||
- rsa = d2i_RSAPublicKey_bio(in, NULL);
|
||||
- }
|
||||
- BIO_free(in);
|
||||
- if (!rsa) {
|
||||
- ossl_clear_error();
|
||||
- ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
|
||||
- }
|
||||
- }
|
||||
- if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
|
||||
- RSA_free(rsa);
|
||||
- ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
|
||||
+
|
||||
+ pass = ossl_pem_passwd_value(pass);
|
||||
+ arg = ossl_to_der_if_possible(arg);
|
||||
+ in = ossl_obj2bio(&arg);
|
||||
+
|
||||
+ /* First try RSAPublicKey format */
|
||||
+ rsa = d2i_RSAPublicKey_bio(in, NULL);
|
||||
+ if (rsa)
|
||||
+ goto legacy;
|
||||
+ OSSL_BIO_reset(in);
|
||||
+ rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
|
||||
+ if (rsa)
|
||||
+ goto legacy;
|
||||
+ OSSL_BIO_reset(in);
|
||||
+
|
||||
+ /* Use the generic routine */
|
||||
+ pkey = ossl_pkey_read_generic(in, pass);
|
||||
+ BIO_free(in);
|
||||
+ if (!pkey)
|
||||
+ ossl_raise(eRSAError, "Neither PUB key nor PRIV key");
|
||||
+
|
||||
+ type = EVP_PKEY_base_id(pkey);
|
||||
+ if (type != EVP_PKEY_RSA) {
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ rb_raise(eRSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
|
||||
}
|
||||
+ RTYPEDDATA_DATA(self) = pkey;
|
||||
+ return self;
|
||||
|
||||
+ legacy:
|
||||
+ BIO_free(in);
|
||||
+ pkey = EVP_PKEY_new();
|
||||
+ if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ RSA_free(rsa);
|
||||
+ ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
|
||||
+ }
|
||||
+ RTYPEDDATA_DATA(self) = pkey;
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -130,16 +141,23 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other)
|
||||
EVP_PKEY *pkey;
|
||||
RSA *rsa, *rsa_new;
|
||||
|
||||
- GetPKey(self, pkey);
|
||||
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
|
||||
- ossl_raise(eRSAError, "RSA already initialized");
|
||||
+ TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey);
|
||||
+ if (pkey)
|
||||
+ rb_raise(rb_eTypeError, "pkey already initialized");
|
||||
GetRSA(other, rsa);
|
||||
|
||||
- rsa_new = ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, (d2i_of_void *)d2i_RSAPrivateKey, (char *)rsa);
|
||||
+ rsa_new = (RSA *)ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey,
|
||||
+ (d2i_of_void *)d2i_RSAPrivateKey,
|
||||
+ (char *)rsa);
|
||||
if (!rsa_new)
|
||||
ossl_raise(eRSAError, "ASN1_dup");
|
||||
|
||||
- EVP_PKEY_assign_RSA(pkey, rsa_new);
|
||||
+ pkey = EVP_PKEY_new();
|
||||
+ if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa_new) != 1) {
|
||||
+ RSA_free(rsa_new);
|
||||
+ ossl_raise(eRSAError, "EVP_PKEY_assign_RSA");
|
||||
+ }
|
||||
+ RTYPEDDATA_DATA(self) = pkey;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
719
ruby-3.1.0-Deprecate-PKey-set_-and-PKey-DH-EC-generate_key.patch
Normal file
719
ruby-3.1.0-Deprecate-PKey-set_-and-PKey-DH-EC-generate_key.patch
Normal file
@ -0,0 +1,719 @@
|
||||
From 46ca47060ca8ef3419ec36c2326a81b442d9b43b Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Sun, 12 Dec 2021 01:25:20 +0900
|
||||
Subject: [PATCH 1/5] pkey/dh: avoid using DH#set_key in DH#compute_key
|
||||
|
||||
DH#set_key will not work on OpenSSL 3.0 because keys are immutable.
|
||||
For now, let's reimplement DH#compute_key by manually constructing a
|
||||
DER-encoded SubjectPublicKeyInfo structure and feeding it to
|
||||
OpenSSL::PKey.read.
|
||||
|
||||
Eventually, we should implement a new method around EVP_PKEY_fromdata()
|
||||
and use it instead.
|
||||
---
|
||||
ext/openssl/lib/openssl/pkey.rb | 16 +++++++++++++---
|
||||
1 file changed, 13 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
|
||||
index f6bf5892..5864faa9 100644
|
||||
--- a/ext/openssl/lib/openssl/pkey.rb
|
||||
+++ b/ext/openssl/lib/openssl/pkey.rb
|
||||
@@ -47,9 +47,19 @@ def public_key
|
||||
# * _pub_bn_ is a OpenSSL::BN, *not* the DH instance returned by
|
||||
# DH#public_key as that contains the DH parameters only.
|
||||
def compute_key(pub_bn)
|
||||
- peer = dup
|
||||
- peer.set_key(pub_bn, nil)
|
||||
- derive(peer)
|
||||
+ # FIXME: This is constructing an X.509 SubjectPublicKeyInfo and is very
|
||||
+ # inefficient
|
||||
+ obj = OpenSSL::ASN1.Sequence([
|
||||
+ OpenSSL::ASN1.Sequence([
|
||||
+ OpenSSL::ASN1.ObjectId("dhKeyAgreement"),
|
||||
+ OpenSSL::ASN1.Sequence([
|
||||
+ OpenSSL::ASN1.Integer(p),
|
||||
+ OpenSSL::ASN1.Integer(g),
|
||||
+ ]),
|
||||
+ ]),
|
||||
+ OpenSSL::ASN1.BitString(OpenSSL::ASN1.Integer(pub_bn).to_der),
|
||||
+ ])
|
||||
+ derive(OpenSSL::PKey.read(obj.to_der))
|
||||
end
|
||||
|
||||
# :call-seq:
|
||||
|
||||
From fc9aabc18df3c189cc6a76a1470ca908c4f16480 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Fri, 17 Dec 2021 02:22:25 +0900
|
||||
Subject: [PATCH 2/5] pkey/ec: avoid using EC#public_key= in EC#dh_compute_key
|
||||
|
||||
Similarly to DH#compute_key, work around it by constructing a
|
||||
SubjectPublicKeyInfo. This should be considered as a temporary
|
||||
implementation.
|
||||
---
|
||||
ext/openssl/lib/openssl/pkey.rb | 11 ++++++++---
|
||||
1 file changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
|
||||
index 5864faa9..ba04cf4b 100644
|
||||
--- a/ext/openssl/lib/openssl/pkey.rb
|
||||
+++ b/ext/openssl/lib/openssl/pkey.rb
|
||||
@@ -259,9 +259,14 @@ def dsa_verify_asn1(data, sig)
|
||||
# This method is provided for backwards compatibility, and calls #derive
|
||||
# internally.
|
||||
def dh_compute_key(pubkey)
|
||||
- peer = OpenSSL::PKey::EC.new(group)
|
||||
- peer.public_key = pubkey
|
||||
- derive(peer)
|
||||
+ obj = OpenSSL::ASN1.Sequence([
|
||||
+ OpenSSL::ASN1.Sequence([
|
||||
+ OpenSSL::ASN1.ObjectId("id-ecPublicKey"),
|
||||
+ group.to_der,
|
||||
+ ]),
|
||||
+ OpenSSL::ASN1.BitString(pubkey.to_octet_string(:uncompressed)),
|
||||
+ ])
|
||||
+ derive(OpenSSL::PKey.read(obj.to_der))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
From 8ee6a582c7e4614eec4f5ca5ab59898fbcb50d2a Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Fri, 22 Oct 2021 16:24:07 +0900
|
||||
Subject: [PATCH 3/5] pkey/dh: deprecate OpenSSL::PKey::DH#generate_key!
|
||||
|
||||
OpenSSL::PKey::DH#generate_key! will not work on OpenSSL 3.0 because
|
||||
keys are made immutable. Users should use OpenSSL::PKey.generate_key
|
||||
instead.
|
||||
---
|
||||
ext/openssl/lib/openssl/pkey.rb | 23 +++++++++++++++++++----
|
||||
ext/openssl/ossl_pkey_dh.c | 9 +++++----
|
||||
test/openssl/test_pkey_dh.rb | 18 ++++++++++--------
|
||||
3 files changed, 34 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb
|
||||
index ba04cf4b..c3e06290 100644
|
||||
--- a/ext/openssl/lib/openssl/pkey.rb
|
||||
+++ b/ext/openssl/lib/openssl/pkey.rb
|
||||
@@ -71,14 +71,29 @@ def compute_key(pub_bn)
|
||||
# called first in order to generate the per-session keys before performing
|
||||
# the actual key exchange.
|
||||
#
|
||||
+ # <b>Deprecated in version 3.0</b>. This method is incompatible with
|
||||
+ # OpenSSL 3.0.0 or later.
|
||||
+ #
|
||||
# See also OpenSSL::PKey.generate_key.
|
||||
#
|
||||
# Example:
|
||||
- # dh = OpenSSL::PKey::DH.new(2048)
|
||||
- # public_key = dh.public_key #contains no private/public key yet
|
||||
- # public_key.generate_key!
|
||||
- # puts public_key.private? # => true
|
||||
+ # # DEPRECATED USAGE: This will not work on OpenSSL 3.0 or later
|
||||
+ # dh0 = OpenSSL::PKey::DH.new(2048)
|
||||
+ # dh = dh0.public_key # #public_key only copies the DH parameters (contrary to the name)
|
||||
+ # dh.generate_key!
|
||||
+ # puts dh.private? # => true
|
||||
+ # puts dh0.pub_key == dh.pub_key #=> false
|
||||
+ #
|
||||
+ # # With OpenSSL::PKey.generate_key
|
||||
+ # dh0 = OpenSSL::PKey::DH.new(2048)
|
||||
+ # dh = OpenSSL::PKey.generate_key(dh0)
|
||||
+ # puts dh0.pub_key == dh.pub_key #=> false
|
||||
def generate_key!
|
||||
+ if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x30000000
|
||||
+ raise DHError, "OpenSSL::PKey::DH is immutable on OpenSSL 3.0; " \
|
||||
+ "use OpenSSL::PKey.generate_key instead"
|
||||
+ end
|
||||
+
|
||||
unless priv_key
|
||||
tmp = OpenSSL::PKey.generate_key(self)
|
||||
set_key(tmp.pub_key, tmp.priv_key)
|
||||
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
|
||||
index 04c11b2157..e70d60ed19 100644
|
||||
--- a/ext/openssl/ossl_pkey_dh.c
|
||||
+++ b/ext/openssl/ossl_pkey_dh.c
|
||||
@@ -58,15 +58,16 @@ VALUE eDHError;
|
||||
*
|
||||
* Examples:
|
||||
* # Creating an instance from scratch
|
||||
- * dh = DH.new
|
||||
+ * # Note that this is deprecated and will not work on OpenSSL 3.0 or later.
|
||||
+ * dh = OpenSSL::PKey::DH.new
|
||||
* dh.set_pqg(bn_p, nil, bn_g)
|
||||
*
|
||||
* # Generating a parameters and a key pair
|
||||
- * dh = DH.new(2048) # An alias of DH.generate(2048)
|
||||
+ * dh = OpenSSL::PKey::DH.new(2048) # An alias of OpenSSL::PKey::DH.generate(2048)
|
||||
*
|
||||
* # Reading DH parameters
|
||||
- * dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet
|
||||
- * dh.generate_key! # -> dh with public and private key
|
||||
+ * dh_params = OpenSSL::PKey::DH.new(File.read('parameters.pem')) # loads parameters only
|
||||
+ * dh = OpenSSL::PKey.generate_key(dh_params) # generates a key pair
|
||||
*/
|
||||
static VALUE
|
||||
ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
|
||||
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb
|
||||
index 757704ca..ac11af38 100644
|
||||
--- a/test/openssl/test_pkey_dh.rb
|
||||
+++ b/test/openssl/test_pkey_dh.rb
|
||||
@@ -26,14 +26,19 @@ def test_new_break
|
||||
end
|
||||
|
||||
def test_derive_key
|
||||
- dh1 = Fixtures.pkey("dh1024").generate_key!
|
||||
- dh2 = Fixtures.pkey("dh1024").generate_key!
|
||||
+ params = Fixtures.pkey("dh1024")
|
||||
+ dh1 = OpenSSL::PKey.generate_key(params)
|
||||
+ dh2 = OpenSSL::PKey.generate_key(params)
|
||||
dh1_pub = OpenSSL::PKey.read(dh1.public_to_der)
|
||||
dh2_pub = OpenSSL::PKey.read(dh2.public_to_der)
|
||||
+
|
||||
z = dh1.g.mod_exp(dh1.priv_key, dh1.p).mod_exp(dh2.priv_key, dh1.p).to_s(2)
|
||||
assert_equal z, dh1.derive(dh2_pub)
|
||||
assert_equal z, dh2.derive(dh1_pub)
|
||||
|
||||
+ assert_raise(OpenSSL::PKey::PKeyError) { params.derive(dh1_pub) }
|
||||
+ assert_raise(OpenSSL::PKey::PKeyError) { dh1_pub.derive(params) }
|
||||
+
|
||||
assert_equal z, dh1.compute_key(dh2.pub_key)
|
||||
assert_equal z, dh2.compute_key(dh1.pub_key)
|
||||
end
|
||||
@@ -74,19 +79,16 @@ def test_public_key
|
||||
end
|
||||
|
||||
def test_generate_key
|
||||
- dh = Fixtures.pkey("dh1024").public_key # creates a copy
|
||||
+ # Deprecated in v3.0.0; incompatible with OpenSSL 3.0
|
||||
+ dh = Fixtures.pkey("dh1024").public_key # creates a copy with params only
|
||||
assert_no_key(dh)
|
||||
dh.generate_key!
|
||||
assert_key(dh)
|
||||
- end
|
||||
|
||||
- def test_key_exchange
|
||||
- dh = Fixtures.pkey("dh1024")
|
||||
dh2 = dh.public_key
|
||||
- dh.generate_key!
|
||||
dh2.generate_key!
|
||||
assert_equal(dh.compute_key(dh2.pub_key), dh2.compute_key(dh.pub_key))
|
||||
- end
|
||||
+ end if !openssl?(3, 0, 0)
|
||||
|
||||
def test_params_ok?
|
||||
dh0 = Fixtures.pkey("dh1024")
|
||||
|
||||
From 5e2e66cce870ea86001dbb0eaa3092badfd37994 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Fri, 17 Dec 2021 02:21:42 +0900
|
||||
Subject: [PATCH 4/5] pkey/ec: deprecate OpenSSL::PKey::EC#generate_key!
|
||||
|
||||
OpenSSL::PKey::EC#generate_key! will not work on OpenSSL 3.0 because
|
||||
keys are made immutable. Users should use OpenSSL::PKey.generate_key
|
||||
instead.
|
||||
---
|
||||
ext/openssl/ossl_pkey_ec.c | 4 ++++
|
||||
test/openssl/test_pkey_ec.rb | 21 +++++++++++++--------
|
||||
2 files changed, 17 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
|
||||
index db80d112..398a550a 100644
|
||||
--- a/ext/openssl/ossl_pkey_ec.c
|
||||
+++ b/ext/openssl/ossl_pkey_ec.c
|
||||
@@ -442,6 +442,9 @@ ossl_ec_key_to_der(VALUE self)
|
||||
*/
|
||||
static VALUE ossl_ec_key_generate_key(VALUE self)
|
||||
{
|
||||
+#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
||||
+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0");
|
||||
+#else
|
||||
EC_KEY *ec;
|
||||
|
||||
GetEC(self, ec);
|
||||
@@ -449,6 +452,7 @@ static VALUE ossl_ec_key_generate_key(VALUE self)
|
||||
ossl_raise(eECError, "EC_KEY_generate_key");
|
||||
|
||||
return self;
|
||||
+#endif
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb
|
||||
index 3f5958af..33f78a4c 100644
|
||||
--- a/test/openssl/test_pkey_ec.rb
|
||||
+++ b/test/openssl/test_pkey_ec.rb
|
||||
@@ -13,15 +13,13 @@ def test_ec_key
|
||||
# FIPS-selftest failure on some environment, so skip for now.
|
||||
next if ["Oakley", "X25519"].any? { |n| curve_name.start_with?(n) }
|
||||
|
||||
- key = OpenSSL::PKey::EC.new(curve_name)
|
||||
- key.generate_key!
|
||||
-
|
||||
+ key = OpenSSL::PKey::EC.generate(curve_name)
|
||||
assert_predicate key, :private?
|
||||
assert_predicate key, :public?
|
||||
assert_nothing_raised { key.check_key }
|
||||
end
|
||||
|
||||
- key1 = OpenSSL::PKey::EC.new("prime256v1").generate_key!
|
||||
+ key1 = OpenSSL::PKey::EC.generate("prime256v1")
|
||||
|
||||
key2 = OpenSSL::PKey::EC.new
|
||||
key2.group = key1.group
|
||||
@@ -52,6 +50,13 @@ def test_generate
|
||||
assert_equal(true, ec.private?)
|
||||
end
|
||||
|
||||
+ def test_generate_key
|
||||
+ ec = OpenSSL::PKey::EC.new("prime256v1")
|
||||
+ assert_equal false, ec.private?
|
||||
+ ec.generate_key!
|
||||
+ assert_equal true, ec.private?
|
||||
+ end if !openssl?(3, 0, 0)
|
||||
+
|
||||
def test_marshal
|
||||
key = Fixtures.pkey("p256")
|
||||
deserialized = Marshal.load(Marshal.dump(key))
|
||||
@@ -136,7 +141,7 @@ def test_sign_verify_raw
|
||||
end
|
||||
|
||||
def test_dsa_sign_asn1_FIPS186_3
|
||||
- key = OpenSSL::PKey::EC.new("prime256v1").generate_key!
|
||||
+ key = OpenSSL::PKey::EC.generate("prime256v1")
|
||||
size = key.group.order.num_bits / 8 + 1
|
||||
dgst = (1..size).to_a.pack('C*')
|
||||
sig = key.dsa_sign_asn1(dgst)
|
||||
@@ -145,8 +150,8 @@ def test_dsa_sign_asn1_FIPS186_3
|
||||
end
|
||||
|
||||
def test_dh_compute_key
|
||||
- key_a = OpenSSL::PKey::EC.new("prime256v1").generate_key!
|
||||
- key_b = OpenSSL::PKey::EC.new(key_a.group).generate_key!
|
||||
+ key_a = OpenSSL::PKey::EC.generate("prime256v1")
|
||||
+ key_b = OpenSSL::PKey::EC.generate(key_a.group)
|
||||
|
||||
pub_a = key_a.public_key
|
||||
pub_b = key_b.public_key
|
||||
@@ -276,7 +281,7 @@ def test_ec_group
|
||||
|
||||
def test_ec_point
|
||||
group = OpenSSL::PKey::EC::Group.new("prime256v1")
|
||||
- key = OpenSSL::PKey::EC.new(group).generate_key!
|
||||
+ key = OpenSSL::PKey::EC.generate(group)
|
||||
point = key.public_key
|
||||
|
||||
point2 = OpenSSL::PKey::EC::Point.new(group, point.to_bn)
|
||||
|
||||
From 6848d2d969d90e6a400d89848ecec21076b87888 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Tue, 21 Sep 2021 18:29:59 +0900
|
||||
Subject: [PATCH 5/5] pkey: deprecate PKey#set_* methods
|
||||
|
||||
OpenSSL 3.0 made EVP_PKEY immutable. This means we can only have a const
|
||||
pointer of the low level struct and the following methods can no longer
|
||||
be provided when linked against OpenSSL 3.0:
|
||||
|
||||
- OpenSSL::PKey::RSA#set_key
|
||||
- OpenSSL::PKey::RSA#set_factors
|
||||
- OpenSSL::PKey::RSA#set_crt_params
|
||||
- OpenSSL::PKey::DSA#set_pqg
|
||||
- OpenSSL::PKey::DSA#set_key
|
||||
- OpenSSL::PKey::DH#set_pqg
|
||||
- OpenSSL::PKey::DH#set_key
|
||||
- OpenSSL::PKey::EC#group=
|
||||
- OpenSSL::PKey::EC#private_key=
|
||||
- OpenSSL::PKey::EC#public_key=
|
||||
|
||||
There is no direct replacement for this functionality at the moment.
|
||||
I plan to introduce a wrapper around EVP_PKEY_fromdata(), which takes
|
||||
all key components at once to construct an EVP_PKEY.
|
||||
---
|
||||
ext/openssl/ossl_pkey.h | 16 +++++++
|
||||
ext/openssl/ossl_pkey_ec.c | 12 +++++
|
||||
test/openssl/test_pkey_dh.rb | 38 +++++++++++-----
|
||||
test/openssl/test_pkey_dsa.rb | 8 +++-
|
||||
test/openssl/test_pkey_ec.rb | 58 ++++++++++++++----------
|
||||
test/openssl/test_pkey_rsa.rb | 85 ++++++++++++++++++++++-------------
|
||||
6 files changed, 149 insertions(+), 68 deletions(-)
|
||||
|
||||
diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h
|
||||
index 4beede22..4536e58e 100644
|
||||
--- a/ext/openssl/ossl_pkey.h
|
||||
+++ b/ext/openssl/ossl_pkey.h
|
||||
@@ -116,6 +116,7 @@ static VALUE ossl_##_keytype##_get_##_name(VALUE self) \
|
||||
OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \
|
||||
_type##_get0_##_group(obj, NULL, &bn))
|
||||
|
||||
+#if !OSSL_OPENSSL_PREREQ(3, 0, 0)
|
||||
#define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \
|
||||
/* \
|
||||
* call-seq: \
|
||||
@@ -173,6 +174,21 @@ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \
|
||||
} \
|
||||
return self; \
|
||||
}
|
||||
+#else
|
||||
+#define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \
|
||||
+static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2, VALUE v3) \
|
||||
+{ \
|
||||
+ rb_raise(ePKeyError, \
|
||||
+ #_keytype"#set_"#_group"= is incompatible with OpenSSL 3.0"); \
|
||||
+}
|
||||
+
|
||||
+#define OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \
|
||||
+static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \
|
||||
+{ \
|
||||
+ rb_raise(ePKeyError, \
|
||||
+ #_keytype"#set_"#_group"= is incompatible with OpenSSL 3.0"); \
|
||||
+}
|
||||
+#endif
|
||||
|
||||
#define OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, _name) \
|
||||
/* \
|
||||
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
|
||||
index 398a550a..7a6ed1c9 100644
|
||||
--- a/ext/openssl/ossl_pkey_ec.c
|
||||
+++ b/ext/openssl/ossl_pkey_ec.c
|
||||
@@ -251,6 +251,9 @@ ossl_ec_key_get_group(VALUE self)
|
||||
static VALUE
|
||||
ossl_ec_key_set_group(VALUE self, VALUE group_v)
|
||||
{
|
||||
+#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
||||
+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0");
|
||||
+#else
|
||||
EC_KEY *ec;
|
||||
EC_GROUP *group;
|
||||
|
||||
@@ -261,6 +264,7 @@ ossl_ec_key_set_group(VALUE self, VALUE group_v)
|
||||
ossl_raise(eECError, "EC_KEY_set_group");
|
||||
|
||||
return group_v;
|
||||
+#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -289,6 +293,9 @@ static VALUE ossl_ec_key_get_private_key(VALUE self)
|
||||
*/
|
||||
static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key)
|
||||
{
|
||||
+#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
||||
+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0");
|
||||
+#else
|
||||
EC_KEY *ec;
|
||||
BIGNUM *bn = NULL;
|
||||
|
||||
@@ -307,6 +314,7 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key)
|
||||
}
|
||||
|
||||
return private_key;
|
||||
+#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -335,6 +343,9 @@ static VALUE ossl_ec_key_get_public_key(VALUE self)
|
||||
*/
|
||||
static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)
|
||||
{
|
||||
+#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
||||
+ rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0");
|
||||
+#else
|
||||
EC_KEY *ec;
|
||||
EC_POINT *point = NULL;
|
||||
|
||||
@@ -353,6 +364,7 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key)
|
||||
}
|
||||
|
||||
return public_key;
|
||||
+#endif
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb
|
||||
index ac11af38..161af189 100644
|
||||
--- a/test/openssl/test_pkey_dh.rb
|
||||
+++ b/test/openssl/test_pkey_dh.rb
|
||||
@@ -107,13 +107,32 @@ def test_params_ok?
|
||||
end
|
||||
|
||||
def test_dup
|
||||
- dh = Fixtures.pkey("dh1024")
|
||||
- dh2 = dh.dup
|
||||
- assert_equal dh.to_der, dh2.to_der # params
|
||||
- assert_equal_params dh, dh2 # keys
|
||||
- dh2.set_pqg(dh2.p + 1, nil, dh2.g)
|
||||
- assert_not_equal dh2.p, dh.p
|
||||
- assert_equal dh2.g, dh.g
|
||||
+ # Parameters only
|
||||
+ dh1 = Fixtures.pkey("dh1024")
|
||||
+ dh2 = dh1.dup
|
||||
+ assert_equal dh1.to_der, dh2.to_der
|
||||
+ assert_not_equal nil, dh1.p
|
||||
+ assert_not_equal nil, dh1.g
|
||||
+ assert_equal [dh1.p, dh1.g], [dh2.p, dh2.g]
|
||||
+ assert_equal nil, dh1.pub_key
|
||||
+ assert_equal nil, dh1.priv_key
|
||||
+ assert_equal [dh1.pub_key, dh1.priv_key], [dh2.pub_key, dh2.priv_key]
|
||||
+
|
||||
+ # PKey is immutable in OpenSSL >= 3.0
|
||||
+ if !openssl?(3, 0, 0)
|
||||
+ dh2.set_pqg(dh2.p + 1, nil, dh2.g)
|
||||
+ assert_not_equal dh2.p, dh1.p
|
||||
+ end
|
||||
+
|
||||
+ # With a key pair
|
||||
+ dh3 = OpenSSL::PKey.generate_key(Fixtures.pkey("dh1024"))
|
||||
+ dh4 = dh3.dup
|
||||
+ assert_equal dh3.to_der, dh4.to_der
|
||||
+ assert_equal dh1.to_der, dh4.to_der # encodes parameters only
|
||||
+ assert_equal [dh1.p, dh1.g], [dh4.p, dh4.g]
|
||||
+ assert_not_equal nil, dh3.pub_key
|
||||
+ assert_not_equal nil, dh3.priv_key
|
||||
+ assert_equal [dh3.pub_key, dh3.priv_key], [dh4.pub_key, dh4.priv_key]
|
||||
end
|
||||
|
||||
def test_marshal
|
||||
@@ -125,11 +144,6 @@ def test_marshal
|
||||
|
||||
private
|
||||
|
||||
- def assert_equal_params(dh1, dh2)
|
||||
- assert_equal(dh1.g, dh2.g)
|
||||
- assert_equal(dh1.p, dh2.p)
|
||||
- end
|
||||
-
|
||||
def assert_no_key(dh)
|
||||
assert_equal(false, dh.public?)
|
||||
assert_equal(false, dh.private?)
|
||||
diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb
|
||||
index 0994607f..726b7dbf 100644
|
||||
--- a/test/openssl/test_pkey_dsa.rb
|
||||
+++ b/test/openssl/test_pkey_dsa.rb
|
||||
@@ -208,8 +208,12 @@ def test_dup
|
||||
key = Fixtures.pkey("dsa1024")
|
||||
key2 = key.dup
|
||||
assert_equal key.params, key2.params
|
||||
- key2.set_pqg(key2.p + 1, key2.q, key2.g)
|
||||
- assert_not_equal key.params, key2.params
|
||||
+
|
||||
+ # PKey is immutable in OpenSSL >= 3.0
|
||||
+ if !openssl?(3, 0, 0)
|
||||
+ key2.set_pqg(key2.p + 1, key2.q, key2.g)
|
||||
+ assert_not_equal key.params, key2.params
|
||||
+ end
|
||||
end
|
||||
|
||||
def test_marshal
|
||||
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb
|
||||
index 33f78a4c..ffe5a94e 100644
|
||||
--- a/test/openssl/test_pkey_ec.rb
|
||||
+++ b/test/openssl/test_pkey_ec.rb
|
||||
@@ -21,11 +21,15 @@ def test_ec_key
|
||||
|
||||
key1 = OpenSSL::PKey::EC.generate("prime256v1")
|
||||
|
||||
- key2 = OpenSSL::PKey::EC.new
|
||||
- key2.group = key1.group
|
||||
- key2.private_key = key1.private_key
|
||||
- key2.public_key = key1.public_key
|
||||
- assert_equal key1.to_der, key2.to_der
|
||||
+ # PKey is immutable in OpenSSL >= 3.0; constructing an empty EC object is
|
||||
+ # deprecated
|
||||
+ if !openssl?(3, 0, 0)
|
||||
+ key2 = OpenSSL::PKey::EC.new
|
||||
+ key2.group = key1.group
|
||||
+ key2.private_key = key1.private_key
|
||||
+ key2.public_key = key1.public_key
|
||||
+ assert_equal key1.to_der, key2.to_der
|
||||
+ end
|
||||
|
||||
key3 = OpenSSL::PKey::EC.new(key1)
|
||||
assert_equal key1.to_der, key3.to_der
|
||||
@@ -35,10 +39,14 @@ def test_ec_key
|
||||
|
||||
key5 = key1.dup
|
||||
assert_equal key1.to_der, key5.to_der
|
||||
- key_tmp = OpenSSL::PKey::EC.new("prime256v1").generate_key!
|
||||
- key5.private_key = key_tmp.private_key
|
||||
- key5.public_key = key_tmp.public_key
|
||||
- assert_not_equal key1.to_der, key5.to_der
|
||||
+
|
||||
+ # PKey is immutable in OpenSSL >= 3.0; EC object should not be modified
|
||||
+ if !openssl?(3, 0, 0)
|
||||
+ key_tmp = OpenSSL::PKey::EC.generate("prime256v1")
|
||||
+ key5.private_key = key_tmp.private_key
|
||||
+ key5.public_key = key_tmp.public_key
|
||||
+ assert_not_equal key1.to_der, key5.to_der
|
||||
+ end
|
||||
end
|
||||
|
||||
def test_generate
|
||||
@@ -65,22 +73,26 @@ def test_marshal
|
||||
end
|
||||
|
||||
def test_check_key
|
||||
- key = OpenSSL::PKey::EC.new("prime256v1").generate_key!
|
||||
- assert_equal(true, key.check_key)
|
||||
- assert_equal(true, key.private?)
|
||||
- assert_equal(true, key.public?)
|
||||
- key2 = OpenSSL::PKey::EC.new(key.group)
|
||||
- assert_equal(false, key2.private?)
|
||||
- assert_equal(false, key2.public?)
|
||||
- key2.public_key = key.public_key
|
||||
- assert_equal(false, key2.private?)
|
||||
- assert_equal(true, key2.public?)
|
||||
- key2.private_key = key.private_key
|
||||
+ key0 = Fixtures.pkey("p256")
|
||||
+ assert_equal(true, key0.check_key)
|
||||
+ assert_equal(true, key0.private?)
|
||||
+ assert_equal(true, key0.public?)
|
||||
+
|
||||
+ key1 = OpenSSL::PKey.read(key0.public_to_der)
|
||||
+ assert_equal(true, key1.check_key)
|
||||
+ assert_equal(false, key1.private?)
|
||||
+ assert_equal(true, key1.public?)
|
||||
+
|
||||
+ key2 = OpenSSL::PKey.read(key0.private_to_der)
|
||||
assert_equal(true, key2.private?)
|
||||
assert_equal(true, key2.public?)
|
||||
assert_equal(true, key2.check_key)
|
||||
- key2.private_key += 1
|
||||
- assert_raise(OpenSSL::PKey::ECError) { key2.check_key }
|
||||
+
|
||||
+ # EC#private_key= is deprecated in 3.0 and won't work on OpenSSL 3.0
|
||||
+ if !openssl?(3, 0, 0)
|
||||
+ key2.private_key += 1
|
||||
+ assert_raise(OpenSSL::PKey::ECError) { key2.check_key }
|
||||
+ end
|
||||
end
|
||||
|
||||
def test_sign_verify
|
||||
@@ -112,7 +124,7 @@ def test_derive_key
|
||||
assert_equal [zIUT].pack("H*"), a.derive(b)
|
||||
|
||||
assert_equal a.derive(b), a.dh_compute_key(b.public_key)
|
||||
- end
|
||||
+ end if !openssl?(3, 0, 0) # TODO: Test it without using #private_key=
|
||||
|
||||
def test_sign_verify_raw
|
||||
key = Fixtures.pkey("p256")
|
||||
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
|
||||
index dbe87ba4..1c7f9ccf 100644
|
||||
--- a/test/openssl/test_pkey_rsa.rb
|
||||
+++ b/test/openssl/test_pkey_rsa.rb
|
||||
@@ -31,15 +31,18 @@ def test_private
|
||||
assert(!key4.private?)
|
||||
rsa1024 = Fixtures.pkey("rsa1024")
|
||||
|
||||
- # Generated by RSA#set_key
|
||||
- key5 = OpenSSL::PKey::RSA.new
|
||||
- key5.set_key(rsa1024.n, rsa1024.e, rsa1024.d)
|
||||
- assert(key5.private?)
|
||||
-
|
||||
- # Generated by RSA#set_key, without d
|
||||
- key6 = OpenSSL::PKey::RSA.new
|
||||
- key6.set_key(rsa1024.n, rsa1024.e, nil)
|
||||
- assert(!key6.private?)
|
||||
+ if !openssl?(3, 0, 0)
|
||||
+ key = OpenSSL::PKey::RSA.new
|
||||
+ # Generated by RSA#set_key
|
||||
+ key5 = OpenSSL::PKey::RSA.new
|
||||
+ key5.set_key(rsa1024.n, rsa1024.e, rsa1024.d)
|
||||
+ assert(key5.private?)
|
||||
+
|
||||
+ # Generated by RSA#set_key, without d
|
||||
+ key6 = OpenSSL::PKey::RSA.new
|
||||
+ key6.set_key(rsa1024.n, rsa1024.e, nil)
|
||||
+ assert(!key6.private?)
|
||||
+ end
|
||||
end
|
||||
|
||||
def test_new
|
||||
@@ -235,36 +238,52 @@ def test_encrypt_decrypt_legacy
|
||||
|
||||
def test_export
|
||||
rsa1024 = Fixtures.pkey("rsa1024")
|
||||
- key = OpenSSL::PKey::RSA.new
|
||||
|
||||
- # key has only n, e and d
|
||||
- key.set_key(rsa1024.n, rsa1024.e, rsa1024.d)
|
||||
- assert_equal rsa1024.public_key.export, key.export
|
||||
+ pub = OpenSSL::PKey.read(rsa1024.public_to_der)
|
||||
+ assert_not_equal rsa1024.export, pub.export
|
||||
+ assert_equal rsa1024.public_to_pem, pub.export
|
||||
+
|
||||
+ # PKey is immutable in OpenSSL >= 3.0
|
||||
+ if !openssl?(3, 0, 0)
|
||||
+ key = OpenSSL::PKey::RSA.new
|
||||
|
||||
- # key has only n, e, d, p and q
|
||||
- key.set_factors(rsa1024.p, rsa1024.q)
|
||||
- assert_equal rsa1024.public_key.export, key.export
|
||||
+ # key has only n, e and d
|
||||
+ key.set_key(rsa1024.n, rsa1024.e, rsa1024.d)
|
||||
+ assert_equal rsa1024.public_key.export, key.export
|
||||
|
||||
- # key has n, e, d, p, q, dmp1, dmq1 and iqmp
|
||||
- key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp)
|
||||
- assert_equal rsa1024.export, key.export
|
||||
+ # key has only n, e, d, p and q
|
||||
+ key.set_factors(rsa1024.p, rsa1024.q)
|
||||
+ assert_equal rsa1024.public_key.export, key.export
|
||||
+
|
||||
+ # key has n, e, d, p, q, dmp1, dmq1 and iqmp
|
||||
+ key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp)
|
||||
+ assert_equal rsa1024.export, key.export
|
||||
+ end
|
||||
end
|
||||
|
||||
def test_to_der
|
||||
rsa1024 = Fixtures.pkey("rsa1024")
|
||||
- key = OpenSSL::PKey::RSA.new
|
||||
|
||||
- # key has only n, e and d
|
||||
- key.set_key(rsa1024.n, rsa1024.e, rsa1024.d)
|
||||
- assert_equal rsa1024.public_key.to_der, key.to_der
|
||||
+ pub = OpenSSL::PKey.read(rsa1024.public_to_der)
|
||||
+ assert_not_equal rsa1024.to_der, pub.to_der
|
||||
+ assert_equal rsa1024.public_to_der, pub.to_der
|
||||
|
||||
- # key has only n, e, d, p and q
|
||||
- key.set_factors(rsa1024.p, rsa1024.q)
|
||||
- assert_equal rsa1024.public_key.to_der, key.to_der
|
||||
+ # PKey is immutable in OpenSSL >= 3.0
|
||||
+ if !openssl?(3, 0, 0)
|
||||
+ key = OpenSSL::PKey::RSA.new
|
||||
|
||||
- # key has n, e, d, p, q, dmp1, dmq1 and iqmp
|
||||
- key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp)
|
||||
- assert_equal rsa1024.to_der, key.to_der
|
||||
+ # key has only n, e and d
|
||||
+ key.set_key(rsa1024.n, rsa1024.e, rsa1024.d)
|
||||
+ assert_equal rsa1024.public_key.to_der, key.to_der
|
||||
+
|
||||
+ # key has only n, e, d, p and q
|
||||
+ key.set_factors(rsa1024.p, rsa1024.q)
|
||||
+ assert_equal rsa1024.public_key.to_der, key.to_der
|
||||
+
|
||||
+ # key has n, e, d, p, q, dmp1, dmq1 and iqmp
|
||||
+ key.set_crt_params(rsa1024.dmp1, rsa1024.dmq1, rsa1024.iqmp)
|
||||
+ assert_equal rsa1024.to_der, key.to_der
|
||||
+ end
|
||||
end
|
||||
|
||||
def test_RSAPrivateKey
|
||||
@@ -501,8 +520,12 @@ def test_dup
|
||||
key = Fixtures.pkey("rsa1024")
|
||||
key2 = key.dup
|
||||
assert_equal key.params, key2.params
|
||||
- key2.set_key(key2.n, 3, key2.d)
|
||||
- assert_not_equal key.params, key2.params
|
||||
+
|
||||
+ # PKey is immutable in OpenSSL >= 3.0
|
||||
+ if !openssl?(3, 0, 0)
|
||||
+ key2.set_key(key2.n, 3, key2.d)
|
||||
+ assert_not_equal key.params, key2.params
|
||||
+ end
|
||||
end
|
||||
|
||||
def test_marshal
|
27
ruby-3.1.0-Disable-test_no_private_exp-on-OpenSSL-3.0.patch
Normal file
27
ruby-3.1.0-Disable-test_no_private_exp-on-OpenSSL-3.0.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 47975ece4096cdab16b3f200f93ea2377dfb41ac Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Mon, 31 May 2021 14:17:21 +0900
|
||||
Subject: [PATCH] test/openssl/test_pkey_rsa: disable test_no_private_exp on
|
||||
OpenSSL 3.0
|
||||
|
||||
OpenSSL::PKey::RSA#set_key does not exist when built with OpenSSL 3.0,
|
||||
so it is not possible to create an RSA object with incomplete state.
|
||||
|
||||
https://github.com/ruby/openssl/commit/ca03c9c070
|
||||
---
|
||||
test/openssl/test_pkey_rsa.rb | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
|
||||
index 4548bdb2cfa6..dbe87ba4c1b0 100644
|
||||
--- a/test/openssl/test_pkey_rsa.rb
|
||||
+++ b/test/openssl/test_pkey_rsa.rb
|
||||
@@ -11,7 +11,7 @@ def test_no_private_exp
|
||||
key.set_factors(rsa.p, rsa.q)
|
||||
assert_raise(OpenSSL::PKey::RSAError){ key.private_encrypt("foo") }
|
||||
assert_raise(OpenSSL::PKey::RSAError){ key.private_decrypt("foo") }
|
||||
- end
|
||||
+ end if !openssl?(3, 0, 0) # Impossible state in OpenSSL 3.0
|
||||
|
||||
def test_private
|
||||
# Generated by key size and public exponent
|
@ -0,0 +1,523 @@
|
||||
From 8253d7c9cea16c2aa009b59db4f5d93afb74c6eb Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Tue, 30 Jun 2020 14:27:13 +0900
|
||||
Subject: [PATCH 1/2] hmac: add a test case for OpenSSL::HMAC singleton methods
|
||||
|
||||
---
|
||||
test/openssl/test_hmac.rb | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb
|
||||
index 9cb3c5a86..7202a5902 100644
|
||||
--- a/test/openssl/test_hmac.rb
|
||||
+++ b/test/openssl/test_hmac.rb
|
||||
@@ -49,6 +49,15 @@ def test_eq
|
||||
refute_equal h1, h2.digest
|
||||
refute_equal h1, h3
|
||||
end
|
||||
+
|
||||
+ def test_singleton_methods
|
||||
+ # RFC 2202 2. Test Cases for HMAC-MD5
|
||||
+ key = ["0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"].pack("H*")
|
||||
+ digest = OpenSSL::HMAC.digest("MD5", key, "Hi There")
|
||||
+ assert_equal ["9294727a3638bb1c13f48ef8158bfc9d"].pack("H*"), digest
|
||||
+ hexdigest = OpenSSL::HMAC.hexdigest("MD5", key, "Hi There")
|
||||
+ assert_equal "9294727a3638bb1c13f48ef8158bfc9d", hexdigest
|
||||
+ end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
From 0317e2fc028be40a7d64d0e4337d3e21539613ce Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Mon, 18 May 2020 16:15:07 +0900
|
||||
Subject: [PATCH 2/2] hmac: migrate from the low-level HMAC API to the EVP API
|
||||
|
||||
Use the EVP API instead of the low-level HMAC API. Use of the HMAC API
|
||||
has been discouraged and is being marked as deprecated starting from
|
||||
OpenSSL 3.0.0.
|
||||
|
||||
The two singleton methods OpenSSL::HMAC, HMAC.digest and HMAC.hexdigest
|
||||
are now in lib/openssl/hmac.rb.
|
||||
---
|
||||
ext/openssl/extconf.rb | 3 +-
|
||||
ext/openssl/lib/openssl/hmac.rb | 40 +++++++
|
||||
ext/openssl/openssl_missing.c | 26 -----
|
||||
ext/openssl/openssl_missing.h | 10 +-
|
||||
ext/openssl/ossl.h | 1 -
|
||||
ext/openssl/ossl_hmac.c | 179 ++++++++------------------------
|
||||
6 files changed, 89 insertions(+), 170 deletions(-)
|
||||
|
||||
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
|
||||
index 693e55cd9..063498a76 100644
|
||||
--- a/ext/openssl/extconf.rb
|
||||
+++ b/ext/openssl/extconf.rb
|
||||
@@ -141,8 +141,7 @@ def find_openssl_library
|
||||
have_func("BN_GENCB_get_arg")
|
||||
have_func("EVP_MD_CTX_new")
|
||||
have_func("EVP_MD_CTX_free")
|
||||
-have_func("HMAC_CTX_new")
|
||||
-have_func("HMAC_CTX_free")
|
||||
+have_func("EVP_MD_CTX_pkey_ctx")
|
||||
have_func("X509_STORE_get_ex_data")
|
||||
have_func("X509_STORE_set_ex_data")
|
||||
have_func("X509_STORE_get_ex_new_index")
|
||||
diff --git a/ext/openssl/lib/openssl/hmac.rb b/ext/openssl/lib/openssl/hmac.rb
|
||||
index 3d4427611d..9bc8bc8df3 100644
|
||||
--- a/ext/openssl/lib/openssl/hmac.rb
|
||||
+++ b/ext/openssl/lib/openssl/hmac.rb
|
||||
@@ -9,5 +9,45 @@ def ==(other)
|
||||
|
||||
OpenSSL.fixed_length_secure_compare(self.digest, other.digest)
|
||||
end
|
||||
+
|
||||
+ class << self
|
||||
+ # :call-seq:
|
||||
+ # HMAC.digest(digest, key, data) -> aString
|
||||
+ #
|
||||
+ # Returns the authentication code as a binary string. The _digest_ parameter
|
||||
+ # specifies the digest algorithm to use. This may be a String representing
|
||||
+ # the algorithm name or an instance of OpenSSL::Digest.
|
||||
+ #
|
||||
+ # === Example
|
||||
+ # key = 'key'
|
||||
+ # data = 'The quick brown fox jumps over the lazy dog'
|
||||
+ #
|
||||
+ # hmac = OpenSSL::HMAC.digest('SHA1', key, data)
|
||||
+ # #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9"
|
||||
+ def digest(digest, key, data)
|
||||
+ hmac = new(key, digest)
|
||||
+ hmac << data
|
||||
+ hmac.digest
|
||||
+ end
|
||||
+
|
||||
+ # :call-seq:
|
||||
+ # HMAC.hexdigest(digest, key, data) -> aString
|
||||
+ #
|
||||
+ # Returns the authentication code as a hex-encoded string. The _digest_
|
||||
+ # parameter specifies the digest algorithm to use. This may be a String
|
||||
+ # representing the algorithm name or an instance of OpenSSL::Digest.
|
||||
+ #
|
||||
+ # === Example
|
||||
+ # key = 'key'
|
||||
+ # data = 'The quick brown fox jumps over the lazy dog'
|
||||
+ #
|
||||
+ # hmac = OpenSSL::HMAC.hexdigest('SHA1', key, data)
|
||||
+ # #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
|
||||
+ def hexdigest(digest, key, data)
|
||||
+ hmac = new(key, digest)
|
||||
+ hmac << data
|
||||
+ hmac.hexdigest
|
||||
+ end
|
||||
+ end
|
||||
end
|
||||
end
|
||||
diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c
|
||||
index b36ef0288..010c158dc 100644
|
||||
--- a/ext/openssl/openssl_missing.c
|
||||
+++ b/ext/openssl/openssl_missing.c
|
||||
@@ -13,9 +13,6 @@
|
||||
#if !defined(OPENSSL_NO_ENGINE)
|
||||
# include <openssl/engine.h>
|
||||
#endif
|
||||
-#if !defined(OPENSSL_NO_HMAC)
|
||||
-# include <openssl/hmac.h>
|
||||
-#endif
|
||||
#include <openssl/x509_vfy.h>
|
||||
|
||||
#include "openssl_missing.h"
|
||||
@@ -58,29 +55,6 @@ ossl_EC_curve_nist2nid(const char *name)
|
||||
#endif
|
||||
|
||||
/*** added in 1.1.0 ***/
|
||||
-#if !defined(HAVE_HMAC_CTX_NEW)
|
||||
-HMAC_CTX *
|
||||
-ossl_HMAC_CTX_new(void)
|
||||
-{
|
||||
- HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX));
|
||||
- if (!ctx)
|
||||
- return NULL;
|
||||
- HMAC_CTX_init(ctx);
|
||||
- return ctx;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
-#if !defined(HAVE_HMAC_CTX_FREE)
|
||||
-void
|
||||
-ossl_HMAC_CTX_free(HMAC_CTX *ctx)
|
||||
-{
|
||||
- if (ctx) {
|
||||
- HMAC_CTX_cleanup(ctx);
|
||||
- OPENSSL_free(ctx);
|
||||
- }
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
#if !defined(HAVE_X509_CRL_GET0_SIGNATURE)
|
||||
void
|
||||
ossl_X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
|
||||
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
|
||||
index 7d218f86f..06d2a9082 100644
|
||||
--- a/ext/openssl/openssl_missing.h
|
||||
+++ b/ext/openssl/openssl_missing.h
|
||||
@@ -54,14 +54,8 @@ int ossl_EC_curve_nist2nid(const char *);
|
||||
# define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||
#endif
|
||||
|
||||
-#if !defined(HAVE_HMAC_CTX_NEW)
|
||||
-HMAC_CTX *ossl_HMAC_CTX_new(void);
|
||||
-# define HMAC_CTX_new ossl_HMAC_CTX_new
|
||||
-#endif
|
||||
-
|
||||
-#if !defined(HAVE_HMAC_CTX_FREE)
|
||||
-void ossl_HMAC_CTX_free(HMAC_CTX *);
|
||||
-# define HMAC_CTX_free ossl_HMAC_CTX_free
|
||||
+#if !defined(HAVE_EVP_MD_CTX_PKEY_CTX)
|
||||
+# define EVP_MD_CTX_pkey_ctx(x) (x)->pctx
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_X509_STORE_GET_EX_DATA)
|
||||
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h
|
||||
index c20f506bd..577eb6d6b 100644
|
||||
--- a/ext/openssl/ossl.h
|
||||
+++ b/ext/openssl/ossl.h
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
-#include <openssl/hmac.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/conf.h>
|
||||
#ifndef OPENSSL_NO_TS
|
||||
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c
|
||||
index 70e9fb819..a21db6c48 100644
|
||||
--- a/ext/openssl/ossl_hmac.c
|
||||
+++ b/ext/openssl/ossl_hmac.c
|
||||
@@ -7,14 +7,12 @@
|
||||
* This program is licensed under the same licence as Ruby.
|
||||
* (See the file 'LICENCE'.)
|
||||
*/
|
||||
-#if !defined(OPENSSL_NO_HMAC)
|
||||
-
|
||||
#include "ossl.h"
|
||||
|
||||
#define NewHMAC(klass) \
|
||||
TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0)
|
||||
#define GetHMAC(obj, ctx) do { \
|
||||
- TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \
|
||||
+ TypedData_Get_Struct((obj), EVP_MD_CTX, &ossl_hmac_type, (ctx)); \
|
||||
if (!(ctx)) { \
|
||||
ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \
|
||||
} \
|
||||
@@ -36,7 +34,7 @@ VALUE eHMACError;
|
||||
static void
|
||||
ossl_hmac_free(void *ctx)
|
||||
{
|
||||
- HMAC_CTX_free(ctx);
|
||||
+ EVP_MD_CTX_free(ctx);
|
||||
}
|
||||
|
||||
static const rb_data_type_t ossl_hmac_type = {
|
||||
@@ -51,12 +49,12 @@ static VALUE
|
||||
ossl_hmac_alloc(VALUE klass)
|
||||
{
|
||||
VALUE obj;
|
||||
- HMAC_CTX *ctx;
|
||||
+ EVP_MD_CTX *ctx;
|
||||
|
||||
obj = NewHMAC(klass);
|
||||
- ctx = HMAC_CTX_new();
|
||||
+ ctx = EVP_MD_CTX_new();
|
||||
if (!ctx)
|
||||
- ossl_raise(eHMACError, NULL);
|
||||
+ ossl_raise(eHMACError, "EVP_MD_CTX");
|
||||
RTYPEDDATA_DATA(obj) = ctx;
|
||||
|
||||
return obj;
|
||||
@@ -76,8 +74,7 @@ ossl_hmac_alloc(VALUE klass)
|
||||
* === Example
|
||||
*
|
||||
* key = 'key'
|
||||
- * digest = OpenSSL::Digest.new('sha1')
|
||||
- * instance = OpenSSL::HMAC.new(key, digest)
|
||||
+ * instance = OpenSSL::HMAC.new(key, 'SHA1')
|
||||
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
||||
* instance.class
|
||||
* #=> OpenSSL::HMAC
|
||||
@@ -86,7 +83,7 @@ ossl_hmac_alloc(VALUE klass)
|
||||
*
|
||||
* Two instances can be securely compared with #== in constant time:
|
||||
*
|
||||
- * other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
|
||||
+ * other_instance = OpenSSL::HMAC.new('key', 'SHA1')
|
||||
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
||||
* instance == other_instance
|
||||
* #=> true
|
||||
@@ -95,12 +92,23 @@ ossl_hmac_alloc(VALUE klass)
|
||||
static VALUE
|
||||
ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
|
||||
{
|
||||
- HMAC_CTX *ctx;
|
||||
+ EVP_MD_CTX *ctx;
|
||||
+ EVP_PKEY *pkey;
|
||||
|
||||
- StringValue(key);
|
||||
GetHMAC(self, ctx);
|
||||
- HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key),
|
||||
- ossl_evp_get_digestbyname(digest), NULL);
|
||||
+ StringValue(key);
|
||||
+ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
|
||||
+ (unsigned char *)RSTRING_PTR(key),
|
||||
+ RSTRING_LENINT(key));
|
||||
+ if (!pkey)
|
||||
+ ossl_raise(eHMACError, "EVP_PKEY_new_mac_key");
|
||||
+ if (EVP_DigestSignInit(ctx, NULL, ossl_evp_get_digestbyname(digest),
|
||||
+ NULL, pkey) != 1) {
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ ossl_raise(eHMACError, "EVP_DigestSignInit");
|
||||
+ }
|
||||
+ /* Decrement reference counter; EVP_MD_CTX still keeps it */
|
||||
+ EVP_PKEY_free(pkey);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -108,16 +116,15 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest)
|
||||
static VALUE
|
||||
ossl_hmac_copy(VALUE self, VALUE other)
|
||||
{
|
||||
- HMAC_CTX *ctx1, *ctx2;
|
||||
+ EVP_MD_CTX *ctx1, *ctx2;
|
||||
|
||||
rb_check_frozen(self);
|
||||
if (self == other) return self;
|
||||
|
||||
GetHMAC(self, ctx1);
|
||||
GetHMAC(other, ctx2);
|
||||
-
|
||||
- if (!HMAC_CTX_copy(ctx1, ctx2))
|
||||
- ossl_raise(eHMACError, "HMAC_CTX_copy");
|
||||
+ if (EVP_MD_CTX_copy(ctx1, ctx2) != 1)
|
||||
+ ossl_raise(eHMACError, "EVP_MD_CTX_copy");
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -142,33 +149,16 @@ ossl_hmac_copy(VALUE self, VALUE other)
|
||||
static VALUE
|
||||
ossl_hmac_update(VALUE self, VALUE data)
|
||||
{
|
||||
- HMAC_CTX *ctx;
|
||||
+ EVP_MD_CTX *ctx;
|
||||
|
||||
StringValue(data);
|
||||
GetHMAC(self, ctx);
|
||||
- HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data));
|
||||
+ if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1)
|
||||
+ ossl_raise(eHMACError, "EVP_DigestSignUpdate");
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-static void
|
||||
-hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
|
||||
-{
|
||||
- HMAC_CTX *final;
|
||||
-
|
||||
- final = HMAC_CTX_new();
|
||||
- if (!final)
|
||||
- ossl_raise(eHMACError, "HMAC_CTX_new");
|
||||
-
|
||||
- if (!HMAC_CTX_copy(final, ctx)) {
|
||||
- HMAC_CTX_free(final);
|
||||
- ossl_raise(eHMACError, "HMAC_CTX_copy");
|
||||
- }
|
||||
-
|
||||
- HMAC_Final(final, buf, buf_len);
|
||||
- HMAC_CTX_free(final);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* call-seq:
|
||||
* hmac.digest -> string
|
||||
@@ -176,7 +166,7 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
|
||||
* Returns the authentication code an instance represents as a binary string.
|
||||
*
|
||||
* === Example
|
||||
- * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
|
||||
+ * instance = OpenSSL::HMAC.new('key', 'SHA1')
|
||||
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
||||
* instance.digest
|
||||
* #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?"
|
||||
@@ -184,15 +174,16 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len)
|
||||
static VALUE
|
||||
ossl_hmac_digest(VALUE self)
|
||||
{
|
||||
- HMAC_CTX *ctx;
|
||||
- unsigned int buf_len;
|
||||
+ EVP_MD_CTX *ctx;
|
||||
+ size_t buf_len;
|
||||
VALUE ret;
|
||||
|
||||
GetHMAC(self, ctx);
|
||||
ret = rb_str_new(NULL, EVP_MAX_MD_SIZE);
|
||||
- hmac_final(ctx, (unsigned char *)RSTRING_PTR(ret), &buf_len);
|
||||
- assert(buf_len <= EVP_MAX_MD_SIZE);
|
||||
- rb_str_set_len(ret, buf_len);
|
||||
+ if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(ret),
|
||||
+ &buf_len) != 1)
|
||||
+ ossl_raise(eHMACError, "EVP_DigestSignFinal");
|
||||
+ rb_str_set_len(ret, (long)buf_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -207,13 +198,14 @@ ossl_hmac_digest(VALUE self)
|
||||
static VALUE
|
||||
ossl_hmac_hexdigest(VALUE self)
|
||||
{
|
||||
- HMAC_CTX *ctx;
|
||||
+ EVP_MD_CTX *ctx;
|
||||
unsigned char buf[EVP_MAX_MD_SIZE];
|
||||
- unsigned int buf_len;
|
||||
+ size_t buf_len;
|
||||
VALUE ret;
|
||||
|
||||
GetHMAC(self, ctx);
|
||||
- hmac_final(ctx, buf, &buf_len);
|
||||
+ if (EVP_DigestSignFinal(ctx, buf, &buf_len) != 1)
|
||||
+ ossl_raise(eHMACError, "EVP_DigestSignFinal");
|
||||
ret = rb_str_new(NULL, buf_len * 2);
|
||||
ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
|
||||
|
||||
@@ -230,7 +222,7 @@ ossl_hmac_hexdigest(VALUE self)
|
||||
* === Example
|
||||
*
|
||||
* data = "The quick brown fox jumps over the lazy dog"
|
||||
- * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
|
||||
+ * instance = OpenSSL::HMAC.new('key', 'SHA1')
|
||||
* #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
|
||||
*
|
||||
* instance.update(data)
|
||||
@@ -242,84 +234,17 @@ ossl_hmac_hexdigest(VALUE self)
|
||||
static VALUE
|
||||
ossl_hmac_reset(VALUE self)
|
||||
{
|
||||
- HMAC_CTX *ctx;
|
||||
+ EVP_MD_CTX *ctx;
|
||||
+ EVP_PKEY *pkey;
|
||||
|
||||
GetHMAC(self, ctx);
|
||||
- HMAC_Init_ex(ctx, NULL, 0, NULL, NULL);
|
||||
+ pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
|
||||
+ if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_md(ctx), NULL, pkey) != 1)
|
||||
+ ossl_raise(eHMACError, "EVP_DigestSignInit");
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * call-seq:
|
||||
- * HMAC.digest(digest, key, data) -> aString
|
||||
- *
|
||||
- * Returns the authentication code as a binary string. The _digest_ parameter
|
||||
- * specifies the digest algorithm to use. This may be a String representing
|
||||
- * the algorithm name or an instance of OpenSSL::Digest.
|
||||
- *
|
||||
- * === Example
|
||||
- *
|
||||
- * key = 'key'
|
||||
- * data = 'The quick brown fox jumps over the lazy dog'
|
||||
- *
|
||||
- * hmac = OpenSSL::HMAC.digest('sha1', key, data)
|
||||
- * #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9"
|
||||
- *
|
||||
- */
|
||||
-static VALUE
|
||||
-ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data)
|
||||
-{
|
||||
- unsigned char *buf;
|
||||
- unsigned int buf_len;
|
||||
-
|
||||
- StringValue(key);
|
||||
- StringValue(data);
|
||||
- buf = HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key),
|
||||
- RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data),
|
||||
- RSTRING_LEN(data), NULL, &buf_len);
|
||||
-
|
||||
- return rb_str_new((const char *)buf, buf_len);
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * call-seq:
|
||||
- * HMAC.hexdigest(digest, key, data) -> aString
|
||||
- *
|
||||
- * Returns the authentication code as a hex-encoded string. The _digest_
|
||||
- * parameter specifies the digest algorithm to use. This may be a String
|
||||
- * representing the algorithm name or an instance of OpenSSL::Digest.
|
||||
- *
|
||||
- * === Example
|
||||
- *
|
||||
- * key = 'key'
|
||||
- * data = 'The quick brown fox jumps over the lazy dog'
|
||||
- *
|
||||
- * hmac = OpenSSL::HMAC.hexdigest('sha1', key, data)
|
||||
- * #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9"
|
||||
- *
|
||||
- */
|
||||
-static VALUE
|
||||
-ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data)
|
||||
-{
|
||||
- unsigned char buf[EVP_MAX_MD_SIZE];
|
||||
- unsigned int buf_len;
|
||||
- VALUE ret;
|
||||
-
|
||||
- StringValue(key);
|
||||
- StringValue(data);
|
||||
-
|
||||
- if (!HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key),
|
||||
- RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data),
|
||||
- RSTRING_LEN(data), buf, &buf_len))
|
||||
- ossl_raise(eHMACError, "HMAC");
|
||||
-
|
||||
- ret = rb_str_new(NULL, buf_len * 2);
|
||||
- ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len);
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* INIT
|
||||
*/
|
||||
@@ -353,8 +278,7 @@ Init_ossl_hmac(void)
|
||||
* data1 = File.read("file1")
|
||||
* data2 = File.read("file2")
|
||||
* key = "key"
|
||||
- * digest = OpenSSL::Digest.new('SHA256')
|
||||
- * hmac = OpenSSL::HMAC.new(key, digest)
|
||||
+ * hmac = OpenSSL::HMAC.new(key, 'SHA256')
|
||||
* hmac << data1
|
||||
* hmac << data2
|
||||
* mac = hmac.digest
|
||||
@@ -364,8 +288,6 @@ Init_ossl_hmac(void)
|
||||
cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject);
|
||||
|
||||
rb_define_alloc_func(cHMAC, ossl_hmac_alloc);
|
||||
- rb_define_singleton_method(cHMAC, "digest", ossl_hmac_s_digest, 3);
|
||||
- rb_define_singleton_method(cHMAC, "hexdigest", ossl_hmac_s_hexdigest, 3);
|
||||
|
||||
rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2);
|
||||
rb_define_method(cHMAC, "initialize_copy", ossl_hmac_copy, 1);
|
||||
@@ -378,12 +300,3 @@ Init_ossl_hmac(void)
|
||||
rb_define_alias(cHMAC, "inspect", "hexdigest");
|
||||
rb_define_alias(cHMAC, "to_s", "hexdigest");
|
||||
}
|
||||
-
|
||||
-#else /* NO_HMAC */
|
||||
-# warning >>> OpenSSL is compiled without HMAC support <<<
|
||||
-void
|
||||
-Init_ossl_hmac(void)
|
||||
-{
|
||||
- rb_warning("HMAC is not available: OpenSSL is compiled without HMAC.");
|
||||
-}
|
||||
-#endif /* NO_HMAC */
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,458 @@
|
||||
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) {
|
@ -1,7 +1,7 @@
|
||||
From 8f948ed68a4ed6c05ff66d822711e3b70ae4bb3f Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Mon, 27 Sep 2021 13:32:03 +0900
|
||||
Subject: [PATCH 1/3] ext/openssl/ossl.h: add helper macros for
|
||||
Subject: [PATCH 1/5] ext/openssl/ossl.h: add helper macros for
|
||||
OpenSSL/LibreSSL versions
|
||||
|
||||
Add following convenient macros:
|
||||
@ -17,7 +17,7 @@ diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h
|
||||
index c20f506bda..a0cef29d74 100644
|
||||
--- a/ext/openssl/ossl.h
|
||||
+++ b/ext/openssl/ossl.h
|
||||
@@ -43,6 +43,18 @@
|
||||
@@ -42,6 +42,18 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/dh.h>
|
||||
|
||||
@ -43,7 +43,7 @@ index c20f506bda..a0cef29d74 100644
|
||||
From bbf235091e49807ece8f3a3df95bbfcc9d3ab43d Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Sat, 22 Feb 2020 05:37:01 +0900
|
||||
Subject: [PATCH 2/3] ts: use TS_VERIFY_CTX_set_certs instead of
|
||||
Subject: [PATCH 2/5] ts: use TS_VERIFY_CTX_set_certs instead of
|
||||
TS_VERIFY_CTS_set_certs
|
||||
|
||||
OpenSSL 3.0 fixed the typo in the function name and replaced the
|
||||
@ -58,7 +58,7 @@ diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
|
||||
index 17d93443fc..09cae05b72 100644
|
||||
--- a/ext/openssl/extconf.rb
|
||||
+++ b/ext/openssl/extconf.rb
|
||||
@@ -166,7 +166,7 @@ def find_openssl_library
|
||||
@@ -165,7 +165,7 @@ def find_openssl_library
|
||||
have_func("TS_STATUS_INFO_get0_status")
|
||||
have_func("TS_STATUS_INFO_get0_text")
|
||||
have_func("TS_STATUS_INFO_get0_failure_info")
|
||||
@ -67,7 +67,7 @@ index 17d93443fc..09cae05b72 100644
|
||||
have_func("TS_VERIFY_CTX_set_store")
|
||||
have_func("TS_VERIFY_CTX_add_flags")
|
||||
have_func("TS_RESP_CTX_set_time_cb")
|
||||
@@ -175,6 +175,9 @@ def find_openssl_library
|
||||
@@ -174,6 +174,9 @@ def find_openssl_library
|
||||
|
||||
# added in 1.1.1
|
||||
have_func("EVP_PKEY_check")
|
||||
@ -81,7 +81,7 @@ diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
|
||||
index e575415f49..fe486bcfcf 100644
|
||||
--- a/ext/openssl/openssl_missing.h
|
||||
+++ b/ext/openssl/openssl_missing.h
|
||||
@@ -242,4 +242,9 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
|
||||
@@ -236,4 +236,9 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
@ -111,7 +111,7 @@ index 692c0d620f..f1da7c1947 100644
|
||||
From 5fba3bc1df93ab6abc3ea53be3393480f36ea259 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Fri, 19 Mar 2021 19:18:25 +0900
|
||||
Subject: [PATCH 3/3] ssl: use SSL_get_rbio() to check if SSL is started or not
|
||||
Subject: [PATCH 3/5] ssl: use SSL_get_rbio() to check if SSL is started or not
|
||||
|
||||
Use SSL_get_rbio() instead of SSL_get_fd(). SSL_get_fd() internally
|
||||
calls SSL_get_rbio() and it's enough for our purpose.
|
||||
@ -140,3 +140,165 @@ index 4b7efa39f5..ec430bfb0c 100644
|
||||
--
|
||||
2.32.0
|
||||
|
||||
From 0a253027e6be47c0b7fd8b664f1048f24d7ca657 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Thu, 22 Apr 2021 13:57:47 +0900
|
||||
Subject: [PATCH 4/5] digest: use EVP_MD_CTX_get0_md() instead of
|
||||
EVP_MD_CTX_md() if exists
|
||||
|
||||
The function was renamed in OpenSSL 3.0 due to the change of the
|
||||
lifetime of EVP_MD objects. They are no longer necessarily statically
|
||||
allocated and can be reference-counted -- when an EVP_MD_CTX is free'd,
|
||||
the associated EVP_MD can also become inaccessible.
|
||||
|
||||
Currently Ruby/OpenSSL only handles builtin algorithms, so no special
|
||||
handling is needed except for adapting to the rename.
|
||||
---
|
||||
ext/openssl/extconf.rb | 1 +
|
||||
ext/openssl/openssl_missing.h | 4 ++++
|
||||
ext/openssl/ossl_digest.c | 6 +++---
|
||||
ext/openssl/ossl_hmac.c | 2 +-
|
||||
4 files changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
|
||||
index 98f96afe..842b7f5b 100644
|
||||
--- a/ext/openssl/extconf.rb
|
||||
+++ b/ext/openssl/extconf.rb
|
||||
@@ -177,6 +177,7 @@ def find_openssl_library
|
||||
|
||||
# added in 3.0.0
|
||||
have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h")
|
||||
+have_func("EVP_MD_CTX_get0_md")
|
||||
|
||||
Logging::message "=== Checking done. ===\n"
|
||||
|
||||
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
|
||||
index 1b1a54a8..64212349 100644
|
||||
--- a/ext/openssl/openssl_missing.h
|
||||
+++ b/ext/openssl/openssl_missing.h
|
||||
@@ -241,4 +241,8 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
|
||||
# define TS_VERIFY_CTX_set_certs(ctx, crts) TS_VERIFY_CTS_set_certs(ctx, crts)
|
||||
#endif
|
||||
|
||||
+#ifndef HAVE_EVP_MD_CTX_GET0_MD
|
||||
+# define EVP_MD_CTX_get0_md(ctx) EVP_MD_CTX_md(ctx)
|
||||
+#endif
|
||||
+
|
||||
#endif /* _OSSL_OPENSSL_MISSING_H_ */
|
||||
diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c
|
||||
index b2506de7..fc326ec1 100644
|
||||
--- a/ext/openssl/ossl_digest.c
|
||||
+++ b/ext/openssl/ossl_digest.c
|
||||
@@ -63,7 +63,7 @@ ossl_evp_get_digestbyname(VALUE obj)
|
||||
|
||||
GetDigest(obj, ctx);
|
||||
|
||||
- md = EVP_MD_CTX_md(ctx);
|
||||
+ md = EVP_MD_CTX_get0_md(ctx);
|
||||
}
|
||||
|
||||
return md;
|
||||
@@ -176,7 +176,7 @@ ossl_digest_reset(VALUE self)
|
||||
EVP_MD_CTX *ctx;
|
||||
|
||||
GetDigest(self, ctx);
|
||||
- if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL) != 1) {
|
||||
+ if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_get0_md(ctx), NULL) != 1) {
|
||||
ossl_raise(eDigestError, "Digest initialization failed.");
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ ossl_digest_name(VALUE self)
|
||||
|
||||
GetDigest(self, ctx);
|
||||
|
||||
- return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx)));
|
||||
+ return rb_str_new_cstr(EVP_MD_name(EVP_MD_CTX_get0_md(ctx)));
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c
|
||||
index a21db6c4..2642728b 100644
|
||||
--- a/ext/openssl/ossl_hmac.c
|
||||
+++ b/ext/openssl/ossl_hmac.c
|
||||
@@ -239,7 +239,7 @@ ossl_hmac_reset(VALUE self)
|
||||
|
||||
GetHMAC(self, ctx);
|
||||
pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
|
||||
- if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_md(ctx), NULL, pkey) != 1)
|
||||
+ if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1)
|
||||
ossl_raise(eHMACError, "EVP_DigestSignInit");
|
||||
|
||||
return self;
|
||||
|
||||
From c106d888c62e44a11cdbba5e4d2d0cb837ec3e52 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Tue, 22 Jun 2021 18:50:17 +0900
|
||||
Subject: [PATCH 5/5] hmac: use EVP_MD_CTX_get_pkey_ctx() instead of
|
||||
EVP_MD_CTX_pkey_ctx()
|
||||
|
||||
OpenSSL 3.0 renamed EVP_MD_CTX_pkey_ctx() to include "get" in the
|
||||
function name. Adjust compatibility macro so that we can use the new
|
||||
function name for all OpenSSL 1.0.2-3.0.
|
||||
---
|
||||
ext/openssl/extconf.rb | 1 +
|
||||
ext/openssl/openssl_missing.h | 16 ++++++++++++----
|
||||
ext/openssl/ossl_hmac.c | 2 +-
|
||||
3 files changed, 14 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
|
||||
index 842b7f5b..d9d34b7c 100644
|
||||
--- a/ext/openssl/extconf.rb
|
||||
+++ b/ext/openssl/extconf.rb
|
||||
@@ -178,6 +178,7 @@ def find_openssl_library
|
||||
# added in 3.0.0
|
||||
have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h")
|
||||
have_func("EVP_MD_CTX_get0_md")
|
||||
+have_func("EVP_MD_CTX_get_pkey_ctx")
|
||||
|
||||
Logging::message "=== Checking done. ===\n"
|
||||
|
||||
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
|
||||
index 64212349..55c4f378 100644
|
||||
--- a/ext/openssl/openssl_missing.h
|
||||
+++ b/ext/openssl/openssl_missing.h
|
||||
@@ -42,10 +42,6 @@ int ossl_EC_curve_nist2nid(const char *);
|
||||
# define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||
#endif
|
||||
|
||||
-#if !defined(HAVE_EVP_MD_CTX_PKEY_CTX)
|
||||
-# define EVP_MD_CTX_pkey_ctx(x) (x)->pctx
|
||||
-#endif
|
||||
-
|
||||
#if !defined(HAVE_X509_STORE_GET_EX_DATA)
|
||||
# define X509_STORE_get_ex_data(x, idx) \
|
||||
CRYPTO_get_ex_data(&(x)->ex_data, (idx))
|
||||
@@ -245,4 +241,16 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
|
||||
# define EVP_MD_CTX_get0_md(ctx) EVP_MD_CTX_md(ctx)
|
||||
#endif
|
||||
|
||||
+/*
|
||||
+ * OpenSSL 1.1.0 added EVP_MD_CTX_pkey_ctx(), and then it was renamed to
|
||||
+ * EVP_MD_CTX_get_pkey_ctx(x) in OpenSSL 3.0.
|
||||
+ */
|
||||
+#ifndef HAVE_EVP_MD_CTX_GET_PKEY_CTX
|
||||
+# ifdef HAVE_EVP_MD_CTX_PKEY_CTX
|
||||
+# define EVP_MD_CTX_get_pkey_ctx(x) EVP_MD_CTX_pkey_ctx(x)
|
||||
+# else
|
||||
+# define EVP_MD_CTX_get_pkey_ctx(x) (x)->pctx
|
||||
+# endif
|
||||
+#endif
|
||||
+
|
||||
#endif /* _OSSL_OPENSSL_MISSING_H_ */
|
||||
diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c
|
||||
index 2642728b..f89ff2f9 100644
|
||||
--- a/ext/openssl/ossl_hmac.c
|
||||
+++ b/ext/openssl/ossl_hmac.c
|
||||
@@ -238,7 +238,7 @@ ossl_hmac_reset(VALUE self)
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
GetHMAC(self, ctx);
|
||||
- pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
|
||||
+ pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx));
|
||||
if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1)
|
||||
ossl_raise(eHMACError, "EVP_DigestSignInit");
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -698,7 +698,7 @@ diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
|
||||
index b3c6647faf..17d93443fc 100644
|
||||
--- a/ext/openssl/extconf.rb
|
||||
+++ b/ext/openssl/extconf.rb
|
||||
@@ -173,6 +173,9 @@ def find_openssl_library
|
||||
@@ -172,6 +172,9 @@ def find_openssl_library
|
||||
have_func("EVP_PBE_scrypt")
|
||||
have_func("SSL_CTX_set_post_handshake_auth")
|
||||
|
||||
|
@ -0,0 +1,114 @@
|
||||
From 8c185e0ae5e42bf5f3d76a1a0898946671116fa3 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Wed, 3 Nov 2021 23:31:29 +0900
|
||||
Subject: [PATCH 1/2] pkey: test parsing concatenated PEM string
|
||||
|
||||
PEM-encoded private keys are sometimes stored together with irrelevant
|
||||
PEM blocks, such as the corresponding X.509 certificate.
|
||||
|
||||
PEM_read_bio_*() family automatically skips unknown PEM blocks, but on
|
||||
OpenSSL 3.0 we will be using the new OSSL_DECODER API instead due to
|
||||
some breaking changes around the password callback.
|
||||
|
||||
Let's add a test case so that we won't break the current behavior.
|
||||
---
|
||||
test/openssl/test_pkey_rsa.rb | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
|
||||
index dbe87ba4..7510658d 100644
|
||||
--- a/test/openssl/test_pkey_rsa.rb
|
||||
+++ b/test/openssl/test_pkey_rsa.rb
|
||||
@@ -306,6 +306,12 @@ def test_RSAPrivateKey
|
||||
|
||||
assert_equal asn1.to_der, rsa1024.to_der
|
||||
assert_equal pem, rsa1024.export
|
||||
+
|
||||
+ # Unknown PEM prepended
|
||||
+ cert = issue_cert(OpenSSL::X509::Name.new([["CN", "nobody"]]), rsa1024, 1, [], nil, nil)
|
||||
+ str = cert.to_text + cert.to_pem + rsa1024.to_pem
|
||||
+ key = OpenSSL::PKey::RSA.new(str)
|
||||
+ assert_same_rsa rsa1024, key
|
||||
end
|
||||
|
||||
def test_RSAPrivateKey_encrypted
|
||||
|
||||
From a84ea531bbd080c3f58fe8d3dc9ffb1af2251f35 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Sat, 20 Mar 2021 23:16:16 +0900
|
||||
Subject: [PATCH 2/2] pkey: use OSSL_DECODER to load encrypted PEM on OpenSSL
|
||||
3.0
|
||||
|
||||
OpenSSL 3.0 has rewritten routines to load pkeys (PEM_read_bio_* and
|
||||
d2i_* functions) around the newly introduced OSSL_DECODER API.
|
||||
|
||||
This comes with a slight behavior change. They now decrypt and parse
|
||||
each encountered PEM block, then check the kind of the block. This used
|
||||
to be the reverse: they checked the PEM header to see the kind, and then
|
||||
decrypted the content. This means that the password callback may now be
|
||||
called repeatedly.
|
||||
|
||||
Let's use the OSSL_DECODER API directly on OpenSSL 3.0 so that the
|
||||
return value from the password callback will be reused automatically.
|
||||
---
|
||||
ext/openssl/ossl_pkey.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 40 insertions(+)
|
||||
|
||||
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
|
||||
index f9f5162e..b08168a5 100644
|
||||
--- a/ext/openssl/ossl_pkey.c
|
||||
+++ b/ext/openssl/ossl_pkey.c
|
||||
@@ -78,6 +78,45 @@ ossl_pkey_new(EVP_PKEY *pkey)
|
||||
return obj;
|
||||
}
|
||||
|
||||
+#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
||||
+# include <openssl/decoder.h>
|
||||
+
|
||||
+EVP_PKEY *
|
||||
+ossl_pkey_read_generic(BIO *bio, VALUE pass)
|
||||
+{
|
||||
+ void *ppass = (void *)pass;
|
||||
+ OSSL_DECODER_CTX *dctx;
|
||||
+ EVP_PKEY *pkey = NULL;
|
||||
+ int pos = 0, pos2;
|
||||
+
|
||||
+ dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "DER", NULL, NULL, 0, NULL, NULL);
|
||||
+ if (!dctx)
|
||||
+ goto out;
|
||||
+ if (OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb, ppass) != 1)
|
||||
+ goto out;
|
||||
+
|
||||
+ /* First check DER */
|
||||
+ if (OSSL_DECODER_from_bio(dctx, bio) == 1)
|
||||
+ goto out;
|
||||
+
|
||||
+ /* Then check PEM; multiple OSSL_DECODER_from_bio() calls may be needed */
|
||||
+ OSSL_BIO_reset(bio);
|
||||
+ if (OSSL_DECODER_CTX_set_input_type(dctx, "PEM") != 1)
|
||||
+ goto out;
|
||||
+ while (OSSL_DECODER_from_bio(dctx, bio) != 1) {
|
||||
+ if (BIO_eof(bio))
|
||||
+ goto out;
|
||||
+ pos2 = BIO_tell(bio);
|
||||
+ if (pos2 < 0 || pos2 <= pos)
|
||||
+ goto out;
|
||||
+ pos = pos2;
|
||||
+ }
|
||||
+
|
||||
+ out:
|
||||
+ OSSL_DECODER_CTX_free(dctx);
|
||||
+ return pkey;
|
||||
+}
|
||||
+#else
|
||||
EVP_PKEY *
|
||||
ossl_pkey_read_generic(BIO *bio, VALUE pass)
|
||||
{
|
||||
@@ -106,6 +145,7 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
|
||||
out:
|
||||
return pkey;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* call-seq:
|
@ -974,7 +974,7 @@ index 693e55cd97..b3c6647faf 100644
|
||||
-have_func("BN_GENCB_get_arg")
|
||||
have_func("EVP_MD_CTX_new")
|
||||
have_func("EVP_MD_CTX_free")
|
||||
have_func("HMAC_CTX_new")
|
||||
have_func("EVP_MD_CTX_pkey_ctx")
|
||||
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
|
||||
index 7d218f86f5..e575415f49 100644
|
||||
--- a/ext/openssl/openssl_missing.h
|
||||
|
71
ruby.spec
71
ruby.spec
@ -22,7 +22,7 @@
|
||||
%endif
|
||||
|
||||
|
||||
%global release 158
|
||||
%global release 159
|
||||
%{!?release_string:%define release_string %{?development_release:0.}%{release}%{?development_release:.%{development_release}}%{?dist}}
|
||||
|
||||
# The RubyGems library has to stay out of Ruby directory tree, since the
|
||||
@ -173,6 +173,9 @@ Patch21: ruby-3.1.0-Properly-exclude-test-cases.patch
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2027099
|
||||
# https://github.com/rubygems/rubygems/pull/5154
|
||||
Patch22: rubygems-3.2.33-Fix-loading-operating_system-rb-customizations-too-late.patch
|
||||
# Fix segfault in `TestArray#test_sample` on s390x.
|
||||
# https://github.com/ruby/ruby/pull/5239
|
||||
Patch23: ruby-3.1.0-Fix-stack-buffer-overflow.patch
|
||||
|
||||
|
||||
# OpenSSL 3.0 compatibility patches
|
||||
@ -193,47 +196,63 @@ Patch40: ruby-3.1.0-Refactor-PEM-DER-serialization-code.patch
|
||||
# Implement more 'generic' operations using the EVP API.
|
||||
# https://github.com/ruby/openssl/pull/329
|
||||
Patch41: ruby-3.1.0-Add-more-support-for-generic-pkey-types.patch
|
||||
# Migrate from the low-level HMAC API to the EVP API.
|
||||
# https://github.com/ruby/openssl/pull/371
|
||||
Patch42: ruby-3.1.0-Migrate-from-the-low-level-HMAC-API-to-the-EVP-API.patch
|
||||
# Allow setting algorithm-specific options in #sign and #verify.
|
||||
# https://github.com/ruby/openssl/pull/374
|
||||
Patch42: ruby-3.1.0-Allow-setting-algorithm-specific-options-in-sign-and-verify.patch
|
||||
Patch43: ruby-3.1.0-Allow-setting-algorithm-specific-options-in-sign-and-verify.patch
|
||||
# Use high level EVP interface to generate parameters and keys.
|
||||
# https://github.com/ruby/openssl/pull/397
|
||||
Patch43: ruby-3.1.0-Use-high-level-EVP-interface-to-generate-parameters-and-keys.patch
|
||||
Patch44: ruby-3.1.0-Use-high-level-EVP-interface-to-generate-parameters-and-keys.patch
|
||||
# Use EVP API in more places.
|
||||
# https://github.com/ruby/openssl/pull/436
|
||||
Patch44: ruby-3.1.0-Use-EVP-API-in-more-places.patch
|
||||
Patch45: ruby-3.1.0-Use-EVP-API-in-more-places.patch
|
||||
# Implement PKey#{encrypt,decrypt,sign_raw,verify_{raw,verify_recover}}.
|
||||
# https://github.com/ruby/openssl/pull/382
|
||||
Patch45: ruby-3.1.0-Implement-PKey-encrypt-decrypt-sign_raw-verify_raw-and-verify_recover.patch
|
||||
Patch46: ruby-3.1.0-Implement-PKey-encrypt-decrypt-sign_raw-verify_raw-and-verify_recover.patch
|
||||
# Fix `OpenSSL::TestSSL#test_dup` test failure.
|
||||
# https://github.com/ruby/openssl/commit/7b66eaa2dbabb6570dbbbdfac24c4dcdcc6793d7
|
||||
Patch46: ruby-3.1.0-test-openssl-utils-remove-dup_public-helper-method.patch
|
||||
Patch47: ruby-3.1.0-test-openssl-utils-remove-dup_public-helper-method.patch
|
||||
# Fix `OpenSSL::TestDigest#test_digest_constants` test case.
|
||||
# https://github.com/ruby/openssl/commit/a3e59f4c2e200c76ef1d93945ff8737a05715e17
|
||||
Patch47: ruby-3.1.0-test-openssl-test_digest-do-not-test-constants-for-l.patch
|
||||
Patch48: ruby-3.1.0-test-openssl-test_digest-do-not-test-constants-for-l.patch
|
||||
# Fix `OpenSSL::TestSSL#test_connect_certificate_verify_failed_exception_message`
|
||||
# test case.
|
||||
# https://github.com/ruby/openssl/commit/b5a0a198505452c7457b192da2e5cd5dda04f23d
|
||||
Patch48: ruby-3.1.0-test-openssl-test_ssl-relax-regex-to-match-OpenSSL-s.patch
|
||||
Patch49: ruby-3.1.0-test-openssl-test_ssl-relax-regex-to-match-OpenSSL-s.patch
|
||||
# Fix `OpenSSL::TestPKCS12#test_{new_with_no_keys,new_with_one_key_and_one_cert}`
|
||||
# test failures.
|
||||
# https://github.com/ruby/openssl/commit/998406d18f2acf73090e9fd9d92a7b4227ac593b
|
||||
Patch49: ruby-3.1.0-test-openssl-test_pkcs12-fix-test-failures-with-Open.patch
|
||||
Patch50: ruby-3.1.0-test-openssl-test_pkcs12-fix-test-failures-with-Open.patch
|
||||
# Fix `OpenSSL::TestPKey#test_s_generate_key` test case.
|
||||
# https://github.com/ruby/openssl/commit/c732387ee5aaa8c5a9717e8b3ffebb3d7430e99a
|
||||
Patch50: ruby-3.1.0-test-openssl-test_pkey-use-EC-keys-for-PKey.generate.patch
|
||||
Patch51: ruby-3.1.0-test-openssl-test_pkey-use-EC-keys-for-PKey.generate.patch
|
||||
# Miscellaneous changes for OpenSSL 3.0 support.
|
||||
# https://github.com/ruby/openssl/pull/468
|
||||
Patch51: ruby-3.1.0-Miscellaneous-changes-for-OpenSSL-3.0-support.patch
|
||||
# Support OpenSSL 3.0.
|
||||
# https://github.com/ruby/openssl/pull/399
|
||||
Patch52: ruby-3.1.0-Support-OpenSSL-3.0.patch
|
||||
Patch52: ruby-3.1.0-Miscellaneous-changes-for-OpenSSL-3.0-support.patch
|
||||
# Use OSSL_DECODER to load encrypted PEM.
|
||||
# https://github.com/ruby/openssl/pull/479
|
||||
Patch53: ruby-3.1.0-Use-OSSL_DECODER-to-load-encrypted-PEM-on-OpenSSL-3.0.patch
|
||||
# Allocate EVP_PKEY on #initialize.
|
||||
# https://github.com/ruby/openssl/pull/478
|
||||
Patch54: ruby-3.1.0-Allocate-EVP_PKEY-on-initialize.patch
|
||||
# Disable `OpenSSL::TestPKeyRSA#test_no_private_exp` test case which is not
|
||||
# compatible with OpenSSL 3.0.
|
||||
# https://github.com/ruby/ruby/commit/47975ece4096cdab16b3f200f93ea2377dfb41ac
|
||||
Patch55: ruby-3.1.0-Disable-test_no_private_exp-on-OpenSSL-3.0.patch
|
||||
# Deprecate PKey::*#set_* and PKey::{DH,EC}#generate_key!
|
||||
# https://github.com/ruby/openssl/pull/480
|
||||
Patch56: ruby-3.1.0-Deprecate-PKey-set_-and-PKey-DH-EC-generate_key.patch
|
||||
# Fix `OpenSSL::PKey::PKeyError: pkeys are immutable on OpenSSL 3.0` errors.
|
||||
# https://github.com/rubygems/rubygems/pull/5196
|
||||
Patch57: rubygems-3.3.1-Fix-compatibility-with-OpenSSL3.0.patch
|
||||
# Miscellaneous changes for OpenSSL 3.0 support.
|
||||
# https://github.com/ruby/openssl/pull/481
|
||||
Patch58: ruby-3.1.0-Miscellaneous-changes-for-OpenSSL-3.0-support-part-2.patch
|
||||
# Fix `TestPumaControlCli#test_control_ssl` testcase in Puma.
|
||||
# https://github.com/ruby/openssl/pull/399#issuecomment-966239736
|
||||
Patch53: ruby-3.1.0-SSL_read-EOF-handling.patch
|
||||
# Fix segfault in `TestArray#test_sample` on s390x.
|
||||
# https://github.com/ruby/ruby/pull/5239
|
||||
Patch54: ruby-3.1.0-Fix-stack-buffer-overflow.patch
|
||||
Patch59: ruby-3.1.0-SSL_read-EOF-handling.patch
|
||||
|
||||
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
|
||||
Suggests: rubypick
|
||||
@ -685,6 +704,7 @@ rm -rf ext/fiddle/libffi*
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
%patch23 -p1
|
||||
%patch30 -p1 -R
|
||||
%patch31 -p1
|
||||
%patch40 -p1
|
||||
@ -702,6 +722,11 @@ rm -rf ext/fiddle/libffi*
|
||||
%patch52 -p1
|
||||
%patch53 -p1
|
||||
%patch54 -p1
|
||||
%patch55 -p1
|
||||
%patch56 -p1
|
||||
%patch57 -p1
|
||||
%patch58 -p1
|
||||
%patch59 -p1
|
||||
|
||||
# Provide an example of usage of the tapset:
|
||||
cp -a %{SOURCE3} .
|
||||
@ -980,13 +1005,6 @@ MSPECOPTS=""
|
||||
# Avoid `hostname' dependency.
|
||||
%{!?with_hostname:MSPECOPTS="-P 'Socket.gethostname returns the host name'"}
|
||||
|
||||
# Some tests are failing upstream due to OpenSSL 3.x compatibility.
|
||||
# https://github.com/ruby/openssl/pull/399/checks?check_run_id=3716152870
|
||||
DISABLE_TESTS="$DISABLE_TESTS -n !/OpenSSL::TestEC#test_check_key/"
|
||||
DISABLE_TESTS="$DISABLE_TESTS -n !/OpenSSL::TestPKeyDH#test_derive_key/"
|
||||
DISABLE_TESTS="$DISABLE_TESTS -n !/OpenSSL::TestPKeyDH#test_key_exchange/"
|
||||
DISABLE_TESTS="$DISABLE_TESTS -n !/OpenSSL::TestCipher#test_ciphers/"
|
||||
|
||||
# Several test broken by libffi-3.4.2. There should be fix in libffi, once
|
||||
# other components are fixed.
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2040380
|
||||
@ -1469,6 +1487,9 @@ mv test/fiddle/test_import.rb{,.disable}
|
||||
|
||||
|
||||
%changelog
|
||||
* Tue Jan 25 2022 Vít Ondruch <vondruch@redhat.com> - 3.0.3-158
|
||||
- Update OpenSSL 3 compatibility patches.
|
||||
|
||||
* Thu Jan 20 2022 Vít Ondruch <vondruch@redhat.com> - 3.0.3-158
|
||||
- Disable package notes to prevent rubygem- build breakage.
|
||||
|
||||
|
@ -92,10 +92,9 @@ even fully sure it was the right thing to do when I added that, and it
|
||||
was not the culprit of the end user issue that led to making that
|
||||
change.
|
||||
---
|
||||
.github/workflows/install-rubygems.yml | 5 ----
|
||||
lib/rubygems.rb | 32 +++++++++++++-------------
|
||||
test/rubygems/test_rubygems.rb | 23 ++++++++++++++++++
|
||||
3 files changed, 39 insertions(+), 21 deletions(-)
|
||||
lib/rubygems.rb | 32 ++++++++++++++++----------------
|
||||
test/rubygems/test_rubygems.rb | 23 +++++++++++++++++++++++
|
||||
2 files changed, 39 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
|
||||
index b8747409304..11474b6554c 100644
|
||||
@ -189,8 +188,8 @@ Otherwise first OS customizations load and activate that fiddle version,
|
||||
but then when we change to `Gem.default_dir`, that fiddle version is no
|
||||
longer there.
|
||||
---
|
||||
bundler/spec/commands/clean_spec.rb | 2 +-
|
||||
bundler/spec/install/gems/standalone_spec.rb | 2 +-
|
||||
spec/bundler/commands/clean_spec.rb | 2 +-
|
||||
spec/bundler/install/gems/standalone_spec.rb | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb
|
||||
|
105
rubygems-3.3.1-Fix-compatibility-with-OpenSSL3.0.patch
Normal file
105
rubygems-3.3.1-Fix-compatibility-with-OpenSSL3.0.patch
Normal file
@ -0,0 +1,105 @@
|
||||
From 558128594de16add5b453833fd5b043a24c1b7f5 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Wed, 22 Dec 2021 01:38:47 +0900
|
||||
Subject: [PATCH 1/3] Use OpenSSL::PKey::EC.generate to generate ECC key pairs
|
||||
|
||||
When Ruby/OpenSSL is built against OpenSSL 3.0, OpenSSL::PKey::PKey
|
||||
instances are immutable and OpenSSL::PKey::EC#generate_key cannot work
|
||||
because it modifies the receiver.
|
||||
|
||||
OpenSSL::PKey::EC.generate is available on Ruby 2.4 (Ruby/OpenSSL 2.0)
|
||||
or later.
|
||||
---
|
||||
lib/rubygems/security.rb | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb
|
||||
index 22759972070..2aa07381d69 100644
|
||||
--- a/lib/rubygems/security.rb
|
||||
+++ b/lib/rubygems/security.rb
|
||||
@@ -490,9 +490,13 @@ def self.create_key(algorithm)
|
||||
when 'rsa'
|
||||
OpenSSL::PKey::RSA.new(RSA_DSA_KEY_LENGTH)
|
||||
when 'ec'
|
||||
- domain_key = OpenSSL::PKey::EC.new(EC_NAME)
|
||||
- domain_key.generate_key
|
||||
- domain_key
|
||||
+ if RUBY_VERSION >= "2.4.0"
|
||||
+ OpenSSL::PKey::EC.generate(EC_NAME)
|
||||
+ else
|
||||
+ domain_key = OpenSSL::PKey::EC.new(EC_NAME)
|
||||
+ domain_key.generate_key
|
||||
+ domain_key
|
||||
+ end
|
||||
else
|
||||
raise Gem::Security::Exception,
|
||||
"#{algorithm} algorithm not found. RSA, DSA, and EC algorithms are supported."
|
||||
|
||||
From 60067d4f09b7fb9c23bed38e91acfde0293f29a0 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Wed, 22 Dec 2021 01:49:05 +0900
|
||||
Subject: [PATCH 2/3] Use OpenSSL::X509::Certificate#check_private_key
|
||||
|
||||
The method is for the exact purpose: to check that an instance of
|
||||
OpenSSL::PKey::PKey matches the public key in a certificate.
|
||||
---
|
||||
lib/rubygems/security.rb | 2 +-
|
||||
lib/rubygems/security/policy.rb | 4 +---
|
||||
2 files changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb
|
||||
index 2aa07381d69..2906819bd34 100644
|
||||
--- a/lib/rubygems/security.rb
|
||||
+++ b/lib/rubygems/security.rb
|
||||
@@ -530,7 +530,7 @@ def self.re_sign(expired_certificate, private_key, age = ONE_YEAR,
|
||||
raise Gem::Security::Exception,
|
||||
"incorrect signing key for re-signing " +
|
||||
"#{expired_certificate.subject}" unless
|
||||
- expired_certificate.public_key.to_pem == get_public_key(private_key).to_pem
|
||||
+ expired_certificate.check_private_key(private_key)
|
||||
|
||||
unless expired_certificate.subject.to_s ==
|
||||
expired_certificate.issuer.to_s
|
||||
diff --git a/lib/rubygems/security/policy.rb b/lib/rubygems/security/policy.rb
|
||||
index 3c3cb647ee3..06eae073f4a 100644
|
||||
--- a/lib/rubygems/security/policy.rb
|
||||
+++ b/lib/rubygems/security/policy.rb
|
||||
@@ -115,11 +115,9 @@ def check_key(signer, key)
|
||||
raise Gem::Security::Exception, 'missing key or signature'
|
||||
end
|
||||
|
||||
- public_key = Gem::Security.get_public_key(key)
|
||||
-
|
||||
raise Gem::Security::Exception,
|
||||
"certificate #{signer.subject} does not match the signing key" unless
|
||||
- signer.public_key.to_pem == public_key.to_pem
|
||||
+ signer.check_private_key(key)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
From 6819e3d0fadc10ce8d10919402eedb730cf0e43f Mon Sep 17 00:00:00 2001
|
||||
From: Kazuki Yamaguchi <k@rhe.jp>
|
||||
Date: Wed, 22 Dec 2021 01:54:10 +0900
|
||||
Subject: [PATCH 3/3] Fix Gem::Security.get_public_key on OpenSSL 3.0
|
||||
|
||||
Ruby/OpenSSL 2.2 added OpenSSL::PKey::PKey#public_to_der for serializing
|
||||
only the public key components contained in the instance. This works
|
||||
for all possible key types.
|
||||
---
|
||||
lib/rubygems/security.rb | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb
|
||||
index 2906819bd34..f21c1756422 100644
|
||||
--- a/lib/rubygems/security.rb
|
||||
+++ b/lib/rubygems/security.rb
|
||||
@@ -424,6 +424,8 @@ def self.create_cert(subject, key, age = ONE_YEAR, extensions = EXTENSIONS,
|
||||
# Gets the right public key from a PKey instance
|
||||
|
||||
def self.get_public_key(key)
|
||||
+ # Ruby 3.0 (Ruby/OpenSSL 2.2) or later
|
||||
+ return OpenSSL::PKey.read(key.public_to_der) if key.respond_to?(:public_to_der)
|
||||
return key.public_key unless key.is_a?(OpenSSL::PKey::EC)
|
||||
|
||||
ec_key = OpenSSL::PKey::EC.new(key.group.curve_name)
|
Loading…
Reference in New Issue
Block a user