From 6e37bfd8fc311bc15d875bdace0340d98fc04d96 Mon Sep 17 00:00:00 2001 From: Toddr Bot Date: Thu, 21 May 2026 02:06:11 +0000 Subject: [PATCH] Add missing _is_private() check to get_private_key_pkcs8_string() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every private-key operation validates _is_private() before proceeding: get_private_key_string, decrypt, private_encrypt, check_key, sign. The PKCS#8 export variant was the sole exception — calling it on a public-only key produced silent garbage (pre-3.x) or a cryptic OpenSSL error (3.x) instead of a clear croak. Co-Authored-By: Claude Opus 4.6 --- RSA.xs | 4 ++++ t/format.t | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/RSA.xs b/RSA.xs index 238bebb..f85bb45 100644 --- a/RSA.xs +++ b/RSA.xs @@ -763,6 +763,10 @@ get_private_key_pkcs8_string(p_rsa, passphrase_SV=&PL_sv_undef, cipher_name_SV=& char* cipher_name; const EVP_CIPHER* enc = NULL; CODE: + if (!_is_private(p_rsa)) + { + croak("Public keys cannot export private key strings"); + } if (SvPOK(cipher_name_SV) && !SvPOK(passphrase_SV)) { croak("Passphrase is required for cipher"); } diff --git a/t/format.t b/t/format.t index a2d4c4b..37563cb 100644 --- a/t/format.t +++ b/t/format.t @@ -7,7 +7,7 @@ use Crypt::OpenSSL::Guess qw(openssl_version); my ($major, $minor, $patch) = openssl_version(); -BEGIN { plan tests => 56 } +BEGIN { plan tests => 57 } my $PRIVATE_KEY_STRING = <get_private_key_string() }; like($@, qr/Public keys cannot export private key strings/, "get_private_key_string croaks on public-only key"); +eval { $pub_only->get_private_key_pkcs8_string() }; +like($@, qr/Public keys cannot export private key strings/, + "get_private_key_pkcs8_string croaks on public-only key"); + # --- Error: wrong passphrase on re-import --- my $encrypted_pem = $private_key->get_private_key_string($passphrase, 'aes-128-cbc');