From 6137eb81eb0558cf9baf99671b58e8f62d34e688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C5=8Dan?= Date: Mon, 16 Mar 2026 05:46:07 -0600 Subject: [PATCH 1/2] fix: prevent resource leaks in get_public_key_string() on OpenSSL 3.x Replace CHECK_OPEN_SSL with THROW/goto err for the OSSL_ENCODER_CTX setup in get_public_key_string(). If encoder creation or encoding fails, both the OSSL_ENCODER_CTX and BIO are now properly freed before croaking. --- RSA.xs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/RSA.xs b/RSA.xs index af12460..c9dceba 100644 --- a/RSA.xs +++ b/RSA.xs @@ -477,22 +477,28 @@ get_public_key_string(p_rsa) rsaData* p_rsa; PREINIT: BIO* stringBIO; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + OSSL_ENCODER_CTX *ctx = NULL; + int error = 0; +#endif CODE: CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem())); #if OPENSSL_VERSION_NUMBER >= 0x30000000L - OSSL_ENCODER_CTX *ctx = NULL; - ctx = OSSL_ENCODER_CTX_new_for_pkey(p_rsa->rsa, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, "PEM", "PKCS1", NULL); - if (!ctx || !OSSL_ENCODER_CTX_get_num_encoders(ctx) - || OSSL_ENCODER_to_bio(ctx, stringBIO) != 1) - { - OSSL_ENCODER_CTX_free(ctx); - BIO_free(stringBIO); - croakSsl(__FILE__, __LINE__); - } + THROW(ctx != NULL && OSSL_ENCODER_CTX_get_num_encoders(ctx)); + + THROW(OSSL_ENCODER_to_bio(ctx, stringBIO) == 1); OSSL_ENCODER_CTX_free(ctx); + ctx = NULL; + + goto pubkey_done; + err: + if (ctx) OSSL_ENCODER_CTX_free(ctx); + BIO_free(stringBIO); + CHECK_OPEN_SSL(0); + pubkey_done: #else PEM_write_bio_RSAPublicKey(stringBIO, p_rsa->rsa); #endif From de4e020d2828fb9f1752c3923df20bde21a82024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C5=8Dan?= Date: Tue, 17 Mar 2026 18:55:56 -0600 Subject: [PATCH 2/2] rebase: apply review feedback on #114 --- RSA.xs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RSA.xs b/RSA.xs index c9dceba..03015bb 100644 --- a/RSA.xs +++ b/RSA.xs @@ -495,7 +495,7 @@ get_public_key_string(p_rsa) goto pubkey_done; err: - if (ctx) OSSL_ENCODER_CTX_free(ctx); + if (ctx) { OSSL_ENCODER_CTX_free(ctx); ctx = NULL; } BIO_free(stringBIO); CHECK_OPEN_SSL(0); pubkey_done: