ssl_key_handler: use OpenSSL 3.0 API for keygen

The APIs for generating an EC key for have changed between OpenSSL 1.x
and OpenSSL 3.x.  Create a separate implementation for OpenSSL 3.x.

Tested: Copied code from phosphor-certificate-manager, which was
tested using unit tests, and confirmed it builds and runs when compiled
with the OpenSSL 3.x library.

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I6df0fb5429e0812763dad4a208bb914fb285fd78
diff --git a/include/ssl_key_handler.hpp b/include/ssl_key_handler.hpp
index 7710ae2..4578c2b 100644
--- a/include/ssl_key_handler.hpp
+++ b/include/ssl_key_handler.hpp
@@ -308,6 +308,8 @@
 EVP_PKEY* createEcKey()
 {
     EVP_PKEY* pKey = nullptr;
+
+#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
     int eccgrp = 0;
     eccgrp = OBJ_txt2nid("secp384r1");
 
@@ -329,6 +331,45 @@
             }
         }
     }
+#else
+    // Create context for curve parameter generation.
+    std::unique_ptr<EVP_PKEY_CTX, decltype(&::EVP_PKEY_CTX_free)> ctx{
+        EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr), &::EVP_PKEY_CTX_free};
+    if (!ctx)
+    {
+        return nullptr;
+    }
+
+    // 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(), NID_secp384r1) <=
+         0) ||
+        (EVP_PKEY_paramgen(ctx.get(), &params) <= 0))
+    {
+        return nullptr;
+    }
+
+    // Set up RAII holder for params.
+    std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)> pparams{
+        params, &::EVP_PKEY_free};
+
+    // Set new context for key generation, using curve parameters.
+    ctx.reset(EVP_PKEY_CTX_new_from_pkey(nullptr, params, nullptr));
+    if (!ctx || (EVP_PKEY_keygen_init(ctx.get()) <= 0))
+    {
+        return nullptr;
+    }
+
+    // Generate key.
+    if (EVP_PKEY_keygen(ctx.get(), &pKey) <= 0)
+    {
+        return nullptr;
+    }
+#endif
+
     return pKey;
 }