certs_manager: switch keygen to support openssl-3
Many of the functions currently used to generate key pairs are
deprecated in OpenSSL-3. Update keygen functions to use non-deprecated
functions.
Unfortunately, the replacement functions are not available in
OpenSSL-1, so we have to add an #ifdef block around the proper routines
for each version.
Tested: Ran test cases under both OpenSSL1 and OpenSSL3.
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I888a8a796cc97caf8c402cd546ab39b4931960ed
diff --git a/certs_manager.cpp b/certs_manager.cpp
index 2904f45..4c71a41 100644
--- a/certs_manager.cpp
+++ b/certs_manager.cpp
@@ -1,5 +1,6 @@
#include "certs_manager.hpp"
+#include <openssl/evp.h>
#include <openssl/pem.h>
#include <unistd.h>
@@ -446,16 +447,6 @@
}
EVP_PKEY_Ptr Manager::generateRSAKeyPair(const int64_t keyBitLength)
{
- int ret = 0;
- // generate rsa key
- BIGNUM_Ptr bne(BN_new(), ::BN_free);
- ret = BN_set_word(bne.get(), RSA_F4);
- if (ret == 0)
- {
- log<level::ERR>("Error occured during BN_set_word call");
- elog<InternalFailure>();
- }
-
int64_t keyBitLen = keyBitLength;
// set keybit length to default value if not set
if (keyBitLen <= 0)
@@ -466,6 +457,18 @@
entry("DEFAULTKEYBITLENGTH=%d", DEFAULT_KEYBITLENGTH));
keyBitLen = DEFAULT_KEYBITLENGTH;
}
+
+#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
+
+ // generate rsa key
+ BIGNUM_Ptr bne(BN_new(), ::BN_free);
+ auto ret = BN_set_word(bne.get(), RSA_F4);
+ if (ret == 0)
+ {
+ log<level::ERR>("Error occured during BN_set_word call");
+ elog<InternalFailure>();
+ }
+
RSA* rsa = RSA_new();
ret = RSA_generate_key_ex(rsa, keyBitLen, bne.get(), NULL);
if (ret != 1)
@@ -487,6 +490,33 @@
}
return pKey;
+
+#else
+ auto ctx = std::unique_ptr<EVP_PKEY_CTX, decltype(&::EVP_PKEY_CTX_free)>(
+ EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr), &::EVP_PKEY_CTX_free);
+ if (!ctx)
+ {
+ log<level::ERR>("Error occured creating EVP_PKEY_CTX from algorithm");
+ elog<InternalFailure>();
+ }
+
+ if ((EVP_PKEY_keygen_init(ctx.get()) <= 0) ||
+ (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), keyBitLen) <= 0))
+
+ {
+ log<level::ERR>("Error occured initializing keygen context");
+ elog<InternalFailure>();
+ }
+
+ EVP_PKEY* pKey = nullptr;
+ if (EVP_PKEY_keygen(ctx.get(), &pKey) <= 0)
+ {
+ log<level::ERR>("Error occured during generate EC key");
+ elog<InternalFailure>();
+ }
+
+ return {pKey, &::EVP_PKEY_free};
+#endif
}
EVP_PKEY_Ptr Manager::generateECKeyPair(const std::string& curveId)
@@ -504,7 +534,6 @@
}
int ecGrp = OBJ_txt2nid(curId.c_str());
-
if (ecGrp == NID_undef)
{
log<level::ERR>(
@@ -513,6 +542,8 @@
elog<InternalFailure>();
}
+#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
+
EC_KEY* ecKey = EC_KEY_new_by_curve_name(ecGrp);
if (ecKey == NULL)
@@ -547,6 +578,56 @@
}
return pKey;
+
+#else
+ auto holder_of_key = [](EVP_PKEY* key) {
+ return std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>{
+ key, &::EVP_PKEY_free};
+ };
+
+ // Create context to set up curve parameters.
+ auto ctx = std::unique_ptr<EVP_PKEY_CTX, decltype(&::EVP_PKEY_CTX_free)>(
+ EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr), &::EVP_PKEY_CTX_free);
+ if (!ctx)
+ {
+ log<level::ERR>("Error occured creating EVP_PKEY_CTX for params");
+ elog<InternalFailure>();
+ }
+
+ // Set up curve parameters.
+ EVP_PKEY* params = nullptr;
+
+ if ((EVP_PKEY_paramgen_init(ctx.get()) <= 0) ||
+ (EVP_PKEY_CTX_set_ec_param_enc(ctx.get(), OPENSSL_EC_NAMED_CURVE) <=
+ 0) ||
+ (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx.get(), ecGrp) <= 0) ||
+ (EVP_PKEY_paramgen(ctx.get(), ¶ms) <= 0))
+ {
+ log<level::ERR>("Error occured setting curve parameters");
+ elog<InternalFailure>();
+ }
+
+ // Move parameters to RAII holder.
+ auto pparms = holder_of_key(params);
+
+ // Create new context for key.
+ ctx.reset(EVP_PKEY_CTX_new_from_pkey(nullptr, params, nullptr));
+
+ if (!ctx || (EVP_PKEY_keygen_init(ctx.get()) <= 0))
+ {
+ log<level::ERR>("Error occured initializing keygen context");
+ elog<InternalFailure>();
+ }
+
+ EVP_PKEY* pKey = nullptr;
+ if (EVP_PKEY_keygen(ctx.get(), &pKey) <= 0)
+ {
+ log<level::ERR>("Error occured during generate EC key");
+ elog<InternalFailure>();
+ }
+
+ return holder_of_key(pKey);
+#endif
}
void Manager::writePrivateKey(const EVP_PKEY_Ptr& pKey,