diff --git a/RSA.xs b/RSA.xs index fd80267..014250a 100644 --- a/RSA.xs +++ b/RSA.xs @@ -580,6 +580,12 @@ _new_public_key_x509_der(proto, key_string_SV) #endif BIO_free(bio); CHECK_OPEN_SSL(pkey); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (EVP_PKEY_get_base_id(pkey) != EVP_PKEY_RSA) { + EVP_PKEY_free(pkey); + croak("The key loaded is not an RSA key"); + } +#endif RETVAL = make_rsa_obj(proto, pkey); OUTPUT: RETVAL diff --git a/t/der.t b/t/der.t index 1d919d5..cc64c88 100644 --- a/t/der.t +++ b/t/der.t @@ -4,7 +4,9 @@ use Test::More; use MIME::Base64; use Crypt::OpenSSL::RSA; -BEGIN { plan tests => 22 } +use File::Temp qw(tempfile); + +BEGIN { plan tests => 24 } # --- Generate a key pair for testing --- @@ -127,3 +129,26 @@ like( $@, qr/unrecognized key format/, eval { Crypt::OpenSSL::RSA->new_public_key("-----BEGIN CERTIFICATE-----\nfoo\n-----END CERTIFICATE-----\n") }; like( $@, qr/unrecognized key format/, "new_public_key gives helpful error on certificate PEM" ); + +# --- Non-RSA DER key rejection --- +# On OpenSSL 3.x, d2i_PUBKEY_bio() accepts any key type. +# _new_public_key_x509_der must reject non-RSA keys. + +SKIP: { + my $ec_pem = `openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 2>/dev/null`; + skip "EC key generation not available", 2 + unless ($? >> 8) == 0 && $ec_pem =~ /-----BEGIN PRIVATE KEY-----/; + + my ($tmpfh, $tmpfile) = tempfile(UNLINK => 1); + print $tmpfh $ec_pem; + close $tmpfh; + my $ec_pub_pem = `openssl pkey -in $tmpfile -pubout -outform PEM 2>/dev/null`; + skip "EC public key export failed", 2 + unless ($? >> 8) == 0 && $ec_pub_pem =~ /-----BEGIN PUBLIC KEY-----/; + + my $ec_pub_der = pem_to_der($ec_pub_pem); + eval { Crypt::OpenSSL::RSA->_new_public_key_x509_der($ec_pub_der) }; + ok($@, "_new_public_key_x509_der rejects EC DER key"); + like($@, qr/not an RSA key|ASN1|expecting an rsa key/i, + "_new_public_key_x509_der gives appropriate error for non-RSA DER key"); +}