From a61c16ba4214da3eda45bdd2b168e7d7e8af30c5 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Tue, 7 Jan 2025 00:13:16 +0900 Subject: [PATCH] [ruby/openssl] pkey: simplify X25519/Ed25519 test cases When these test cases were written, we did not know the exact OpenSSL and LibreSSL version number in which they would be implemented. Now that we know it, we can use that information to ensure the tests are run whenever they should be. - OpenSSL 1.1.0 added X25519 support - OpenSSL 1.1.1 added Ed25519 support and EVP_PKEY_new_raw_private_key() - LibreSSL 3.7.0 added X25519 and Ed25519 support in EVP_PKEY and EVP_PKEY_new_raw_private_key() - LibreSSL 3.8.1 allowed ASN1_item_sign() to use Ed25519 https://github.com/ruby/openssl/commit/6cb6663c91 --- test/openssl/test_pkey.rb | 71 ++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb index 0a55364af6..5fe4a3efc4 100644 --- a/test/openssl/test_pkey.rb +++ b/test/openssl/test_pkey.rb @@ -2,25 +2,20 @@ require_relative "utils" class OpenSSL::TestPKey < OpenSSL::PKeyTestCase - def test_generic_oid_inspect + def test_generic_oid_inspect_rsa # RSA private key rsa = Fixtures.pkey("rsa-1") assert_instance_of OpenSSL::PKey::RSA, rsa assert_equal "rsaEncryption", rsa.oid assert_match %r{oid=rsaEncryption}, rsa.inspect + end + + def test_generic_oid_inspect_x25519 + omit "X25519 not supported" unless openssl?(1, 1, 0) || libressl?(3, 7, 0) + omit_on_fips # X25519 private key - x25519_pem = <<~EOF - -----BEGIN PRIVATE KEY----- - MC4CAQAwBQYDK2VuBCIEIHcHbQpzGKV9PBbBclGyZkXfTC+H68CZKrF3+6UduSwq - -----END PRIVATE KEY----- - EOF - begin - x25519 = OpenSSL::PKey.read(x25519_pem) - rescue OpenSSL::PKey::PKeyError - # OpenSSL < 1.1.0 - pend "X25519 is not implemented" - end + x25519 = OpenSSL::PKey.generate_key("X25519") assert_instance_of OpenSSL::PKey::PKey, x25519 assert_equal "X25519", x25519.oid assert_match %r{oid=X25519}, x25519.inspect @@ -112,18 +107,14 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase assert_equal pub_pem, priv.public_to_pem assert_equal pub_pem, pub.public_to_pem - begin - assert_equal "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", - 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.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" - end + assert_equal "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", + 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.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 sig = [<<~EOF.gsub(/[^0-9a-f]/, "")].pack("H*") 92a009a9f0d4cab8720e820b5f642540 @@ -146,6 +137,9 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase end def test_x25519 + omit "X25519 not supported" unless openssl?(1, 1, 0) || libressl?(3, 7, 0) + omit_on_fips + # Test vector from RFC 7748 Section 6.1 alice_pem = <<~EOF -----BEGIN PRIVATE KEY----- @@ -158,38 +152,31 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase -----END PUBLIC KEY----- EOF shared_secret = "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742" - begin - alice = OpenSSL::PKey.read(alice_pem) - bob = OpenSSL::PKey.read(bob_pem) - rescue OpenSSL::PKey::PKeyError - # OpenSSL < 1.1.0 - pend "X25519 is not implemented" - end + + alice = OpenSSL::PKey.read(alice_pem) + bob = OpenSSL::PKey.read(bob_pem) assert_instance_of OpenSSL::PKey::PKey, alice 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) - begin - 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" + + unless openssl?(1, 1, 1) || libressl?(3, 7, 0) + omit "running OpenSSL version does not have raw public key support" end + 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) assert_equal alice_private.private_to_pem, alice.private_to_pem assert_equal bob_public.public_to_pem, bob.public_to_pem assert_equal "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a", - alice_private_raw + alice.raw_private_key.unpack1("H*") assert_equal "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f", - bob_public_raw + bob.raw_public_key.unpack1("H*") end def test_raw_initialize_errors - pend "Ed25519 is not implemented" unless openssl?(1, 1, 1) # >= v1.1.1 + omit "Ed25519 not supported" unless openssl?(1, 1, 1) || libressl?(3, 7, 0) 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") }