From 717fe3f3fee8ecd866d9626ab1d1abd7e4dccb3e Mon Sep 17 00:00:00 2001 From: Bart de Water Date: Mon, 18 May 2020 10:36:12 -0400 Subject: [PATCH 01/18] Add private?/public? methods and Marshal support to OpenSSL::PKey::PKey --- ext/openssl/ossl_pkey.c | 40 +++++++++++++++++++++++++++++++++++++++ lib/openssl/pkey.rb | 14 ++++++++++++++ test/openssl/test_pkey.rb | 14 ++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index df8b425a0..5d66298b8 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -568,6 +568,25 @@ ossl_pkey_inspect(VALUE self) OBJ_nid2sn(nid)); } +/* + * call-seq: + * key.private? => true or false + * + * Returns whether this PKey instance has a private key. The private key can + * be retrieved with PKey#private_to_{der,pem,raw}. + */ +static VALUE ossl_pkey_is_private(VALUE self) +{ + EVP_PKEY *pkey; + size_t len; + + GetPKey(self, pkey); + len = EVP_PKEY_size(pkey); + unsigned char str[len]; + + return EVP_PKEY_get_raw_private_key(pkey, str, &len) == 1 ? Qtrue : Qfalse; +} + VALUE ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, int to_der) { @@ -708,6 +727,25 @@ ossl_pkey_export_spki(VALUE self, int to_der) return ossl_membio2str(bio); } +/* + * call-seq: + * key.public? => true or false + * + * Returns whether this PKey instance has a public key. The public key can + * be retrieved with PKey#public_to_{der,pem,raw}. + */ +static VALUE ossl_pkey_is_public(VALUE self) +{ + EVP_PKEY *pkey; + size_t len; + + GetPKey(self, pkey); + len = EVP_PKEY_size(pkey); + unsigned char str[len]; + + return EVP_PKEY_get_raw_public_key(pkey, str, &len) == 1 ? Qtrue : Qfalse; +} + /* * call-seq: * pkey.public_to_der -> string @@ -1027,8 +1065,10 @@ Init_ossl_pkey(void) rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0); rb_define_method(cPKey, "oid", ossl_pkey_oid, 0); rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0); + rb_define_method(cPKey, "private?", ossl_pkey_is_private, 0); rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1); rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); + rb_define_method(cPKey, "public?", ossl_pkey_is_public, 0); rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0); diff --git a/lib/openssl/pkey.rb b/lib/openssl/pkey.rb index be60ac2be..201ac7a94 100644 --- a/lib/openssl/pkey.rb +++ b/lib/openssl/pkey.rb @@ -69,6 +69,20 @@ def to_bn(conversion_form = group.point_conversion_form) end end + class PKey + def self._load(string) + OpenSSL::PKey.read(string) + end + + def _dump(_level) + if private? + private_to_der + else + public_to_der + end + end + end + class RSA include OpenSSL::Marshal end diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb index 5307fe5b0..78bbb7dd5 100644 --- a/test/openssl/test_pkey.rb +++ b/test/openssl/test_pkey.rb @@ -103,8 +103,18 @@ def test_ed25519 assert_instance_of OpenSSL::PKey::PKey, priv assert_instance_of OpenSSL::PKey::PKey, pub assert_equal priv_pem, priv.private_to_pem + assert_equal true, priv.private? + assert_equal true, priv.public? + priv_deserialized = Marshal.load(Marshal.dump(priv)) + assert_equal priv.private_to_der, priv_deserialized.private_to_der + assert_equal pub_pem, priv.public_to_pem assert_equal pub_pem, pub.public_to_pem + assert_equal false, pub.private? + assert_equal true, pub.public? + pub_deserialized = Marshal.load(Marshal.dump(pub)) + assert_equal pub.public_to_der, pub_deserialized.public_to_der + sig = [<<~EOF.gsub(/[^0-9a-f]/, "")].pack("H*") 92a009a9f0d4cab8720e820b5f642540 @@ -150,5 +160,9 @@ def test_x25519 assert_equal alice_pem, alice.private_to_pem assert_equal bob_pem, bob.public_to_pem assert_equal [shared_secret].pack("H*"), alice.derive(bob) + alice_deserialized = Marshal.load(Marshal.dump(alice)) + assert_equal alice.private_to_der, alice_deserialized.private_to_der + bob_deserialized = Marshal.load(Marshal.dump(bob)) + assert_equal bob.public_to_der, bob_deserialized.public_to_der end end From 8f7467f2b67a706b7e9fb6ee0e69f1c755bbde35 Mon Sep 17 00:00:00 2001 From: Bart de Water Date: Wed, 20 May 2020 23:45:46 -0400 Subject: [PATCH 02/18] Add OpenSSL::PKey.private_new, #private_to_raw and public equivalents --- ext/openssl/ossl_pkey.c | 102 ++++++++++++++++++++++++++++++++++++++ test/openssl/test_pkey.rb | 25 ++++++++++ 2 files changed, 127 insertions(+) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 5d66298b8..3d15fbb06 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -532,6 +532,56 @@ ossl_pkey_initialize(VALUE self) return self; } +/* + * call-seq: + * OpenSSL::PKey.private_new(algo, string) -> PKey + * + * See the OpenSSL documentation for EVP_PKEY_new_raw_private_key() + */ + +static VALUE +ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) +{ + EVP_PKEY *pkey; + int nid; + size_t keylen; + + nid = OBJ_sn2nid(StringValueCStr(type)); + if(!nid) ossl_raise(ePKeyError, "unknown OID `%"PRIsVALUE"'", type); + + keylen = RSTRING_LEN(key); + pkey = EVP_PKEY_new_raw_private_key(nid, NULL, (unsigned char *)RSTRING_PTR(key), keylen); + if (!pkey) + ossl_raise(ePKeyError, "Could not parse PKey"); + + return ossl_pkey_new(pkey); +} + +/* + * call-seq: + * OpenSSL::PKey.public_new(algo, string) -> PKey + * + * See the OpenSSL documentation for EVP_PKEY_new_raw_public_key() + */ + +static VALUE +ossl_pkey_initialize_public(VALUE self, VALUE type, VALUE key) +{ + EVP_PKEY *pkey; + int nid; + size_t keylen; + + nid = OBJ_sn2nid(StringValueCStr(type)); + if(!nid) ossl_raise(ePKeyError, "unknown OID `%"PRIsVALUE"'", type); + + keylen = RSTRING_LEN(key); + pkey = EVP_PKEY_new_raw_public_key(nid, NULL, (unsigned char *)RSTRING_PTR(key), keylen); + if (!pkey) + ossl_raise(ePKeyError, "Could not parse PKey"); + + return ossl_pkey_new(pkey); +} + /* * call-seq: * pkey.oid -> string @@ -702,6 +752,30 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) return do_pkcs8_export(argc, argv, self, 0); } +/* + * call-seq: + * key.private_to_raw => string + * + * See the OpenSSL documentation for EVP_PKEY_get_raw_private_key() + */ +static VALUE ossl_pkey_private_to_raw(VALUE self) +{ + EVP_PKEY *pkey; + VALUE str; + size_t len; + + GetPKey(self, pkey); + EVP_PKEY_get_raw_private_key(pkey, NULL, &len); + str = rb_str_new(NULL, len); + + if (EVP_PKEY_get_raw_private_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1) + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key"); + + rb_str_set_len(str, len); + + return str; +} + VALUE ossl_pkey_export_spki(VALUE self, int to_der) { @@ -770,6 +844,30 @@ ossl_pkey_public_to_pem(VALUE self) return ossl_pkey_export_spki(self, 0); } +/* + * call-seq: + * key.public_to_raw => string + * + * See the OpenSSL documentation for EVP_PKEY_get_raw_public_key() + */ +static VALUE ossl_pkey_public_to_raw(VALUE self) +{ + EVP_PKEY *pkey; + VALUE str; + size_t len; + + GetPKey(self, pkey); + EVP_PKEY_get_raw_public_key(pkey, NULL, &len); + str = rb_str_new(NULL, len); + + if (EVP_PKEY_get_raw_public_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1) + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_public_key"); + + rb_str_set_len(str, len); + + return str; +} + /* * call-seq: * pkey.sign(digest, data) -> String @@ -1060,6 +1158,8 @@ Init_ossl_pkey(void) rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1); rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1); rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1); + rb_define_module_function(mPKey, "private_new", ossl_pkey_initialize_private, 2); + rb_define_module_function(mPKey, "public_new", ossl_pkey_initialize_public, 2); rb_define_alloc_func(cPKey, ossl_pkey_alloc); rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0); @@ -1068,9 +1168,11 @@ Init_ossl_pkey(void) rb_define_method(cPKey, "private?", ossl_pkey_is_private, 0); rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1); rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); + rb_define_method(cPKey, "private_to_raw", ossl_pkey_private_to_raw, 0); rb_define_method(cPKey, "public?", ossl_pkey_is_public, 0); rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0); + rb_define_method(cPKey, "public_to_raw", ossl_pkey_public_to_raw, 0); rb_define_method(cPKey, "sign", ossl_pkey_sign, 2); rb_define_method(cPKey, "verify", ossl_pkey_verify, 3); diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb index 78bbb7dd5..5a60e5e27 100644 --- a/test/openssl/test_pkey.rb +++ b/test/openssl/test_pkey.rb @@ -107,6 +107,10 @@ def test_ed25519 assert_equal true, priv.public? priv_deserialized = Marshal.load(Marshal.dump(priv)) assert_equal priv.private_to_der, priv_deserialized.private_to_der + assert_equal "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", + priv.private_to_raw.unpack1("H*") + assert_equal OpenSSL::PKey.private_new("ED25519", priv.private_to_raw).private_to_pem, + priv.private_to_pem assert_equal pub_pem, priv.public_to_pem assert_equal pub_pem, pub.public_to_pem @@ -114,6 +118,10 @@ def test_ed25519 assert_equal true, pub.public? pub_deserialized = Marshal.load(Marshal.dump(pub)) assert_equal pub.public_to_der, pub_deserialized.public_to_der + assert_equal "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", + priv.public_to_raw.unpack1("H*") + assert_equal OpenSSL::PKey.public_new("ED25519", priv.public_to_raw).public_to_pem, + pub.public_to_pem sig = [<<~EOF.gsub(/[^0-9a-f]/, "")].pack("H*") @@ -164,5 +172,22 @@ def test_x25519 assert_equal alice.private_to_der, alice_deserialized.private_to_der bob_deserialized = Marshal.load(Marshal.dump(bob)) assert_equal bob.public_to_der, bob_deserialized.public_to_der + assert_equal "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a", + alice.private_to_raw.unpack1("H*") + assert_equal OpenSSL::PKey.private_new("X25519", alice.private_to_raw).private_to_pem, + alice.private_to_pem + assert_equal "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f", + bob.public_to_raw.unpack1("H*") + assert_equal OpenSSL::PKey.public_new("X25519", bob.public_to_raw).public_to_pem, + bob.public_to_pem + end + + def raw_initialize + pend "Ed25519 is not implemented" unless OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10101000 && # >= v1.1.1 + + assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.private_new("foo123", "xxx") } + assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.private_new("ED25519", "xxx") } + assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.public_new("foo123", "xxx") } + assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.public_new("ED25519", "xxx") } end end From 7b599ca530972bab46359ec41f6bdc1b8164455d Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Sat, 1 Jul 2023 16:35:50 +0900 Subject: [PATCH 03/18] Temporarily remove private?/public? methods --- ext/openssl/ossl_pkey.c | 40 --------------------------------------- test/openssl/test_pkey.rb | 12 ------------ 2 files changed, 52 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 6a4c073bb..48e1f3f48 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -714,25 +714,6 @@ ossl_pkey_inspect(VALUE self) OBJ_nid2sn(nid)); } -/* - * call-seq: - * key.private? => true or false - * - * Returns whether this PKey instance has a private key. The private key can - * be retrieved with PKey#private_to_{der,pem,raw}. - */ -static VALUE ossl_pkey_is_private(VALUE self) -{ - EVP_PKEY *pkey; - size_t len; - - GetPKey(self, pkey); - len = EVP_PKEY_size(pkey); - unsigned char str[len]; - - return EVP_PKEY_get_raw_private_key(pkey, str, &len) == 1 ? Qtrue : Qfalse; -} - /* * call-seq: * pkey.to_text -> string @@ -934,25 +915,6 @@ ossl_pkey_export_spki(VALUE self, int to_der) return ossl_membio2str(bio); } -/* - * call-seq: - * key.public? => true or false - * - * Returns whether this PKey instance has a public key. The public key can - * be retrieved with PKey#public_to_{der,pem,raw}. - */ -static VALUE ossl_pkey_is_public(VALUE self) -{ - EVP_PKEY *pkey; - size_t len; - - GetPKey(self, pkey); - len = EVP_PKEY_size(pkey); - unsigned char str[len]; - - return EVP_PKEY_get_raw_public_key(pkey, str, &len) == 1 ? Qtrue : Qfalse; -} - /* * call-seq: * pkey.public_to_der -> string @@ -1751,12 +1713,10 @@ Init_ossl_pkey(void) #endif rb_define_method(cPKey, "oid", ossl_pkey_oid, 0); rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0); - rb_define_method(cPKey, "private?", ossl_pkey_is_private, 0); rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0); rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1); rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); rb_define_method(cPKey, "private_to_raw", ossl_pkey_private_to_raw, 0); - rb_define_method(cPKey, "public?", ossl_pkey_is_public, 0); rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0); rb_define_method(cPKey, "public_to_raw", ossl_pkey_public_to_raw, 0); diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb index 1bd35d4e5..29dbd35f8 100644 --- a/test/openssl/test_pkey.rb +++ b/test/openssl/test_pkey.rb @@ -106,10 +106,6 @@ def test_ed25519 assert_instance_of OpenSSL::PKey::PKey, priv assert_instance_of OpenSSL::PKey::PKey, pub assert_equal priv_pem, priv.private_to_pem - assert_equal true, priv.private? - assert_equal true, priv.public? - priv_deserialized = Marshal.load(Marshal.dump(priv)) - assert_equal priv.private_to_der, priv_deserialized.private_to_der assert_equal "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", priv.private_to_raw.unpack1("H*") assert_equal OpenSSL::PKey.private_new("ED25519", priv.private_to_raw).private_to_pem, @@ -117,10 +113,6 @@ def test_ed25519 assert_equal pub_pem, priv.public_to_pem assert_equal pub_pem, pub.public_to_pem - assert_equal false, pub.private? - assert_equal true, pub.public? - pub_deserialized = Marshal.load(Marshal.dump(pub)) - assert_equal pub.public_to_der, pub_deserialized.public_to_der assert_equal "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", priv.public_to_raw.unpack1("H*") assert_equal OpenSSL::PKey.public_new("ED25519", priv.public_to_raw).public_to_pem, @@ -173,10 +165,6 @@ def test_x25519 assert_equal alice_pem, alice.private_to_pem assert_equal bob_pem, bob.public_to_pem assert_equal [shared_secret].pack("H*"), alice.derive(bob) - alice_deserialized = Marshal.load(Marshal.dump(alice)) - assert_equal alice.private_to_der, alice_deserialized.private_to_der - bob_deserialized = Marshal.load(Marshal.dump(bob)) - assert_equal bob.public_to_der, bob_deserialized.public_to_der assert_equal "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a", alice.private_to_raw.unpack1("H*") assert_equal OpenSSL::PKey.private_new("X25519", alice.private_to_raw).private_to_pem, From 4e1da3d928b03d13162517fc233b89c44e146554 Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Sat, 1 Jul 2023 16:37:09 +0900 Subject: [PATCH 04/18] Temporarily remove dumping --- lib/openssl/pkey.rb | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/openssl/pkey.rb b/lib/openssl/pkey.rb index a33061785..8463c9e5f 100644 --- a/lib/openssl/pkey.rb +++ b/lib/openssl/pkey.rb @@ -314,14 +314,6 @@ class PKey def self._load(string) OpenSSL::PKey.read(string) end - - def _dump(_level) - if private? - private_to_der - else - public_to_der - end - end end class RSA From 8e89a27a5ae5e67862ffbb51167b748b402dceb0 Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Thu, 29 Jun 2023 20:51:56 +0900 Subject: [PATCH 05/18] Rewrite OBJ_sn2nid() using EVP_PKEY_asn1_find_str() --- ext/openssl/ossl_pkey.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 48e1f3f48..58a331661 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -639,14 +639,18 @@ static VALUE ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) { EVP_PKEY *pkey; - int nid; + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id; size_t keylen; - nid = OBJ_sn2nid(StringValueCStr(type)); - if(!nid) ossl_raise(ePKeyError, "unknown OID `%"PRIsVALUE"'", type); + StringValue(type); + ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); + if (!ameth) + ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type); + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); keylen = RSTRING_LEN(key); - pkey = EVP_PKEY_new_raw_private_key(nid, NULL, (unsigned char *)RSTRING_PTR(key), keylen); + pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); if (!pkey) ossl_raise(ePKeyError, "Could not parse PKey"); @@ -664,14 +668,18 @@ static VALUE ossl_pkey_initialize_public(VALUE self, VALUE type, VALUE key) { EVP_PKEY *pkey; - int nid; + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id; size_t keylen; - nid = OBJ_sn2nid(StringValueCStr(type)); - if(!nid) ossl_raise(ePKeyError, "unknown OID `%"PRIsVALUE"'", type); + StringValue(type); + ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); + if (!ameth) + ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type); + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); keylen = RSTRING_LEN(key); - pkey = EVP_PKEY_new_raw_public_key(nid, NULL, (unsigned char *)RSTRING_PTR(key), keylen); + pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); if (!pkey) ossl_raise(ePKeyError, "Could not parse PKey"); From 46d4fc780fb12cda2308be1fc9c2ac22b56b6004 Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Sat, 1 Jul 2023 16:38:11 +0900 Subject: [PATCH 06/18] Check if running OpenSSL's EVP has raw private key support --- ext/openssl/ossl_pkey.c | 23 +++++++++++++++++++++-- test/openssl/test_pkey.rb | 21 +++++++++++++++------ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 58a331661..98464fa3a 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -638,11 +638,16 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other) static VALUE ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) { + EVP_PKEY *pkey; const EVP_PKEY_ASN1_METHOD *ameth; int pkey_id; size_t keylen; +#ifndef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key is not implemented"); +#endif + StringValue(type); ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); if (!ameth) @@ -650,10 +655,11 @@ ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); keylen = RSTRING_LEN(key); + pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); if (!pkey) ossl_raise(ePKeyError, "Could not parse PKey"); - + return ossl_pkey_new(pkey); } @@ -672,6 +678,10 @@ ossl_pkey_initialize_public(VALUE self, VALUE type, VALUE key) int pkey_id; size_t keylen; +#ifndef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key is not implemented"); +#endif + StringValue(type); ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); if (!ameth) @@ -679,10 +689,11 @@ ossl_pkey_initialize_public(VALUE self, VALUE type, VALUE key) EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); keylen = RSTRING_LEN(key); + pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); if (!pkey) ossl_raise(ePKeyError, "Could not parse PKey"); - + return ossl_pkey_new(pkey); } @@ -886,6 +897,10 @@ static VALUE ossl_pkey_private_to_raw(VALUE self) VALUE str; size_t len; +#ifndef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key is not implemented"); +#endif + GetPKey(self, pkey); EVP_PKEY_get_raw_private_key(pkey, NULL, &len); str = rb_str_new(NULL, len); @@ -959,6 +974,10 @@ static VALUE ossl_pkey_public_to_raw(VALUE self) VALUE str; size_t len; +#ifndef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key is not implemented"); +#endif + GetPKey(self, pkey); EVP_PKEY_get_raw_public_key(pkey, NULL, &len); str = rb_str_new(NULL, len); diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb index 29dbd35f8..32ba49c62 100644 --- a/test/openssl/test_pkey.rb +++ b/test/openssl/test_pkey.rb @@ -165,14 +165,23 @@ def test_x25519 assert_equal alice_pem, alice.private_to_pem assert_equal bob_pem, bob.public_to_pem assert_equal [shared_secret].pack("H*"), alice.derive(bob) - assert_equal "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a", - alice.private_to_raw.unpack1("H*") - assert_equal OpenSSL::PKey.private_new("X25519", alice.private_to_raw).private_to_pem, + begin + alice_private = OpenSSL::PKey.private_new("X25519", alice.private_to_raw) + bob_public = OpenSSL::PKey.public_new("X25519", bob.public_to_raw) + alice_private_raw = alice.private_to_raw.unpack1("H*") + bob_public_raw = bob.public_to_raw.unpack1("H*") + rescue OpenSSL::PKey::PKeyError + # OpenSSL < 1.1.1 + pend "EVP_PKEY_new_raw_private_key is not implemented" + end + assert_equal alice_private.private_to_pem, alice.private_to_pem - assert_equal "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f", - bob.public_to_raw.unpack1("H*") - assert_equal OpenSSL::PKey.public_new("X25519", bob.public_to_raw).public_to_pem, + assert_equal bob_public.public_to_pem, bob.public_to_pem + assert_equal "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a", + alice_private_raw + assert_equal "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f", + bob_public_raw end def raw_initialize From 80e9ef1a188bf8d712c976e622b165d330998b5c Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Sat, 1 Jul 2023 21:00:18 +0900 Subject: [PATCH 07/18] Remove method definition when OpenSSL does not support raw pkeys --- ext/openssl/ossl_pkey.c | 32 ++++++++++++++++---------------- test/openssl/test_pkey.rb | 25 ++++++++++++++----------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 98464fa3a..f310fa87c 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -635,6 +635,7 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other) * See the OpenSSL documentation for EVP_PKEY_new_raw_private_key() */ +#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY static VALUE ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) { @@ -644,10 +645,6 @@ ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) int pkey_id; size_t keylen; -#ifndef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY - ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key is not implemented"); -#endif - StringValue(type); ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); if (!ameth) @@ -662,6 +659,7 @@ ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) return ossl_pkey_new(pkey); } +#endif /* * call-seq: @@ -670,6 +668,7 @@ ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) * See the OpenSSL documentation for EVP_PKEY_new_raw_public_key() */ +#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY static VALUE ossl_pkey_initialize_public(VALUE self, VALUE type, VALUE key) { @@ -678,10 +677,6 @@ ossl_pkey_initialize_public(VALUE self, VALUE type, VALUE key) int pkey_id; size_t keylen; -#ifndef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY - ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key is not implemented"); -#endif - StringValue(type); ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); if (!ameth) @@ -696,6 +691,7 @@ ossl_pkey_initialize_public(VALUE self, VALUE type, VALUE key) return ossl_pkey_new(pkey); } +#endif /* * call-seq: @@ -891,16 +887,14 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) * * See the OpenSSL documentation for EVP_PKEY_get_raw_private_key() */ + +#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY static VALUE ossl_pkey_private_to_raw(VALUE self) { EVP_PKEY *pkey; VALUE str; size_t len; -#ifndef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY - ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key is not implemented"); -#endif - GetPKey(self, pkey); EVP_PKEY_get_raw_private_key(pkey, NULL, &len); str = rb_str_new(NULL, len); @@ -912,6 +906,7 @@ static VALUE ossl_pkey_private_to_raw(VALUE self) return str; } +#endif VALUE ossl_pkey_export_spki(VALUE self, int to_der) @@ -968,16 +963,14 @@ ossl_pkey_public_to_pem(VALUE self) * * See the OpenSSL documentation for EVP_PKEY_get_raw_public_key() */ + +#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY static VALUE ossl_pkey_public_to_raw(VALUE self) { EVP_PKEY *pkey; VALUE str; size_t len; -#ifndef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY - ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key is not implemented"); -#endif - GetPKey(self, pkey); EVP_PKEY_get_raw_public_key(pkey, NULL, &len); str = rb_str_new(NULL, len); @@ -989,6 +982,7 @@ static VALUE ossl_pkey_public_to_raw(VALUE self) return str; } +#endif /* * call-seq: @@ -1728,8 +1722,10 @@ Init_ossl_pkey(void) rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1); rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1); rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1); +#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY rb_define_module_function(mPKey, "private_new", ossl_pkey_initialize_private, 2); rb_define_module_function(mPKey, "public_new", ossl_pkey_initialize_public, 2); +#endif rb_define_alloc_func(cPKey, ossl_pkey_alloc); rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0); @@ -1743,10 +1739,14 @@ Init_ossl_pkey(void) rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0); rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1); rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); +#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY rb_define_method(cPKey, "private_to_raw", ossl_pkey_private_to_raw, 0); +#endif rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0); +#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY rb_define_method(cPKey, "public_to_raw", ossl_pkey_public_to_raw, 0); +#endif rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1); rb_define_method(cPKey, "sign", ossl_pkey_sign, -1); diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb index 32ba49c62..d7f10ee5c 100644 --- a/test/openssl/test_pkey.rb +++ b/test/openssl/test_pkey.rb @@ -106,18 +106,21 @@ def test_ed25519 assert_instance_of OpenSSL::PKey::PKey, priv assert_instance_of OpenSSL::PKey::PKey, pub assert_equal priv_pem, priv.private_to_pem - assert_equal "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", - priv.private_to_raw.unpack1("H*") - assert_equal OpenSSL::PKey.private_new("ED25519", priv.private_to_raw).private_to_pem, - priv.private_to_pem - assert_equal pub_pem, priv.public_to_pem assert_equal pub_pem, pub.public_to_pem - assert_equal "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", - priv.public_to_raw.unpack1("H*") - assert_equal OpenSSL::PKey.public_new("ED25519", priv.public_to_raw).public_to_pem, - pub.public_to_pem + begin + assert_equal "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", + priv.private_to_raw.unpack1("H*") + assert_equal OpenSSL::PKey.private_new("ED25519", priv.private_to_raw).private_to_pem, + priv.private_to_pem + assert_equal "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", + priv.public_to_raw.unpack1("H*") + assert_equal OpenSSL::PKey.public_new("ED25519", priv.public_to_raw).public_to_pem, + pub.public_to_pem + rescue NoMethodError + pend "running OpenSSL version does not have raw public key support" + end sig = [<<~EOF.gsub(/[^0-9a-f]/, "")].pack("H*") 92a009a9f0d4cab8720e820b5f642540 @@ -170,9 +173,9 @@ def test_x25519 bob_public = OpenSSL::PKey.public_new("X25519", bob.public_to_raw) alice_private_raw = alice.private_to_raw.unpack1("H*") bob_public_raw = bob.public_to_raw.unpack1("H*") - rescue OpenSSL::PKey::PKeyError + rescue NoMethodError # OpenSSL < 1.1.1 - pend "EVP_PKEY_new_raw_private_key is not implemented" + pend "running OpenSSL version does not have raw public key support" end assert_equal alice_private.private_to_pem, alice.private_to_pem From 202cac7992f3d935b4e37cd846d02774dfbea52e Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Fri, 7 Jul 2023 14:33:42 +0900 Subject: [PATCH 08/18] Move #ifdev above doc comment --- ext/openssl/ossl_pkey.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index f310fa87c..ea5594190 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -628,6 +628,7 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other) } #endif +#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY /* * call-seq: * OpenSSL::PKey.private_new(algo, string) -> PKey @@ -635,7 +636,6 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other) * See the OpenSSL documentation for EVP_PKEY_new_raw_private_key() */ -#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY static VALUE ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) { @@ -661,6 +661,7 @@ ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) } #endif +#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY /* * call-seq: * OpenSSL::PKey.public_new(algo, string) -> PKey @@ -668,7 +669,6 @@ ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) * See the OpenSSL documentation for EVP_PKEY_new_raw_public_key() */ -#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY static VALUE ossl_pkey_initialize_public(VALUE self, VALUE type, VALUE key) { @@ -881,6 +881,7 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) return do_pkcs8_export(argc, argv, self, 0); } +#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY /* * call-seq: * key.private_to_raw => string @@ -888,7 +889,6 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) * See the OpenSSL documentation for EVP_PKEY_get_raw_private_key() */ -#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY static VALUE ossl_pkey_private_to_raw(VALUE self) { EVP_PKEY *pkey; @@ -957,6 +957,7 @@ ossl_pkey_public_to_pem(VALUE self) return ossl_pkey_export_spki(self, 0); } +#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY /* * call-seq: * key.public_to_raw => string @@ -964,7 +965,6 @@ ossl_pkey_public_to_pem(VALUE self) * See the OpenSSL documentation for EVP_PKEY_get_raw_public_key() */ -#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY static VALUE ossl_pkey_public_to_raw(VALUE self) { EVP_PKEY *pkey; From b48fcabeb651ad70688ea941021554f136450377 Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Fri, 7 Jul 2023 14:36:10 +0900 Subject: [PATCH 09/18] Ensure key is a String --- ext/openssl/ossl_pkey.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index ea5594190..f0ac6d3ce 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -646,6 +646,7 @@ ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) size_t keylen; StringValue(type); + StringValue(key); ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); if (!ameth) ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type); @@ -678,6 +679,7 @@ ossl_pkey_initialize_public(VALUE self, VALUE type, VALUE key) size_t keylen; StringValue(type); + StringValue(key); ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); if (!ameth) ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type); From e9ccf58e2f75557e4cc014c05bf3813d0cab456c Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Fri, 7 Jul 2023 14:37:12 +0900 Subject: [PATCH 10/18] Fix error message to match actual operation --- ext/openssl/ossl_pkey.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index f0ac6d3ce..a55959fe7 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -656,7 +656,7 @@ ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); if (!pkey) - ossl_raise(ePKeyError, "Could not parse PKey"); + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key"); return ossl_pkey_new(pkey); } @@ -689,7 +689,7 @@ ossl_pkey_initialize_public(VALUE self, VALUE type, VALUE key) pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); if (!pkey) - ossl_raise(ePKeyError, "Could not parse PKey"); + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key"); return ossl_pkey_new(pkey); } From 26bd41dff382f665a69cecb4efdbe38b5170a8c6 Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Fri, 7 Jul 2023 14:37:36 +0900 Subject: [PATCH 11/18] Styling fix --- ext/openssl/ossl_pkey.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index a55959fe7..9b885641e 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -891,7 +891,8 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) * See the OpenSSL documentation for EVP_PKEY_get_raw_private_key() */ -static VALUE ossl_pkey_private_to_raw(VALUE self) +static VALUE +ossl_pkey_private_to_raw(VALUE self) { EVP_PKEY *pkey; VALUE str; From 6628df1adfcad9100095c26b17c2fa3d4e043740 Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Fri, 7 Jul 2023 14:40:01 +0900 Subject: [PATCH 12/18] Error check on EVP_PKEY_get_raw_private/public_key --- ext/openssl/ossl_pkey.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 9b885641e..70bd06673 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -899,7 +899,8 @@ ossl_pkey_private_to_raw(VALUE self) size_t len; GetPKey(self, pkey); - EVP_PKEY_get_raw_private_key(pkey, NULL, &len); + if (EVP_PKEY_get_raw_private_key(pkey, NULL, &len) != 1) + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key"); str = rb_str_new(NULL, len); if (EVP_PKEY_get_raw_private_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1) @@ -975,7 +976,8 @@ static VALUE ossl_pkey_public_to_raw(VALUE self) size_t len; GetPKey(self, pkey); - EVP_PKEY_get_raw_public_key(pkey, NULL, &len); + if (EVP_PKEY_get_raw_public_key(pkey, NULL, &len) != 1) + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_public_key"); str = rb_str_new(NULL, len); if (EVP_PKEY_get_raw_public_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1) From 4d6784194a815128c00f8cab8f699dac06a7f104 Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Fri, 7 Jul 2023 14:41:53 +0900 Subject: [PATCH 13/18] Remove loading support as this might result in unreachable code --- lib/openssl/pkey.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/openssl/pkey.rb b/lib/openssl/pkey.rb index 8463c9e5f..0414658a1 100644 --- a/lib/openssl/pkey.rb +++ b/lib/openssl/pkey.rb @@ -310,12 +310,6 @@ def to_bn(conversion_form = group.point_conversion_form) end end - class PKey - def self._load(string) - OpenSSL::PKey.read(string) - end - end - class RSA include OpenSSL::Marshal From edadf2ff05cd319fe06e8d98f97e1c8daf916313 Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Fri, 7 Jul 2023 15:01:40 +0900 Subject: [PATCH 14/18] Rename methods to match OpenSSL function names --- ext/openssl/ossl_pkey.c | 8 ++++---- test/openssl/test_pkey.rb | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 70bd06673..ecb0b6e4d 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -1728,8 +1728,8 @@ Init_ossl_pkey(void) rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1); rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1); #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY - rb_define_module_function(mPKey, "private_new", ossl_pkey_initialize_private, 2); - rb_define_module_function(mPKey, "public_new", ossl_pkey_initialize_public, 2); + rb_define_module_function(mPKey, "new_raw_private_key", ossl_pkey_initialize_private, 2); + rb_define_module_function(mPKey, "new_raw_public_key", ossl_pkey_initialize_public, 2); #endif rb_define_alloc_func(cPKey, ossl_pkey_alloc); @@ -1745,12 +1745,12 @@ Init_ossl_pkey(void) rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1); rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY - rb_define_method(cPKey, "private_to_raw", ossl_pkey_private_to_raw, 0); + rb_define_method(cPKey, "raw_private_key", ossl_pkey_private_to_raw, 0); #endif rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0); #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY - rb_define_method(cPKey, "public_to_raw", ossl_pkey_public_to_raw, 0); + rb_define_method(cPKey, "raw_public_key", ossl_pkey_public_to_raw, 0); #endif rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1); diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb index d7f10ee5c..691dd74aa 100644 --- a/test/openssl/test_pkey.rb +++ b/test/openssl/test_pkey.rb @@ -111,12 +111,12 @@ def test_ed25519 begin assert_equal "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", - priv.private_to_raw.unpack1("H*") - assert_equal OpenSSL::PKey.private_new("ED25519", priv.private_to_raw).private_to_pem, + priv.raw_private_key.unpack1("H*") + assert_equal OpenSSL::PKey.new_raw_private_key("ED25519", priv.raw_private_key).private_to_pem, priv.private_to_pem assert_equal "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", - priv.public_to_raw.unpack1("H*") - assert_equal OpenSSL::PKey.public_new("ED25519", priv.public_to_raw).public_to_pem, + priv.raw_public_key.unpack1("H*") + assert_equal OpenSSL::PKey.new_raw_public_key("ED25519", priv.raw_public_key).public_to_pem, pub.public_to_pem rescue NoMethodError pend "running OpenSSL version does not have raw public key support" @@ -169,10 +169,10 @@ def test_x25519 assert_equal bob_pem, bob.public_to_pem assert_equal [shared_secret].pack("H*"), alice.derive(bob) begin - alice_private = OpenSSL::PKey.private_new("X25519", alice.private_to_raw) - bob_public = OpenSSL::PKey.public_new("X25519", bob.public_to_raw) - alice_private_raw = alice.private_to_raw.unpack1("H*") - bob_public_raw = bob.public_to_raw.unpack1("H*") + alice_private = OpenSSL::PKey.new_raw_private_key("X25519", alice.raw_private_key) + bob_public = OpenSSL::PKey.new_raw_public_key("X25519", bob.raw_public_key) + alice_private_raw = alice.raw_private_key.unpack1("H*") + bob_public_raw = bob.raw_public_key.unpack1("H*") rescue NoMethodError # OpenSSL < 1.1.1 pend "running OpenSSL version does not have raw public key support" @@ -190,10 +190,10 @@ def test_x25519 def raw_initialize pend "Ed25519 is not implemented" unless OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10101000 && # >= v1.1.1 - assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.private_new("foo123", "xxx") } - assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.private_new("ED25519", "xxx") } - assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.public_new("foo123", "xxx") } - assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.public_new("ED25519", "xxx") } + assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.new_raw_private_key("foo123", "xxx") } + assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.new_raw_private_key("ED25519", "xxx") } + assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.new_raw_public_key("foo123", "xxx") } + assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.new_raw_public_key("ED25519", "xxx") } end def test_compare? From f721fd0586c7c1e8ba58943026dd4855ede98048 Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Fri, 7 Jul 2023 17:17:36 +0900 Subject: [PATCH 15/18] Fix documentation --- ext/openssl/ossl_pkey.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index ecb0b6e4d..cf6423f1c 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -631,7 +631,7 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other) #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY /* * call-seq: - * OpenSSL::PKey.private_new(algo, string) -> PKey + * OpenSSL::PKey.new_raw_private_key(algo, string) -> PKey * * See the OpenSSL documentation for EVP_PKEY_new_raw_private_key() */ @@ -665,7 +665,7 @@ ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY /* * call-seq: - * OpenSSL::PKey.public_new(algo, string) -> PKey + * OpenSSL::PKey.new_raw_public_key(algo, string) -> PKey * * See the OpenSSL documentation for EVP_PKEY_new_raw_public_key() */ @@ -886,7 +886,7 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY /* * call-seq: - * key.private_to_raw => string + * key.raw_private_key => string * * See the OpenSSL documentation for EVP_PKEY_get_raw_private_key() */ @@ -964,7 +964,7 @@ ossl_pkey_public_to_pem(VALUE self) #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY /* * call-seq: - * key.public_to_raw => string + * key.raw_public_key => string * * See the OpenSSL documentation for EVP_PKEY_get_raw_public_key() */ From 18623dd7bbc7dc4205525e050b68159c850597f7 Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Fri, 7 Jul 2023 17:19:02 +0900 Subject: [PATCH 16/18] Rename C function names --- ext/openssl/ossl_pkey.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index cf6423f1c..36ff7c5cd 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -637,7 +637,7 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other) */ static VALUE -ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) +ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key) { EVP_PKEY *pkey; @@ -671,7 +671,7 @@ ossl_pkey_initialize_private(VALUE self, VALUE type, VALUE key) */ static VALUE -ossl_pkey_initialize_public(VALUE self, VALUE type, VALUE key) +ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key) { EVP_PKEY *pkey; const EVP_PKEY_ASN1_METHOD *ameth; @@ -892,7 +892,7 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) */ static VALUE -ossl_pkey_private_to_raw(VALUE self) +ossl_pkey_raw_private_key(VALUE self) { EVP_PKEY *pkey; VALUE str; @@ -969,7 +969,7 @@ ossl_pkey_public_to_pem(VALUE self) * See the OpenSSL documentation for EVP_PKEY_get_raw_public_key() */ -static VALUE ossl_pkey_public_to_raw(VALUE self) +static VALUE ossl_pkey_raw_public_key(VALUE self) { EVP_PKEY *pkey; VALUE str; @@ -1728,8 +1728,8 @@ Init_ossl_pkey(void) rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1); rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1); #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY - rb_define_module_function(mPKey, "new_raw_private_key", ossl_pkey_initialize_private, 2); - rb_define_module_function(mPKey, "new_raw_public_key", ossl_pkey_initialize_public, 2); + rb_define_module_function(mPKey, "new_raw_private_key", ossl_pkey_new_raw_private_key, 2); + rb_define_module_function(mPKey, "new_raw_public_key", ossl_pkey_new_raw_public_key, 2); #endif rb_define_alloc_func(cPKey, ossl_pkey_alloc); @@ -1745,12 +1745,12 @@ Init_ossl_pkey(void) rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1); rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY - rb_define_method(cPKey, "raw_private_key", ossl_pkey_private_to_raw, 0); + rb_define_method(cPKey, "raw_private_key", ossl_pkey_raw_private_key, 0); #endif rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0); #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY - rb_define_method(cPKey, "raw_public_key", ossl_pkey_public_to_raw, 0); + rb_define_method(cPKey, "raw_public_key", ossl_pkey_raw_public_key, 0); #endif rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1); From c40d4fe7398e891f547d68fe7905662148c8ab34 Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Sat, 8 Jul 2023 17:01:24 +0900 Subject: [PATCH 17/18] Styling fixes - Remove trailing whitespaces - Remove extra line break - Styling of function definition - Remove wrong documentation - Group raw_*_key methods together --- ext/openssl/ossl_pkey.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 36ff7c5cd..e94e0a274 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -639,7 +639,6 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other) static VALUE ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key) { - EVP_PKEY *pkey; const EVP_PKEY_ASN1_METHOD *ameth; int pkey_id; @@ -657,7 +656,7 @@ ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key) pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); if (!pkey) ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key"); - + return ossl_pkey_new(pkey); } #endif @@ -690,7 +689,7 @@ ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key) pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); if (!pkey) ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key"); - + return ossl_pkey_new(pkey); } #endif @@ -969,7 +968,8 @@ ossl_pkey_public_to_pem(VALUE self) * See the OpenSSL documentation for EVP_PKEY_get_raw_public_key() */ -static VALUE ossl_pkey_raw_public_key(VALUE self) +static VALUE +ossl_pkey_raw_public_key(VALUE self) { EVP_PKEY *pkey; VALUE str; @@ -991,7 +991,6 @@ static VALUE ossl_pkey_raw_public_key(VALUE self) /* * call-seq: - * pkey.sign(digest, data) -> String * pkey.compare?(another_pkey) -> true | false * * Used primarily to check if an OpenSSL::X509::Certificate#public_key compares to its private key. @@ -1744,12 +1743,10 @@ Init_ossl_pkey(void) rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0); rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1); rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); -#ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY - rb_define_method(cPKey, "raw_private_key", ossl_pkey_raw_private_key, 0); -#endif rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0); #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY + rb_define_method(cPKey, "raw_private_key", ossl_pkey_raw_private_key, 0); rb_define_method(cPKey, "raw_public_key", ossl_pkey_raw_public_key, 0); #endif rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1); From 23262c2034436c0cfbc49a1c7ecbaf0a8669963e Mon Sep 17 00:00:00 2001 From: Ryo Kajiwara Date: Sat, 8 Jul 2023 17:03:20 +0900 Subject: [PATCH 18/18] Doc: key -> pkey --- ext/openssl/ossl_pkey.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index e94e0a274..3603b06ad 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -885,7 +885,7 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY /* * call-seq: - * key.raw_private_key => string + * pkey.raw_private_key => string * * See the OpenSSL documentation for EVP_PKEY_get_raw_private_key() */ @@ -963,7 +963,7 @@ ossl_pkey_public_to_pem(VALUE self) #ifdef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY /* * call-seq: - * key.raw_public_key => string + * pkey.raw_public_key => string * * See the OpenSSL documentation for EVP_PKEY_get_raw_public_key() */