From 11216b8beca0b5e104052a6c9f15290300dbe8ca Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Thu, 4 Jul 2024 17:05:05 +0900 Subject: [PATCH 1/4] x509cert: simplify test cases for Certificate.load_file Remove files from test/openssl/fixtures/pkey/ which are not pkeys. The test cases for OpenSSL::X509::Certificate.load_file can simply use issue_cert and Tempfile. --- test/openssl/fixtures/pkey/certificate.der | Bin 1325 -> 0 bytes test/openssl/fixtures/pkey/empty.der | 0 test/openssl/fixtures/pkey/empty.pem | 0 test/openssl/fixtures/pkey/fullchain.pem | 56 --------------------- test/openssl/fixtures/pkey/garbage.txt | 1 - test/openssl/test_x509cert.rb | 51 +++++++++++++------ test/openssl/utils.rb | 4 -- 7 files changed, 35 insertions(+), 77 deletions(-) delete mode 100644 test/openssl/fixtures/pkey/certificate.der delete mode 100644 test/openssl/fixtures/pkey/empty.der delete mode 100644 test/openssl/fixtures/pkey/empty.pem delete mode 100644 test/openssl/fixtures/pkey/fullchain.pem delete mode 100644 test/openssl/fixtures/pkey/garbage.txt diff --git a/test/openssl/fixtures/pkey/certificate.der b/test/openssl/fixtures/pkey/certificate.der deleted file mode 100644 index 7d44df8413aac2a7b71767f5926cb70c12bf77f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1325 zcmXqLV%0QgVi8=x%*4pVB*YS}Y5&@@R;=l@RQB2j6>jsr40zc%wc0$|zVk9NaqoMbzx zr^>1MTJ>-D0P$2l@5%3;SHFF9AgW;h6U~I%=l@Fj-~4dnkJqkKJBxlrx;{HD*3gB7N;gn~D`9FALnz5aDA6~N0og0aB5EMqge86WfMgX| zTn(HJIM~?I8+jO+7!AzXxPiW9VQjh&^cw44LcK*FplvjT; zzOrX;*M9Rh(eEL$Grbg_w$5Nu;8m;I#dqM87_XMi(eSn)1)<0d% z`rr2QKG7YmwflVgdrMEX`EQpL>%S@fJLpwIxE*I>!r55CUu7cf=@OSWdFVyF71$Bv z9~?CKTXU>wg5=_tSGb&_8xFLn{9@i=sOc{3R1*BtXPNbD-E=+Ktrh=8I~6b6b^O{R z`AqletB4ubtz(~fH2u4JSH{`#LjH}XKF_lKLtowPc+26nJ-T}4`t$iS*NH6n;p8h9 z*>mvJPPx@S2laVA@YL Date: Thu, 4 Jul 2024 17:28:10 +0900 Subject: [PATCH 2/4] pkey/ec: use heredoc for invalid key example in test cases test/openssl/fixtures/pkey/p256_too_large.pem and p384_invalid.pem are invalid keys where the encoded public key doesn't match the private key. They are only useful for test cases for OpenSSL::PKey::EC#check_key and will not be reused elsewhere. Let's directly include the PEM encoding as a heredoc for clarity. p384_invalid.pem is dropped because it is redundant. --- test/openssl/fixtures/pkey/p256_too_large.pem | 5 ----- test/openssl/fixtures/pkey/p384_invalid.pem | 6 ------ test/openssl/test_pkey_ec.rb | 12 ++++++++---- 3 files changed, 8 insertions(+), 15 deletions(-) delete mode 100644 test/openssl/fixtures/pkey/p256_too_large.pem delete mode 100644 test/openssl/fixtures/pkey/p384_invalid.pem diff --git a/test/openssl/fixtures/pkey/p256_too_large.pem b/test/openssl/fixtures/pkey/p256_too_large.pem deleted file mode 100644 index a73ac37f8..000000000 --- a/test/openssl/fixtures/pkey/p256_too_large.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN EC PRIVATE KEY----- -MHcCAQEEIP+TT0V8Fndsnacji9tyf6hmhHywcOWTee9XkiBeJoVloAoGCCqGSM49 -AwEHoUQDQgAEBkhhJIU/2/YdPSlY2I1k25xjK4trr5OXSgXvBC21PtY0HQ7lor7A -jzT0giJITqmcd81fwGw5+96zLcdxTF1hVQ== ------END EC PRIVATE KEY----- diff --git a/test/openssl/fixtures/pkey/p384_invalid.pem b/test/openssl/fixtures/pkey/p384_invalid.pem deleted file mode 100644 index d5cdc9a3a..000000000 --- a/test/openssl/fixtures/pkey/p384_invalid.pem +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN EC PRIVATE KEY----- -MIGkAgEBBDDA1Tm0m7YhkfeVpFuarAJYVlHp2tQj+1fOBiLa10t9E8TiQO/hVfxB -vGaVEQwOheWgBwYFK4EEACKhZANiAASyGqmryZGqdpsq5gEDIfNvgC3AwSJxiBCL -XKHBTFRp+tCezLDOK/6V8KK/vVGBJlGFW6/I7ahyXprxS7xs7hPA9iz5YiuqXlu+ -lbrIpZOz7b73hyQQCkvbBO/Avg+hPAk= ------END EC PRIVATE KEY----- diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb index 2cb8e287a..5a15c5441 100644 --- a/test/openssl/test_pkey_ec.rb +++ b/test/openssl/test_pkey_ec.rb @@ -88,12 +88,16 @@ def test_check_key assert_equal(true, key2.check_key) # Behavior of EVP_PKEY_public_check changes between OpenSSL 1.1.1 and 3.0 - key4 = Fixtures.pkey("p256_too_large") + # The public key does not match the private key + key4 = OpenSSL::PKey.read(<<~EOF) + -----BEGIN EC PRIVATE KEY----- + MHcCAQEEIP+TT0V8Fndsnacji9tyf6hmhHywcOWTee9XkiBeJoVloAoGCCqGSM49 + AwEHoUQDQgAEBkhhJIU/2/YdPSlY2I1k25xjK4trr5OXSgXvBC21PtY0HQ7lor7A + jzT0giJITqmcd81fwGw5+96zLcdxTF1hVQ== + -----END EC PRIVATE KEY----- + EOF assert_raise(OpenSSL::PKey::ECError) { key4.check_key } - key5 = Fixtures.pkey("p384_invalid") - assert_raise(OpenSSL::PKey::ECError) { key5.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 From fed9d09b76a9a1fb9f4d2e62e79924e908b4419f Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Sat, 17 Aug 2024 15:04:00 +0900 Subject: [PATCH 3/4] pkey: fix test case for new_raw_*key Method names must start with "test_" to run. --- test/openssl/test_pkey.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb index aae6b7e07..0a55364af 100644 --- a/test/openssl/test_pkey.rb +++ b/test/openssl/test_pkey.rb @@ -188,7 +188,7 @@ def test_x25519 bob_public_raw end - def raw_initialize + def test_raw_initialize_errors pend "Ed25519 is not implemented" unless openssl?(1, 1, 1) # >= v1.1.1 assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.new_raw_private_key("foo123", "xxx") } From 6cb6663c916ba56079e81dc6bf9ad97e7970b89f Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Tue, 7 Jan 2025 00:13:16 +0900 Subject: [PATCH 4/4] 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 --- 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 0a55364af..5fe4a3efc 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 @@ def test_ed25519 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 @@ def test_ed25519 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 @@ def test_x25519 -----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") }