From e5f93c915c663b8afaafc3c6f7c436ae6780e509 Mon Sep 17 00:00:00 2001 From: Sean Khan Date: Tue, 4 Jun 2024 23:20:14 -0400 Subject: [PATCH] nginx-util: Rework ptr cleanup and error handling As per @Ansuel's not about ctx cleanup in error path, decided to rework the patch. Changes and Improvements: Smart Pointers for Memory Management: * The `EVP_PKEY_ptr` and `X509_NAME_ptr` smart pointers are used to manage the memory of `EVP_PKEY` and `X509_NAME` objects respectively to ensure proper cleanup. Error Handling: * Improved error messages and exception handling to provide more information about what went wrong. Resource Cleanup: * Ensured all allocated resources are now properly freed in case of an error to prevent memory leaks. Signed-off-by: Sean Khan --- net/nginx-util/src/px5g-openssl.hpp | 41 ++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/net/nginx-util/src/px5g-openssl.hpp b/net/nginx-util/src/px5g-openssl.hpp index 3dab5891ca..d73c3ae68e 100644 --- a/net/nginx-util/src/px5g-openssl.hpp +++ b/net/nginx-util/src/px5g-openssl.hpp @@ -1,7 +1,6 @@ #ifndef _PX5G_OPENSSL_HPP #define _PX5G_OPENSSL_HPP -// #define OPENSSL_API_COMPAT 0x10102000L #include #include #include @@ -93,25 +92,45 @@ auto gen_eckey(const int curve) -> EVP_PKEY_ptr EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr); - if (!EVP_PKEY_paramgen_init(ctx)) { - throw std::runtime_error("Could not init paramgen"); + if (!ctx || !EVP_PKEY_paramgen_init(ctx)) { + EC_GROUP_free(group); + if (ctx) EVP_PKEY_CTX_free(ctx); + throw std::runtime_error("gen_eckey error: could not initialize paramgen"); } - EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, curve); + if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, curve) <= 0) { + EVP_PKEY_CTX_free(ctx); + EC_GROUP_free(group); + std::string errmsg{"gen_eckey error: cannot set curve nid\n"}; + ERR_print_errors_cb(print_error, &errmsg); + throw std::runtime_error(errmsg); + } EVP_PKEY* params = nullptr; - EVP_PKEY_paramgen(ctx, ¶ms); + if (EVP_PKEY_paramgen(ctx, ¶ms) <= 0) { + EVP_PKEY_CTX_free(ctx); + EC_GROUP_free(group); + std::string errmsg{"gen_eckey error: cannot generate parameters\n"}; + ERR_print_errors_cb(print_error, &errmsg); + throw std::runtime_error(errmsg); + } + + EVP_PKEY_CTX_free(ctx); + + std::unique_ptr params_ptr(params, EVP_PKEY_free); EVP_PKEY_CTX* key_gen_ctx = EVP_PKEY_CTX_new(params, nullptr); - if (EVP_PKEY_keygen_init(key_gen_ctx) <= 0) { + if (!key_gen_ctx || EVP_PKEY_keygen_init(key_gen_ctx) <= 0) { + EC_GROUP_free(group); + if (key_gen_ctx) EVP_PKEY_CTX_free(key_gen_ctx); std::string errmsg{"gen_eckey error: cannot initialize key generation context\n"}; ERR_print_errors_cb(print_error, &errmsg); throw std::runtime_error(errmsg); } EVP_PKEY* pkey = nullptr; - if (!EVP_PKEY_keygen(key_gen_ctx, &pkey)) { + if (EVP_PKEY_keygen(key_gen_ctx, &pkey) <= 0) { EVP_PKEY_CTX_free(key_gen_ctx); EC_GROUP_free(group); std::string errmsg{"gen_eckey error: cannot generate key pair\n"}; @@ -119,12 +138,10 @@ auto gen_eckey(const int curve) -> EVP_PKEY_ptr throw std::runtime_error(errmsg); } - EVP_PKEY_CTX_free(ctx); + EVP_PKEY_CTX_free(key_gen_ctx); EC_GROUP_free(group); - EVP_PKEY_ptr pkey_ptr{pkey, ::EVP_PKEY_free}; - - return pkey_ptr; + return EVP_PKEY_ptr{pkey, EVP_PKEY_free}; } auto gen_rsakey(const int keysize) -> EVP_PKEY_ptr @@ -197,7 +214,7 @@ auto subject2name(const std::string& subject) -> X509_NAME_ptr throw std::runtime_error("subject2name errror: not starting with /"); } - X509_NAME_ptr name = {X509_NAME_new(), ::X509_NAME_free}; + X509_NAME_ptr name = {X509_NAME_new(), X509_NAME_free}; if (!name) { std::string errmsg{"subject2name error: cannot create X509 name \n"}; -- 2.30.2