From 46ca47060ca8ef3419ec36c2326a81b442d9b43b Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi 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 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 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. # + # Deprecated in version 3.0. 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 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 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