From 3ac255af567921f1db1ccfbdae83a54e02a54807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C5=8Dan?= Date: Thu, 2 Apr 2026 22:42:19 -0600 Subject: [PATCH 1/2] fix: reject invalid RSA exponents before calling OpenSSL RSA_generate_key_ex() on OpenSSL 1.1.x enters an infinite loop when given an even exponent (e.g. 2). Add pre-validation in generate_key() to croak immediately if the exponent is < 3 or even, preventing the hang on all OpenSSL versions. Fixes the CI timeout on Debian Bullseye (OpenSSL 1.1.1d) reported in PR #95. Co-Authored-By: Claude Opus 4.6 --- RSA.xs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RSA.xs b/RSA.xs index c6e80af..6bf64b3 100644 --- a/RSA.xs +++ b/RSA.xs @@ -582,6 +582,8 @@ generate_key(proto, bitsSV, exponent = 65537) int error = 0; #endif CODE: + if (exponent < 3 || (exponent % 2) == 0) + croak("RSA exponent must be odd and >= 3 (got %lu)", exponent); e = BN_new(); BN_set_word(e, exponent); #if OPENSSL_VERSION_NUMBER < 0x00908000L From 2371c26b5d9c05e1dcdcee842fa9f30fbb8e7188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C5=8Dan?= Date: Thu, 2 Apr 2026 22:43:08 -0600 Subject: [PATCH 2/2] test: add regression tests for invalid RSA exponent rejection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verify that generate_key() croaks immediately on even exponents (2, 100), exponent 1, and exponent 0 — all of which would hang on OpenSSL 1.1.x without the pre-validation check. Co-Authored-By: Claude Opus 4.6 --- t/key_lifecycle.t | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/t/key_lifecycle.t b/t/key_lifecycle.t index 4ad93d9..5c25b19 100644 --- a/t/key_lifecycle.t +++ b/t/key_lifecycle.t @@ -11,7 +11,7 @@ my $HAS_BIGNUM = eval { require Crypt::OpenSSL::Bignum; 1 } ? 1 : 0; # skip() reports skipped tests which count toward total, so plan must # always include them regardless of whether Bignum is available. -plan tests => 9 + 14 + 20 + 2; +plan tests => 9 + 14 + 20 + 2 + 4; # --- Cross-key operations --- # Sign with key1, verify with key2 — should return false, not croak. @@ -206,3 +206,21 @@ like( $@, qr/modulus and public key must be provided/, eval { Crypt::OpenSSL::RSA->_new_key_from_parameters(0, 0, 0, 0, 0) }; like( $@, qr/modulus and public key must be provided/, "croak when n=0 and e=0 (missing required params)" ); + +# --- Invalid exponent rejection (prevents RSA_generate_key_ex hang on OpenSSL 1.1.x) --- + +eval { Crypt::OpenSSL::RSA->generate_key(2048, 2) }; +like( $@, qr/RSA exponent must be odd and >= 3/, + "generate_key croaks on even exponent (2)" ); + +eval { Crypt::OpenSSL::RSA->generate_key(2048, 1) }; +like( $@, qr/RSA exponent must be odd and >= 3/, + "generate_key croaks on exponent 1" ); + +eval { Crypt::OpenSSL::RSA->generate_key(2048, 0) }; +like( $@, qr/RSA exponent must be odd and >= 3/, + "generate_key croaks on exponent 0" ); + +eval { Crypt::OpenSSL::RSA->generate_key(2048, 100) }; +like( $@, qr/RSA exponent must be odd and >= 3/, + "generate_key croaks on even exponent (100)" );