Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix parsing EC private keys with EC parameters #535

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion ext/openssl/ossl_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)
OSSL_BIO_reset(bio);
if (OSSL_DECODER_CTX_set_input_type(dctx, "PEM") != 1)
goto out;
while (OSSL_DECODER_from_bio(dctx, bio) != 1) {
for (;;) {
OSSL_DECODER_from_bio(dctx, bio);
if (BIO_eof(bio))
goto out;
pos2 = BIO_tell(bio);
Expand All @@ -115,6 +116,17 @@ ossl_pkey_read_generic(BIO *bio, VALUE pass)

out:
OSSL_DECODER_CTX_free(dctx);

#if !defined(OPENSSL_NO_EC)
if (pkey && EVP_PKEY_base_id(pkey) == EVP_PKEY_EC) {
const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
if (!EC_KEY_get0_public_key(ec_key) && !EC_KEY_get0_private_key(ec_key)) {
EVP_PKEY_free(pkey);
pkey = NULL;
}
}
#endif

return pkey;
}
#else
Expand Down
10 changes: 10 additions & 0 deletions test/openssl/test_pkey.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@ def test_x25519
assert_equal [shared_secret].pack("H*"), alice.derive(bob)
end

def test_invalid_pkey_valid_ecparam
priv_pem = <<~EOF
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
EOF

assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.read(priv_pem) }
end

def test_compare?
key1 = Fixtures.pkey("rsa1024")
key2 = Fixtures.pkey("rsa1024")
Expand Down
39 changes: 39 additions & 0 deletions test/openssl/test_pkey_ec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,45 @@ def test_ECPrivateKey
assert_equal pem, p256.export
end

def test_ECPrivateKey_with_parameters
p256 = Fixtures.pkey("p256")
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(1),
OpenSSL::ASN1::OctetString(p256.private_key.to_s(2)),
OpenSSL::ASN1::ObjectId("prime256v1", 0, :EXPLICIT),
OpenSSL::ASN1::BitString(p256.public_key.to_octet_string(:uncompressed),
1, :EXPLICIT)
])
key = OpenSSL::PKey::EC.new(asn1.to_der)
assert_predicate key, :private?
assert_same_ec p256, key

in_pem = <<~EOF
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIID49FDqcf1O1eO8saTgG70UbXQw9Fqwseliit2aWhH1oAoGCCqGSM49
AwEHoUQDQgAEFglk2c+oVUIKQ64eZG9bhLNPWB7lSZ/ArK41eGy5wAzU/0G51Xtt
CeBUl+MahZtn9fO1JKdF4qJmS39dXnpENg==
-----END EC PRIVATE KEY-----
EOF

out_pem = <<~EOF
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIID49FDqcf1O1eO8saTgG70UbXQw9Fqwseliit2aWhH1oAoGCCqGSM49
AwEHoUQDQgAEFglk2c+oVUIKQ64eZG9bhLNPWB7lSZ/ArK41eGy5wAzU/0G51Xtt
CeBUl+MahZtn9fO1JKdF4qJmS39dXnpENg==
-----END EC PRIVATE KEY-----
EOF

key = OpenSSL::PKey::EC.new(in_pem)
assert_same_ec p256, key

assert_equal asn1.to_der, p256.to_der
assert_equal out_pem, p256.export
end

def test_ECPrivateKey_encrypted
p256 = Fixtures.pkey("p256")
# key = abcdef
Expand Down