Skip to content

Commit

Permalink
pkey: simplify X25519/Ed25519 test cases
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rhenium committed Jan 6, 2025
1 parent fed9d09 commit 6cb6663
Showing 1 changed file with 29 additions and 42 deletions.
71 changes: 29 additions & 42 deletions test/openssl/test_pkey.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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-----
Expand All @@ -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") }
Expand Down

0 comments on commit 6cb6663

Please sign in to comment.