Break out x509 generation

This function is a little long, and deeply nested which makes the
cleanup a little confusing.  Break out one method into its own function.

Tested: bmcweb starts, and certificates generate correctly.

Change-Id: I315c172ae17e1efa9ba049c4fb60a9c369c6415b
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/src/ssl_key_handler.cpp b/src/ssl_key_handler.cpp
index c36841b..af64957 100644
--- a/src/ssl_key_handler.cpp
+++ b/src/ssl_key_handler.cpp
@@ -268,6 +268,92 @@
     }
 }
 
+static std::string constructX509(const std::string& cn, EVP_PKEY* pPrivKey)
+{
+    std::string buffer;
+    X509* x509 = X509_new();
+    if (x509 == nullptr)
+    {
+        return buffer;
+    }
+
+    // get a random number from the RNG for the certificate serial
+    // number If this is not random, regenerating certs throws browser
+    // errors
+    bmcweb::OpenSSLGenerator gen;
+    std::uniform_int_distribution<int> dis(1, std::numeric_limits<int>::max());
+    int serial = dis(gen);
+
+    ASN1_INTEGER_set(X509_get_serialNumber(x509), serial);
+
+    // not before this moment
+    X509_gmtime_adj(X509_get_notBefore(x509), 0);
+    // Cert is valid for 10 years
+    X509_gmtime_adj(X509_get_notAfter(x509), 60L * 60L * 24L * 365L * 10L);
+
+    // set the public key to the key we just generated
+    X509_set_pubkey(x509, pPrivKey);
+
+    // get the subject name
+    X509_NAME* name = X509_get_subject_name(x509);
+
+    using x509String = const unsigned char;
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+    const auto* country = reinterpret_cast<x509String*>("US");
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+    const auto* company = reinterpret_cast<x509String*>("OpenBMC");
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+    const auto* cnStr = reinterpret_cast<x509String*>(cn.c_str());
+
+    X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, country, -1, -1, 0);
+    X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, company, -1, -1, 0);
+    X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, cnStr, -1, -1, 0);
+    // set the CSR options
+    X509_set_issuer_name(x509, name);
+
+    X509_set_version(x509, 2);
+    addExt(x509, NID_basic_constraints, ("critical,CA:TRUE"));
+    addExt(x509, NID_subject_alt_name, ("DNS:" + cn).c_str());
+    addExt(x509, NID_subject_key_identifier, ("hash"));
+    addExt(x509, NID_authority_key_identifier, ("keyid"));
+    addExt(x509, NID_key_usage, ("digitalSignature, keyEncipherment"));
+    addExt(x509, NID_ext_key_usage, ("serverAuth"));
+    addExt(x509, NID_netscape_comment, (x509Comment));
+
+    // Sign the certificate with our private key
+    X509_sign(x509, pPrivKey, EVP_sha256());
+
+    BIO* bufio = BIO_new(BIO_s_mem());
+
+    int pkeyRet = PEM_write_bio_PrivateKey(bufio, pPrivKey, nullptr, nullptr, 0,
+                                           nullptr, nullptr);
+    if (pkeyRet <= 0)
+    {
+        BMCWEB_LOG_ERROR("Failed to write pkey with code {}.  Ignoring.",
+                         pkeyRet);
+    }
+
+    char* data = nullptr;
+    long int dataLen = BIO_get_mem_data(bufio, &data);
+    buffer += std::string_view(data, static_cast<size_t>(dataLen));
+    BIO_free(bufio);
+
+    bufio = BIO_new(BIO_s_mem());
+    pkeyRet = PEM_write_bio_X509(bufio, x509);
+    if (pkeyRet <= 0)
+    {
+        BMCWEB_LOG_ERROR("Failed to write X509 with code {}.  Ignoring.",
+                         pkeyRet);
+    }
+    dataLen = BIO_get_mem_data(bufio, &data);
+    buffer += std::string_view(data, static_cast<size_t>(dataLen));
+
+    BIO_free(bufio);
+    BMCWEB_LOG_INFO("Cert size is {}", buffer.size());
+    X509_free(x509);
+    return buffer;
+}
+
 std::string generateSslCertificate(const std::string& cn)
 {
     BMCWEB_LOG_INFO("Generating new keys");
@@ -279,95 +365,11 @@
     {
         BMCWEB_LOG_INFO("Generating x509 Certificates");
         // Use this code to directly generate a certificate
-        X509* x509 = X509_new();
-        if (x509 != nullptr)
-        {
-            // get a random number from the RNG for the certificate serial
-            // number If this is not random, regenerating certs throws browser
-            // errors
-            bmcweb::OpenSSLGenerator gen;
-            std::uniform_int_distribution<int> dis(
-                1, std::numeric_limits<int>::max());
-            int serial = dis(gen);
-
-            ASN1_INTEGER_set(X509_get_serialNumber(x509), serial);
-
-            // not before this moment
-            X509_gmtime_adj(X509_get_notBefore(x509), 0);
-            // Cert is valid for 10 years
-            X509_gmtime_adj(X509_get_notAfter(x509),
-                            60L * 60L * 24L * 365L * 10L);
-
-            // set the public key to the key we just generated
-            X509_set_pubkey(x509, pPrivKey);
-
-            // get the subject name
-            X509_NAME* name = X509_get_subject_name(x509);
-
-            using x509String = const unsigned char;
-            // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-            x509String* country = reinterpret_cast<x509String*>("US");
-            // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-            x509String* company = reinterpret_cast<x509String*>("OpenBMC");
-            // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-            x509String* cnStr = reinterpret_cast<x509String*>(cn.c_str());
-
-            X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, country, -1, -1,
-                                       0);
-            X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, company, -1, -1,
-                                       0);
-            X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, cnStr, -1, -1,
-                                       0);
-            // set the CSR options
-            X509_set_issuer_name(x509, name);
-
-            X509_set_version(x509, 2);
-            addExt(x509, NID_basic_constraints, ("critical,CA:TRUE"));
-            addExt(x509, NID_subject_alt_name, ("DNS:" + cn).c_str());
-            addExt(x509, NID_subject_key_identifier, ("hash"));
-            addExt(x509, NID_authority_key_identifier, ("keyid"));
-            addExt(x509, NID_key_usage, ("digitalSignature, keyEncipherment"));
-            addExt(x509, NID_ext_key_usage, ("serverAuth"));
-            addExt(x509, NID_netscape_comment, (x509Comment));
-
-            // Sign the certificate with our private key
-            X509_sign(x509, pPrivKey, EVP_sha256());
-
-            BIO* bufio = BIO_new(BIO_s_mem());
-
-            int pkeyRet = PEM_write_bio_PrivateKey(
-                bufio, pPrivKey, nullptr, nullptr, 0, nullptr, nullptr);
-            if (pkeyRet <= 0)
-            {
-                BMCWEB_LOG_ERROR(
-                    "Failed to write pkey with code {}.  Ignoring.", pkeyRet);
-            }
-
-            char* data = nullptr;
-            long int dataLen = BIO_get_mem_data(bufio, &data);
-            buffer += std::string_view(data, static_cast<size_t>(dataLen));
-            BIO_free(bufio);
-
-            bufio = BIO_new(BIO_s_mem());
-            pkeyRet = PEM_write_bio_X509(bufio, x509);
-            if (pkeyRet <= 0)
-            {
-                BMCWEB_LOG_ERROR(
-                    "Failed to write X509 with code {}.  Ignoring.", pkeyRet);
-            }
-            dataLen = BIO_get_mem_data(bufio, &data);
-            buffer += std::string_view(data, static_cast<size_t>(dataLen));
-
-            BIO_free(bufio);
-            BMCWEB_LOG_INFO("Cert size is {}", buffer.size());
-            X509_free(x509);
-        }
-
-        EVP_PKEY_free(pPrivKey);
-        pPrivKey = nullptr;
+        buffer = constructX509(cn, pPrivKey);
     }
 
-    // cleanup_openssl();
+    EVP_PKEY_free(pPrivKey);
+
     return buffer;
 }