diff --git a/http/mutual_tls.cpp b/http/mutual_tls.cpp
new file mode 100644
index 0000000..f579089
--- /dev/null
+++ b/http/mutual_tls.cpp
@@ -0,0 +1,131 @@
+#include "mutual_tls.hpp"
+
+extern "C"
+{
+#include <openssl/x509_vfy.h>
+}
+
+#include "logging.hpp"
+#include "mutual_tls_meta.hpp"
+#include "persistent_data.hpp"
+
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ssl/verify_context.hpp>
+
+#include <memory>
+#include <string_view>
+
+std::string getUsernameFromCommonName(std::string_view commonName)
+{
+    const persistent_data::AuthConfigMethods& authMethodsConfig =
+        persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
+    switch (authMethodsConfig.mTLSCommonNameParsingMode)
+    {
+        case persistent_data::MTLSCommonNameParseMode::Invalid:
+        case persistent_data::MTLSCommonNameParseMode::Whole:
+        case persistent_data::MTLSCommonNameParseMode::UserPrincipalName:
+        {
+            // Not yet supported
+            return "";
+        }
+        case persistent_data::MTLSCommonNameParseMode::CommonName:
+        {
+            return std::string{commonName};
+        }
+        case persistent_data::MTLSCommonNameParseMode::Meta:
+        {
+            // Meta Inc. CommonName parsing
+            std::optional<std::string_view> sslUserMeta =
+                mtlsMetaParseSslUser(commonName);
+            if (!sslUserMeta)
+            {
+                return "";
+            }
+            return std::string{*sslUserMeta};
+        }
+    }
+    return "";
+}
+
+std::shared_ptr<persistent_data::UserSession>
+    verifyMtlsUser(const boost::asio::ip::address& clientIp,
+                   boost::asio::ssl::verify_context& ctx)
+{
+    // do nothing if TLS is disabled
+    if (!persistent_data::SessionStore::getInstance()
+             .getAuthMethodsConfig()
+             .tls)
+    {
+        BMCWEB_LOG_DEBUG("TLS auth_config is disabled");
+        return nullptr;
+    }
+
+    X509_STORE_CTX* cts = ctx.native_handle();
+    if (cts == nullptr)
+    {
+        BMCWEB_LOG_DEBUG("Cannot get native TLS handle.");
+        return nullptr;
+    }
+
+    // Get certificate
+    X509* peerCert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
+    if (peerCert == nullptr)
+    {
+        BMCWEB_LOG_DEBUG("Cannot get current TLS certificate.");
+        return nullptr;
+    }
+
+    // Check if certificate is OK
+    int ctxError = X509_STORE_CTX_get_error(cts);
+    if (ctxError != X509_V_OK)
+    {
+        BMCWEB_LOG_INFO("Last TLS error is: {}", ctxError);
+        return nullptr;
+    }
+
+    // Check that we have reached final certificate in chain
+    int32_t depth = X509_STORE_CTX_get_error_depth(cts);
+    if (depth != 0)
+    {
+        BMCWEB_LOG_DEBUG(
+            "Certificate verification in progress (depth {}), waiting to reach final depth",
+            depth);
+        return nullptr;
+    }
+
+    BMCWEB_LOG_DEBUG("Certificate verification of final depth");
+
+    if (X509_check_purpose(peerCert, X509_PURPOSE_SSL_CLIENT, 0) != 1)
+    {
+        BMCWEB_LOG_DEBUG(
+            "Chain does not allow certificate to be used for SSL client authentication");
+        return nullptr;
+    }
+
+    std::string commonName;
+    // Extract username contained in CommonName
+    commonName.resize(256, '\0');
+
+    int length = X509_NAME_get_text_by_NID(X509_get_subject_name(peerCert),
+                                           NID_commonName, commonName.data(),
+                                           static_cast<int>(commonName.size()));
+    if (length <= 0)
+    {
+        BMCWEB_LOG_DEBUG("TLS cannot get common name to create session");
+        return nullptr;
+    }
+
+    commonName.resize(static_cast<size_t>(length));
+    std::string sslUser = getUsernameFromCommonName(commonName);
+    if (sslUser.empty())
+    {
+        BMCWEB_LOG_WARNING("Failed to get user from common name {}",
+                           commonName);
+        return nullptr;
+    }
+
+    std::string unsupportedClientId;
+    return persistent_data::SessionStore::getInstance().generateUserSession(
+        sslUser, clientIp, unsupportedClientId,
+        persistent_data::SessionType::MutualTLS);
+}
diff --git a/http/mutual_tls.hpp b/http/mutual_tls.hpp
index eb26b5a..2af46f2 100644
--- a/http/mutual_tls.hpp
+++ b/http/mutual_tls.hpp
@@ -1,132 +1,15 @@
 #pragma once
 
-#include "logging.hpp"
-#include "mutual_tls_meta.hpp"
 #include "persistent_data.hpp"
 
-extern "C"
-{
-#include <openssl/crypto.h>
-#include <openssl/ssl.h>
-}
-
 #include <boost/asio/ip/address.hpp>
 #include <boost/asio/ssl/verify_context.hpp>
 
 #include <memory>
-#include <span>
+#include <string_view>
 
-inline std::string getUsernameFromCommonName(std::string_view commonName)
-{
-    const persistent_data::AuthConfigMethods& authMethodsConfig =
-        persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
-    switch (authMethodsConfig.mTLSCommonNameParsingMode)
-    {
-        case persistent_data::MTLSCommonNameParseMode::Invalid:
-        case persistent_data::MTLSCommonNameParseMode::Whole:
-        case persistent_data::MTLSCommonNameParseMode::UserPrincipalName:
-        {
-            // Not yet supported
-            return "";
-        }
-        case persistent_data::MTLSCommonNameParseMode::CommonName:
-        {
-            return std::string{commonName};
-        }
-        case persistent_data::MTLSCommonNameParseMode::Meta:
-        {
-            // Meta Inc. CommonName parsing
-            std::optional<std::string_view> sslUserMeta =
-                mtlsMetaParseSslUser(commonName);
-            if (!sslUserMeta)
-            {
-                return "";
-            }
-            return std::string{*sslUserMeta};
-        }
-    }
-    return "";
-}
+std::string getUsernameFromCommonName(std::string_view commonName);
 
-inline std::shared_ptr<persistent_data::UserSession>
+std::shared_ptr<persistent_data::UserSession>
     verifyMtlsUser(const boost::asio::ip::address& clientIp,
-                   boost::asio::ssl::verify_context& ctx)
-{
-    // do nothing if TLS is disabled
-    if (!persistent_data::SessionStore::getInstance()
-             .getAuthMethodsConfig()
-             .tls)
-    {
-        BMCWEB_LOG_DEBUG("TLS auth_config is disabled");
-        return nullptr;
-    }
-
-    X509_STORE_CTX* cts = ctx.native_handle();
-    if (cts == nullptr)
-    {
-        BMCWEB_LOG_DEBUG("Cannot get native TLS handle.");
-        return nullptr;
-    }
-
-    // Get certificate
-    X509* peerCert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
-    if (peerCert == nullptr)
-    {
-        BMCWEB_LOG_DEBUG("Cannot get current TLS certificate.");
-        return nullptr;
-    }
-
-    // Check if certificate is OK
-    int ctxError = X509_STORE_CTX_get_error(cts);
-    if (ctxError != X509_V_OK)
-    {
-        BMCWEB_LOG_INFO("Last TLS error is: {}", ctxError);
-        return nullptr;
-    }
-
-    // Check that we have reached final certificate in chain
-    int32_t depth = X509_STORE_CTX_get_error_depth(cts);
-    if (depth != 0)
-    {
-        BMCWEB_LOG_DEBUG(
-            "Certificate verification in progress (depth {}), waiting to reach final depth",
-            depth);
-        return nullptr;
-    }
-
-    BMCWEB_LOG_DEBUG("Certificate verification of final depth");
-
-    if (X509_check_purpose(peerCert, X509_PURPOSE_SSL_CLIENT, 0) != 1)
-    {
-        BMCWEB_LOG_DEBUG(
-            "Chain does not allow certificate to be used for SSL client authentication");
-        return nullptr;
-    }
-
-    std::string commonName;
-    // Extract username contained in CommonName
-    commonName.resize(256, '\0');
-
-    int length = X509_NAME_get_text_by_NID(X509_get_subject_name(peerCert),
-                                           NID_commonName, commonName.data(),
-                                           static_cast<int>(commonName.size()));
-    if (length <= 0)
-    {
-        BMCWEB_LOG_DEBUG("TLS cannot get common name to create session");
-        return nullptr;
-    }
-
-    commonName.resize(static_cast<size_t>(length));
-    std::string sslUser = getUsernameFromCommonName(commonName);
-    if (sslUser.empty())
-    {
-        BMCWEB_LOG_WARNING("Failed to get user from common name {}",
-                           commonName);
-        return nullptr;
-    }
-
-    std::string unsupportedClientId;
-    return persistent_data::SessionStore::getInstance().generateUserSession(
-        sslUser, clientIp, unsupportedClientId,
-        persistent_data::SessionType::MutualTLS);
-}
+                   boost::asio::ssl::verify_context& ctx);
diff --git a/http/utility.hpp b/http/utility.hpp
index da174e5..41b48e4 100644
--- a/http/utility.hpp
+++ b/http/utility.hpp
@@ -2,11 +2,6 @@
 
 #include "bmcweb_config.h"
 
-extern "C"
-{
-#include <openssl/crypto.h>
-}
-
 #include <boost/callable_traits.hpp>
 #include <boost/url/parse.hpp>
 #include <boost/url/url.hpp>
@@ -313,25 +308,6 @@
     return true;
 }
 
-inline bool constantTimeStringCompare(std::string_view a, std::string_view b)
-{
-    // Important note, this function is ONLY constant time if the two input
-    // sizes are the same
-    if (a.size() != b.size())
-    {
-        return false;
-    }
-    return CRYPTO_memcmp(a.data(), b.data(), a.size()) == 0;
-}
-
-struct ConstantTimeCompare
-{
-    bool operator()(std::string_view a, std::string_view b) const
-    {
-        return constantTimeStringCompare(a, b);
-    }
-};
-
 namespace details
 {
 inline boost::urls::url
diff --git a/http/websocket.hpp b/http/websocket.hpp
index e8d7b12..7e38302 100644
--- a/http/websocket.hpp
+++ b/http/websocket.hpp
@@ -99,8 +99,8 @@
                 {
                     // use protocol for csrf checking
                     if (session->cookieAuth &&
-                        !crow::utility::constantTimeStringCompare(
-                            protocolHeader, session->csrfToken))
+                        !bmcweb::constantTimeStringCompare(protocolHeader,
+                                                           session->csrfToken))
                     {
                         BMCWEB_LOG_ERROR("Websocket CSRF error");
                         m.result(boost::beast::http::status::unauthorized);
diff --git a/include/authentication.hpp b/include/authentication.hpp
index 221e197..6199808 100644
--- a/include/authentication.hpp
+++ b/include/authentication.hpp
@@ -171,8 +171,8 @@
                     return nullptr;
                 }
                 // Reject if csrf token not available
-                if (!crow::utility::constantTimeStringCompare(
-                        csrf, sessionOut->csrfToken))
+                if (!bmcweb::constantTimeStringCompare(csrf,
+                                                       sessionOut->csrfToken))
                 {
                     return nullptr;
                 }
diff --git a/include/ossl_random.hpp b/include/ossl_random.hpp
index 0a92e37..70e5ed0 100644
--- a/include/ossl_random.hpp
+++ b/include/ossl_random.hpp
@@ -39,4 +39,10 @@
 
 std::string getRandomIdOfLength(size_t length);
 
+bool constantTimeStringCompare(std::string_view a, std::string_view b);
+struct ConstantTimeCompare
+{
+    bool operator()(std::string_view a, std::string_view b) const;
+};
+
 } // namespace bmcweb
diff --git a/include/sessions.hpp b/include/sessions.hpp
index 9f93259..d97c54d 100644
--- a/include/sessions.hpp
+++ b/include/sessions.hpp
@@ -470,8 +470,7 @@
     ~SessionStore() = default;
 
     std::unordered_map<std::string, std::shared_ptr<UserSession>,
-                       std::hash<std::string>,
-                       crow::utility::ConstantTimeCompare>
+                       std::hash<std::string>, bmcweb::ConstantTimeCompare>
         authTokens;
 
     std::chrono::time_point<std::chrono::steady_clock> lastTimeoutUpdate;
diff --git a/include/ssl_key_handler.hpp b/include/ssl_key_handler.hpp
index 30a037c..7670bcb 100644
--- a/include/ssl_key_handler.hpp
+++ b/include/ssl_key_handler.hpp
@@ -1,567 +1,14 @@
+
+
 #pragma once
 
-#include "bmcweb_config.h"
-
-#include "logging.hpp"
-#include "ossl_random.hpp"
-#include "persistent_data.hpp"
-
-#include <boost/beast/core/file_posix.hpp>
-
-extern "C"
-{
-#include <nghttp2/nghttp2.h>
-#include <openssl/bio.h>
-#include <openssl/dh.h>
-#include <openssl/dsa.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/pem.h>
-#include <openssl/rand.h>
-#include <openssl/rsa.h>
-#include <openssl/ssl.h>
-}
-
 #include <boost/asio/ssl/context.hpp>
-#include <boost/system/error_code.hpp>
 
-#include <filesystem>
-#include <memory>
 #include <optional>
-#include <random>
 #include <string>
 
 namespace ensuressl
 {
-constexpr const char* trustStorePath = "/etc/ssl/certs/authority";
-constexpr const char* x509Comment = "Generated from OpenBMC service";
-static EVP_PKEY* createEcKey();
-
-// Mozilla intermediate cipher suites v5.7
-// Sourced from: https://ssl-config.mozilla.org/guidelines/5.7.json
-constexpr const char* mozillaIntermediate = "ECDHE-ECDSA-AES128-GCM-SHA256:"
-                                            "ECDHE-RSA-AES128-GCM-SHA256:"
-                                            "ECDHE-ECDSA-AES256-GCM-SHA384:"
-                                            "ECDHE-RSA-AES256-GCM-SHA384:"
-                                            "ECDHE-ECDSA-CHACHA20-POLY1305:"
-                                            "ECDHE-RSA-CHACHA20-POLY1305:"
-                                            "DHE-RSA-AES128-GCM-SHA256:"
-                                            "DHE-RSA-AES256-GCM-SHA384:"
-                                            "DHE-RSA-CHACHA20-POLY1305";
-
-// Trust chain related errors.`
-inline bool isTrustChainError(int errnum)
-{
-    return (errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ||
-           (errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) ||
-           (errnum == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) ||
-           (errnum == X509_V_ERR_CERT_UNTRUSTED) ||
-           (errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
-}
-
-inline bool validateCertificate(X509* const cert)
-{
-    // Create an empty X509_STORE structure for certificate validation.
-    X509_STORE* x509Store = X509_STORE_new();
-    if (x509Store == nullptr)
-    {
-        BMCWEB_LOG_ERROR("Error occurred during X509_STORE_new call");
-        return false;
-    }
-
-    // Load Certificate file into the X509 structure.
-    X509_STORE_CTX* storeCtx = X509_STORE_CTX_new();
-    if (storeCtx == nullptr)
-    {
-        BMCWEB_LOG_ERROR("Error occurred during X509_STORE_CTX_new call");
-        X509_STORE_free(x509Store);
-        return false;
-    }
-
-    int errCode = X509_STORE_CTX_init(storeCtx, x509Store, cert, nullptr);
-    if (errCode != 1)
-    {
-        BMCWEB_LOG_ERROR("Error occurred during X509_STORE_CTX_init call");
-        X509_STORE_CTX_free(storeCtx);
-        X509_STORE_free(x509Store);
-        return false;
-    }
-
-    errCode = X509_verify_cert(storeCtx);
-    if (errCode == 1)
-    {
-        BMCWEB_LOG_INFO("Certificate verification is success");
-        X509_STORE_CTX_free(storeCtx);
-        X509_STORE_free(x509Store);
-        return true;
-    }
-    if (errCode == 0)
-    {
-        errCode = X509_STORE_CTX_get_error(storeCtx);
-        X509_STORE_CTX_free(storeCtx);
-        X509_STORE_free(x509Store);
-        if (isTrustChainError(errCode))
-        {
-            BMCWEB_LOG_DEBUG("Ignoring Trust Chain error. Reason: {}",
-                             X509_verify_cert_error_string(errCode));
-            return true;
-        }
-        BMCWEB_LOG_ERROR("Certificate verification failed. Reason: {}",
-                         X509_verify_cert_error_string(errCode));
-        return false;
-    }
-
-    BMCWEB_LOG_ERROR(
-        "Error occurred during X509_verify_cert call. ErrorCode: {}", errCode);
-    X509_STORE_CTX_free(storeCtx);
-    X509_STORE_free(x509Store);
-    return false;
-}
-
-inline std::string verifyOpensslKeyCert(const std::string& filepath)
-{
-    bool privateKeyValid = false;
-
-    BMCWEB_LOG_INFO("Checking certs in file {}", filepath);
-    boost::beast::file_posix file;
-    boost::system::error_code ec;
-    file.open(filepath.c_str(), boost::beast::file_mode::read, ec);
-    if (ec)
-    {
-        return "";
-    }
-    bool certValid = false;
-    std::string fileContents;
-    fileContents.resize(static_cast<size_t>(file.size(ec)), '\0');
-    file.read(fileContents.data(), fileContents.size(), ec);
-    if (ec)
-    {
-        BMCWEB_LOG_ERROR("Failed to read file");
-        return "";
-    }
-
-    BIO* bufio = BIO_new_mem_buf(static_cast<void*>(fileContents.data()),
-                                 static_cast<int>(fileContents.size()));
-    EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bufio, nullptr, nullptr, nullptr);
-    BIO_free(bufio);
-    if (pkey != nullptr)
-    {
-        EVP_PKEY_CTX* pkeyCtx = EVP_PKEY_CTX_new_from_pkey(nullptr, pkey,
-                                                           nullptr);
-
-        if (pkeyCtx == nullptr)
-        {
-            BMCWEB_LOG_ERROR("Unable to allocate pkeyCtx {}", ERR_get_error());
-        }
-        else if (EVP_PKEY_check(pkeyCtx) == 1)
-        {
-            privateKeyValid = true;
-        }
-        else
-        {
-            BMCWEB_LOG_ERROR("Key not valid error number {}", ERR_get_error());
-        }
-
-        if (privateKeyValid)
-        {
-            BIO* bufio2 =
-                BIO_new_mem_buf(static_cast<void*>(fileContents.data()),
-                                static_cast<int>(fileContents.size()));
-            X509* x509 = PEM_read_bio_X509(bufio2, nullptr, nullptr, nullptr);
-            BIO_free(bufio2);
-            if (x509 == nullptr)
-            {
-                BMCWEB_LOG_ERROR("error getting x509 cert {}", ERR_get_error());
-            }
-            else
-            {
-                certValid = validateCertificate(x509);
-                X509_free(x509);
-            }
-        }
-
-        EVP_PKEY_CTX_free(pkeyCtx);
-        EVP_PKEY_free(pkey);
-    }
-    if (!certValid)
-    {
-        return "";
-    }
-    return fileContents;
-}
-
-inline X509* loadCert(const std::string& filePath)
-{
-    BIO* certFileBio = BIO_new_file(filePath.c_str(), "rb");
-    if (certFileBio == nullptr)
-    {
-        BMCWEB_LOG_ERROR("Error occurred during BIO_new_file call, FILE= {}",
-                         filePath);
-        return nullptr;
-    }
-
-    X509* cert = X509_new();
-    if (cert == nullptr)
-    {
-        BMCWEB_LOG_ERROR("Error occurred during X509_new call, {}",
-                         ERR_get_error());
-        BIO_free(certFileBio);
-        return nullptr;
-    }
-
-    if (PEM_read_bio_X509(certFileBio, &cert, nullptr, nullptr) == nullptr)
-    {
-        BMCWEB_LOG_ERROR(
-            "Error occurred during PEM_read_bio_X509 call, FILE= {}", filePath);
-
-        BIO_free(certFileBio);
-        X509_free(cert);
-        return nullptr;
-    }
-    BIO_free(certFileBio);
-    return cert;
-}
-
-inline int addExt(X509* cert, int nid, const char* value)
-{
-    X509_EXTENSION* ex = nullptr;
-    X509V3_CTX ctx{};
-    X509V3_set_ctx(&ctx, cert, cert, nullptr, nullptr, 0);
-
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
-    ex = X509V3_EXT_conf_nid(nullptr, &ctx, nid, const_cast<char*>(value));
-    if (ex == nullptr)
-    {
-        BMCWEB_LOG_ERROR("Error: In X509V3_EXT_conf_nidn: {}", value);
-        return -1;
-    }
-    X509_add_ext(cert, ex, -1);
-    X509_EXTENSION_free(ex);
-    return 0;
-}
-
-// Writes a certificate to a path, ignoring errors
-inline void writeCertificateToFile(const std::string& filepath,
-                                   const std::string& certificate)
-{
-    boost::system::error_code ec;
-    boost::beast::file_posix file;
-    file.open(filepath.c_str(), boost::beast::file_mode::write, ec);
-    if (!ec)
-    {
-        file.write(certificate.data(), certificate.size(), ec);
-        // ignore result
-    }
-}
-
-inline std::string generateSslCertificate(const std::string& cn)
-{
-    BMCWEB_LOG_INFO("Generating new keys");
-
-    std::string buffer;
-    BMCWEB_LOG_INFO("Generating EC key");
-    EVP_PKEY* pPrivKey = createEcKey();
-    if (pPrivKey != nullptr)
-    {
-        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;
-    }
-
-    // cleanup_openssl();
-    return buffer;
-}
-
-EVP_PKEY* createEcKey()
-{
-    EVP_PKEY* pKey = nullptr;
-
-    // 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;
-    }
-
-    return pKey;
-}
-
-inline std::string ensureOpensslKeyPresentAndValid(const std::string& filepath)
-{
-    std::string cert = verifyOpensslKeyCert(filepath);
-
-    if (cert.empty())
-    {
-        BMCWEB_LOG_WARNING("Error in verifying signature, regenerating");
-        cert = generateSslCertificate("testhost");
-        if (cert.empty())
-        {
-            BMCWEB_LOG_ERROR("Failed to generate cert");
-        }
-        else
-        {
-            writeCertificateToFile(filepath, cert);
-        }
-    }
-    return cert;
-}
-
-inline std::string ensureCertificate()
-{
-    namespace fs = std::filesystem;
-    // Cleanup older certificate file existing in the system
-    fs::path oldcertPath = fs::path("/home/root/server.pem");
-    std::error_code ec;
-    fs::remove(oldcertPath, ec);
-    // Ignore failure to remove;  File might not exist.
-
-    fs::path certPath = "/etc/ssl/certs/https/";
-    // if path does not exist create the path so that
-    // self signed certificate can be created in the
-    // path
-    fs::path certFile = certPath / "server.pem";
-
-    if (!fs::exists(certPath, ec))
-    {
-        fs::create_directories(certPath, ec);
-    }
-    BMCWEB_LOG_INFO("Building SSL Context file= {}", certFile.string());
-    std::string sslPemFile(certFile);
-    return ensuressl::ensureOpensslKeyPresentAndValid(sslPemFile);
-}
-
-inline int nextProtoCallback(SSL* /*unused*/, const unsigned char** data,
-                             unsigned int* len, void* /*unused*/)
-{
-    // First byte is the length.
-    constexpr std::string_view h2 = "\x02h2";
-    *data = std::bit_cast<const unsigned char*>(h2.data());
-    *len = static_cast<unsigned int>(h2.size());
-    return SSL_TLSEXT_ERR_OK;
-}
-
-inline int alpnSelectProtoCallback(SSL* /*unused*/, const unsigned char** out,
-                                   unsigned char* outlen,
-                                   const unsigned char* in, unsigned int inlen,
-                                   void* /*unused*/)
-{
-    // There's a mismatch in constness for nghttp2_select_next_protocol.  The
-    // examples in nghttp2 don't show this problem.  Unclear what the right fix
-    // is here.
-
-    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
-    unsigned char** outNew = const_cast<unsigned char**>(out);
-    int rv = nghttp2_select_next_protocol(outNew, outlen, in, inlen);
-    if (rv != 1)
-    {
-        return SSL_TLSEXT_ERR_NOACK;
-    }
-
-    return SSL_TLSEXT_ERR_OK;
-}
-
-inline bool getSslContext(boost::asio::ssl::context& mSslContext,
-                          const std::string& sslPemFile)
-{
-    mSslContext.set_options(boost::asio::ssl::context::default_workarounds |
-                            boost::asio::ssl::context::no_sslv2 |
-                            boost::asio::ssl::context::no_sslv3 |
-                            boost::asio::ssl::context::single_dh_use |
-                            boost::asio::ssl::context::no_tlsv1 |
-                            boost::asio::ssl::context::no_tlsv1_1);
-
-    BMCWEB_LOG_DEBUG("Using default TrustStore location: {}", trustStorePath);
-    mSslContext.add_verify_path(trustStorePath);
-
-    if (!sslPemFile.empty())
-    {
-        boost::system::error_code ec;
-
-        boost::asio::const_buffer buf(sslPemFile.data(), sslPemFile.size());
-        mSslContext.use_certificate(buf, boost::asio::ssl::context::pem, ec);
-        if (ec)
-        {
-            return false;
-        }
-        mSslContext.use_private_key(buf, boost::asio::ssl::context::pem, ec);
-        if (ec)
-        {
-            BMCWEB_LOG_CRITICAL("Failed to open ssl pkey");
-            return false;
-        }
-    }
-
-    // Set up EC curves to auto (boost asio doesn't have a method for this)
-    // There is a pull request to add this.  Once this is included in an asio
-    // drop, use the right way
-    // http://stackoverflow.com/questions/18929049/boost-asio-with-ecdsa-certificate-issue
-    if (SSL_CTX_set_ecdh_auto(mSslContext.native_handle(), 1) != 1)
-    {}
-
-    if (SSL_CTX_set_cipher_list(mSslContext.native_handle(),
-                                mozillaIntermediate) != 1)
-    {
-        BMCWEB_LOG_ERROR("Error setting cipher list");
-        return false;
-    }
-    return true;
-}
-
-inline std::shared_ptr<boost::asio::ssl::context> getSslServerContext()
-{
-    boost::asio::ssl::context sslCtx(boost::asio::ssl::context::tls_server);
-
-    auto certFile = ensureCertificate();
-    if (!getSslContext(sslCtx, certFile))
-    {
-        BMCWEB_LOG_CRITICAL("Couldn't get server context");
-        return nullptr;
-    }
-    const persistent_data::AuthConfigMethods& c =
-        persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
-
-    boost::asio::ssl::verify_mode mode = boost::asio::ssl::verify_peer;
-    if (c.tlsStrict)
-    {
-        BMCWEB_LOG_DEBUG("Setting verify peer");
-        mode |= boost::asio::ssl::verify_fail_if_no_peer_cert;
-    }
-
-    boost::system::error_code ec;
-    sslCtx.set_verify_mode(mode, ec);
-    if (ec)
-    {
-        BMCWEB_LOG_DEBUG("Failed to set verify mode {}", ec.message());
-        return nullptr;
-    }
-    SSL_CTX_set_options(sslCtx.native_handle(), SSL_OP_NO_RENEGOTIATION);
-
-    if constexpr (BMCWEB_EXPERIMENTAL_HTTP2)
-    {
-        SSL_CTX_set_next_protos_advertised_cb(sslCtx.native_handle(),
-                                              nextProtoCallback, nullptr);
-
-        SSL_CTX_set_alpn_select_cb(sslCtx.native_handle(),
-                                   alpnSelectProtoCallback, nullptr);
-    }
-
-    return std::make_shared<boost::asio::ssl::context>(std::move(sslCtx));
-}
 
 enum class VerifyCertificate
 {
@@ -569,55 +16,29 @@
     NoVerify
 };
 
-inline std::optional<boost::asio::ssl::context>
-    getSSLClientContext(VerifyCertificate verifyCertificate)
-{
-    namespace fs = std::filesystem;
+constexpr const char* trustStorePath = "/etc/ssl/certs/authority";
+constexpr const char* x509Comment = "Generated from OpenBMC service";
 
-    boost::asio::ssl::context sslCtx(boost::asio::ssl::context::tls_client);
+bool isTrustChainError(int errnum);
 
-    // NOTE, this path is temporary;  In the future it will need to change to
-    // be set per subscription.  Do not rely on this.
-    fs::path certPath = "/etc/ssl/certs/https/client.pem";
-    std::string cert = verifyOpensslKeyCert(certPath);
+bool validateCertificate(X509* cert);
 
-    if (!getSslContext(sslCtx, cert))
-    {
-        return std::nullopt;
-    }
+std::string verifyOpensslKeyCert(const std::string& filepath);
 
-    // Add a directory containing certificate authority files to be used
-    // for performing verification.
-    boost::system::error_code ec;
-    sslCtx.set_default_verify_paths(ec);
-    if (ec)
-    {
-        BMCWEB_LOG_ERROR("SSL context set_default_verify failed");
-        return std::nullopt;
-    }
+X509* loadCert(const std::string& filePath);
 
-    int mode = boost::asio::ssl::verify_peer;
-    if (verifyCertificate == VerifyCertificate::NoVerify)
-    {
-        mode = boost::asio::ssl::verify_none;
-    }
+int addExt(X509* cert, int nid, const char* value);
 
-    // Verify the remote server's certificate
-    sslCtx.set_verify_mode(mode, ec);
-    if (ec)
-    {
-        BMCWEB_LOG_ERROR("SSL context set_verify_mode failed");
-        return std::nullopt;
-    }
+std::string generateSslCertificate(const std::string& cn);
 
-    if (SSL_CTX_set_cipher_list(sslCtx.native_handle(), mozillaIntermediate) !=
-        1)
-    {
-        BMCWEB_LOG_ERROR("SSL_CTX_set_cipher_list failed");
-        return std::nullopt;
-    }
+void writeCertificateToFile(const std::string& filepath,
+                            const std::string& certificate);
 
-    return {std::move(sslCtx)};
-}
+std::string ensureOpensslKeyPresentAndValid(const std::string& filepath);
+
+std::shared_ptr<boost::asio::ssl::context> getSslServerContext();
+
+std::optional<boost::asio::ssl::context>
+    getSSLClientContext(VerifyCertificate verifyCertificate);
 
 } // namespace ensuressl
diff --git a/meson.build b/meson.build
index bce2c95..5a4ec87 100644
--- a/meson.build
+++ b/meson.build
@@ -86,6 +86,7 @@
         '-Wno-unused-macros',
         '-Wno-covered-switch-default',
         '-Wno-disabled-macro-expansion',
+        '-Wno-unneeded-internal-declaration',
         language: 'cpp',
     )
 endif
@@ -327,10 +328,8 @@
 fs = import('fs')
 
 srcfiles_bmcweb = files(
-    # end large files
-
+    'http/mutual_tls.cpp',
     'redfish-core/src/error_messages.cpp',
-    # Begin large files, should be at the beginning
     'redfish-core/src/filter_expr_executor.cpp',
     'redfish-core/src/filter_expr_printer.cpp',
     'redfish-core/src/redfish.cpp',
@@ -344,6 +343,7 @@
     'src/dbus_singleton.cpp',
     'src/json_html_serializer.cpp',
     'src/ossl_random.cpp',
+    'src/ssl_key_handler.cpp',
     'src/webserver_run.cpp',
 )
 
diff --git a/src/ossl_random.cpp b/src/ossl_random.cpp
index 419fe31..487f986 100644
--- a/src/ossl_random.cpp
+++ b/src/ossl_random.cpp
@@ -2,6 +2,7 @@
 
 extern "C"
 {
+#include <openssl/crypto.h>
 #include <openssl/rand.h>
 }
 
@@ -60,4 +61,22 @@
     }
     return token;
 }
+
+bool constantTimeStringCompare(std::string_view a, std::string_view b)
+{
+    // Important note, this function is ONLY constant time if the two input
+    // sizes are the same
+    if (a.size() != b.size())
+    {
+        return false;
+    }
+    return CRYPTO_memcmp(a.data(), b.data(), a.size()) == 0;
+}
+
+bool ConstantTimeCompare::operator()(std::string_view a,
+                                     std::string_view b) const
+{
+    return constantTimeStringCompare(a, b);
+}
+
 } // namespace bmcweb
diff --git a/src/ssl_key_handler.cpp b/src/ssl_key_handler.cpp
new file mode 100644
index 0000000..4423508
--- /dev/null
+++ b/src/ssl_key_handler.cpp
@@ -0,0 +1,616 @@
+#include "ssl_key_handler.hpp"
+
+#include "bmcweb_config.h"
+
+#include "logging.hpp"
+#include "ossl_random.hpp"
+#include "persistent_data.hpp"
+
+#include <boost/beast/core/file_posix.hpp>
+
+extern "C"
+{
+#include <nghttp2/nghttp2.h>
+#include <openssl/bio.h>
+#include <openssl/dh.h>
+#include <openssl/dsa.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/rsa.h>
+#include <openssl/ssl.h>
+}
+
+#include <boost/asio/ssl/context.hpp>
+#include <boost/system/error_code.hpp>
+
+#include <filesystem>
+#include <memory>
+#include <optional>
+#include <random>
+#include <string>
+
+namespace ensuressl
+{
+
+static EVP_PKEY* createEcKey();
+
+// Mozilla intermediate cipher suites v5.7
+// Sourced from: https://ssl-config.mozilla.org/guidelines/5.7.json
+constexpr const char* mozillaIntermediate = "ECDHE-ECDSA-AES128-GCM-SHA256:"
+                                            "ECDHE-RSA-AES128-GCM-SHA256:"
+                                            "ECDHE-ECDSA-AES256-GCM-SHA384:"
+                                            "ECDHE-RSA-AES256-GCM-SHA384:"
+                                            "ECDHE-ECDSA-CHACHA20-POLY1305:"
+                                            "ECDHE-RSA-CHACHA20-POLY1305:"
+                                            "DHE-RSA-AES128-GCM-SHA256:"
+                                            "DHE-RSA-AES256-GCM-SHA384:"
+                                            "DHE-RSA-CHACHA20-POLY1305";
+
+// Trust chain related errors.`
+bool isTrustChainError(int errnum)
+{
+    return (errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) ||
+           (errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) ||
+           (errnum == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) ||
+           (errnum == X509_V_ERR_CERT_UNTRUSTED) ||
+           (errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
+}
+
+bool validateCertificate(X509* const cert)
+{
+    // Create an empty X509_STORE structure for certificate validation.
+    X509_STORE* x509Store = X509_STORE_new();
+    if (x509Store == nullptr)
+    {
+        BMCWEB_LOG_ERROR("Error occurred during X509_STORE_new call");
+        return false;
+    }
+
+    // Load Certificate file into the X509 structure.
+    X509_STORE_CTX* storeCtx = X509_STORE_CTX_new();
+    if (storeCtx == nullptr)
+    {
+        BMCWEB_LOG_ERROR("Error occurred during X509_STORE_CTX_new call");
+        X509_STORE_free(x509Store);
+        return false;
+    }
+
+    int errCode = X509_STORE_CTX_init(storeCtx, x509Store, cert, nullptr);
+    if (errCode != 1)
+    {
+        BMCWEB_LOG_ERROR("Error occurred during X509_STORE_CTX_init call");
+        X509_STORE_CTX_free(storeCtx);
+        X509_STORE_free(x509Store);
+        return false;
+    }
+
+    errCode = X509_verify_cert(storeCtx);
+    if (errCode == 1)
+    {
+        BMCWEB_LOG_INFO("Certificate verification is success");
+        X509_STORE_CTX_free(storeCtx);
+        X509_STORE_free(x509Store);
+        return true;
+    }
+    if (errCode == 0)
+    {
+        errCode = X509_STORE_CTX_get_error(storeCtx);
+        X509_STORE_CTX_free(storeCtx);
+        X509_STORE_free(x509Store);
+        if (isTrustChainError(errCode))
+        {
+            BMCWEB_LOG_DEBUG("Ignoring Trust Chain error. Reason: {}",
+                             X509_verify_cert_error_string(errCode));
+            return true;
+        }
+        BMCWEB_LOG_ERROR("Certificate verification failed. Reason: {}",
+                         X509_verify_cert_error_string(errCode));
+        return false;
+    }
+
+    BMCWEB_LOG_ERROR(
+        "Error occurred during X509_verify_cert call. ErrorCode: {}", errCode);
+    X509_STORE_CTX_free(storeCtx);
+    X509_STORE_free(x509Store);
+    return false;
+}
+
+std::string verifyOpensslKeyCert(const std::string& filepath)
+{
+    bool privateKeyValid = false;
+
+    BMCWEB_LOG_INFO("Checking certs in file {}", filepath);
+    boost::beast::file_posix file;
+    boost::system::error_code ec;
+    file.open(filepath.c_str(), boost::beast::file_mode::read, ec);
+    if (ec)
+    {
+        return "";
+    }
+    bool certValid = false;
+    std::string fileContents;
+    fileContents.resize(static_cast<size_t>(file.size(ec)), '\0');
+    file.read(fileContents.data(), fileContents.size(), ec);
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR("Failed to read file");
+        return "";
+    }
+
+    BIO* bufio = BIO_new_mem_buf(static_cast<void*>(fileContents.data()),
+                                 static_cast<int>(fileContents.size()));
+    EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bufio, nullptr, nullptr, nullptr);
+    BIO_free(bufio);
+    if (pkey != nullptr)
+    {
+        EVP_PKEY_CTX* pkeyCtx = EVP_PKEY_CTX_new_from_pkey(nullptr, pkey,
+                                                           nullptr);
+
+        if (pkeyCtx == nullptr)
+        {
+            BMCWEB_LOG_ERROR("Unable to allocate pkeyCtx {}", ERR_get_error());
+        }
+        else if (EVP_PKEY_check(pkeyCtx) == 1)
+        {
+            privateKeyValid = true;
+        }
+        else
+        {
+            BMCWEB_LOG_ERROR("Key not valid error number {}", ERR_get_error());
+        }
+
+        if (privateKeyValid)
+        {
+            BIO* bufio2 =
+                BIO_new_mem_buf(static_cast<void*>(fileContents.data()),
+                                static_cast<int>(fileContents.size()));
+            X509* x509 = PEM_read_bio_X509(bufio2, nullptr, nullptr, nullptr);
+            BIO_free(bufio2);
+            if (x509 == nullptr)
+            {
+                BMCWEB_LOG_ERROR("error getting x509 cert {}", ERR_get_error());
+            }
+            else
+            {
+                certValid = validateCertificate(x509);
+                X509_free(x509);
+            }
+        }
+
+        EVP_PKEY_CTX_free(pkeyCtx);
+        EVP_PKEY_free(pkey);
+    }
+    if (!certValid)
+    {
+        return "";
+    }
+    return fileContents;
+}
+
+X509* loadCert(const std::string& filePath)
+{
+    BIO* certFileBio = BIO_new_file(filePath.c_str(), "rb");
+    if (certFileBio == nullptr)
+    {
+        BMCWEB_LOG_ERROR("Error occurred during BIO_new_file call, FILE= {}",
+                         filePath);
+        return nullptr;
+    }
+
+    X509* cert = X509_new();
+    if (cert == nullptr)
+    {
+        BMCWEB_LOG_ERROR("Error occurred during X509_new call, {}",
+                         ERR_get_error());
+        BIO_free(certFileBio);
+        return nullptr;
+    }
+
+    if (PEM_read_bio_X509(certFileBio, &cert, nullptr, nullptr) == nullptr)
+    {
+        BMCWEB_LOG_ERROR(
+            "Error occurred during PEM_read_bio_X509 call, FILE= {}", filePath);
+
+        BIO_free(certFileBio);
+        X509_free(cert);
+        return nullptr;
+    }
+    BIO_free(certFileBio);
+    return cert;
+}
+
+int addExt(X509* cert, int nid, const char* value)
+{
+    X509_EXTENSION* ex = nullptr;
+    X509V3_CTX ctx{};
+    X509V3_set_ctx(&ctx, cert, cert, nullptr, nullptr, 0);
+
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
+    ex = X509V3_EXT_conf_nid(nullptr, &ctx, nid, const_cast<char*>(value));
+    if (ex == nullptr)
+    {
+        BMCWEB_LOG_ERROR("Error: In X509V3_EXT_conf_nidn: {}", value);
+        return -1;
+    }
+    X509_add_ext(cert, ex, -1);
+    X509_EXTENSION_free(ex);
+    return 0;
+}
+
+// Writes a certificate to a path, ignoring errors
+void writeCertificateToFile(const std::string& filepath,
+                            const std::string& certificate)
+{
+    boost::system::error_code ec;
+    boost::beast::file_posix file;
+    file.open(filepath.c_str(), boost::beast::file_mode::write, ec);
+    if (!ec)
+    {
+        file.write(certificate.data(), certificate.size(), ec);
+        // ignore result
+    }
+}
+
+std::string generateSslCertificate(const std::string& cn)
+{
+    BMCWEB_LOG_INFO("Generating new keys");
+
+    std::string buffer;
+    BMCWEB_LOG_INFO("Generating EC key");
+    EVP_PKEY* pPrivKey = createEcKey();
+    if (pPrivKey != nullptr)
+    {
+        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;
+    }
+
+    // cleanup_openssl();
+    return buffer;
+}
+
+EVP_PKEY* createEcKey()
+{
+    EVP_PKEY* pKey = nullptr;
+
+    // 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;
+    }
+
+    return pKey;
+}
+
+std::string ensureOpensslKeyPresentAndValid(const std::string& filepath)
+{
+    std::string cert = verifyOpensslKeyCert(filepath);
+
+    if (cert.empty())
+    {
+        BMCWEB_LOG_WARNING("Error in verifying signature, regenerating");
+        cert = generateSslCertificate("testhost");
+        if (cert.empty())
+        {
+            BMCWEB_LOG_ERROR("Failed to generate cert");
+        }
+        else
+        {
+            writeCertificateToFile(filepath, cert);
+        }
+    }
+    return cert;
+}
+
+static std::string ensureCertificate()
+{
+    namespace fs = std::filesystem;
+    // Cleanup older certificate file existing in the system
+    fs::path oldcertPath = fs::path("/home/root/server.pem");
+    std::error_code ec;
+    fs::remove(oldcertPath, ec);
+    // Ignore failure to remove;  File might not exist.
+
+    fs::path certPath = "/etc/ssl/certs/https/";
+    // if path does not exist create the path so that
+    // self signed certificate can be created in the
+    // path
+    fs::path certFile = certPath / "server.pem";
+
+    if (!fs::exists(certPath, ec))
+    {
+        fs::create_directories(certPath, ec);
+    }
+    BMCWEB_LOG_INFO("Building SSL Context file= {}", certFile.string());
+    std::string sslPemFile(certFile);
+    return ensuressl::ensureOpensslKeyPresentAndValid(sslPemFile);
+}
+
+static int nextProtoCallback(SSL* /*unused*/, const unsigned char** data,
+                             unsigned int* len, void* /*unused*/)
+{
+    // First byte is the length.
+    constexpr std::string_view h2 = "\x02h2";
+    *data = std::bit_cast<const unsigned char*>(h2.data());
+    *len = static_cast<unsigned int>(h2.size());
+    return SSL_TLSEXT_ERR_OK;
+}
+
+static int alpnSelectProtoCallback(SSL* /*unused*/, const unsigned char** out,
+                                   unsigned char* outlen,
+                                   const unsigned char* in, unsigned int inlen,
+                                   void* /*unused*/)
+{
+    // There's a mismatch in constness for nghttp2_select_next_protocol.  The
+    // examples in nghttp2 don't show this problem.  Unclear what the right fix
+    // is here.
+
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
+    unsigned char** outNew = const_cast<unsigned char**>(out);
+    int rv = nghttp2_select_next_protocol(outNew, outlen, in, inlen);
+    if (rv != 1)
+    {
+        return SSL_TLSEXT_ERR_NOACK;
+    }
+
+    return SSL_TLSEXT_ERR_OK;
+}
+
+static bool getSslContext(boost::asio::ssl::context& mSslContext,
+                          const std::string& sslPemFile)
+{
+    mSslContext.set_options(boost::asio::ssl::context::default_workarounds |
+                            boost::asio::ssl::context::no_sslv2 |
+                            boost::asio::ssl::context::no_sslv3 |
+                            boost::asio::ssl::context::single_dh_use |
+                            boost::asio::ssl::context::no_tlsv1 |
+                            boost::asio::ssl::context::no_tlsv1_1);
+
+    BMCWEB_LOG_DEBUG("Using default TrustStore location: {}", trustStorePath);
+    mSslContext.add_verify_path(trustStorePath);
+
+    if (!sslPemFile.empty())
+    {
+        boost::system::error_code ec;
+
+        boost::asio::const_buffer buf(sslPemFile.data(), sslPemFile.size());
+        mSslContext.use_certificate(buf, boost::asio::ssl::context::pem, ec);
+        if (ec)
+        {
+            return false;
+        }
+        mSslContext.use_private_key(buf, boost::asio::ssl::context::pem, ec);
+        if (ec)
+        {
+            BMCWEB_LOG_CRITICAL("Failed to open ssl pkey");
+            return false;
+        }
+    }
+
+    // Set up EC curves to auto (boost asio doesn't have a method for this)
+    // There is a pull request to add this.  Once this is included in an asio
+    // drop, use the right way
+    // http://stackoverflow.com/questions/18929049/boost-asio-with-ecdsa-certificate-issue
+    if (SSL_CTX_set_ecdh_auto(mSslContext.native_handle(), 1) != 1)
+    {}
+
+    if (SSL_CTX_set_cipher_list(mSslContext.native_handle(),
+                                mozillaIntermediate) != 1)
+    {
+        BMCWEB_LOG_ERROR("Error setting cipher list");
+        return false;
+    }
+    return true;
+}
+
+std::shared_ptr<boost::asio::ssl::context> getSslServerContext()
+{
+    boost::asio::ssl::context sslCtx(boost::asio::ssl::context::tls_server);
+
+    auto certFile = ensureCertificate();
+    if (!getSslContext(sslCtx, certFile))
+    {
+        BMCWEB_LOG_CRITICAL("Couldn't get server context");
+        return nullptr;
+    }
+    const persistent_data::AuthConfigMethods& c =
+        persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
+
+    boost::asio::ssl::verify_mode mode = boost::asio::ssl::verify_peer;
+    if (c.tlsStrict)
+    {
+        BMCWEB_LOG_DEBUG("Setting verify peer");
+        mode |= boost::asio::ssl::verify_fail_if_no_peer_cert;
+    }
+
+    boost::system::error_code ec;
+    sslCtx.set_verify_mode(mode, ec);
+    if (ec)
+    {
+        BMCWEB_LOG_DEBUG("Failed to set verify mode {}", ec.message());
+        return nullptr;
+    }
+    SSL_CTX_set_options(sslCtx.native_handle(), SSL_OP_NO_RENEGOTIATION);
+
+    if constexpr (BMCWEB_EXPERIMENTAL_HTTP2)
+    {
+        SSL_CTX_set_next_protos_advertised_cb(sslCtx.native_handle(),
+                                              nextProtoCallback, nullptr);
+
+        SSL_CTX_set_alpn_select_cb(sslCtx.native_handle(),
+                                   alpnSelectProtoCallback, nullptr);
+    }
+
+    return std::make_shared<boost::asio::ssl::context>(std::move(sslCtx));
+}
+
+std::optional<boost::asio::ssl::context>
+    getSSLClientContext(VerifyCertificate verifyCertificate)
+{
+    namespace fs = std::filesystem;
+
+    boost::asio::ssl::context sslCtx(boost::asio::ssl::context::tls_client);
+
+    // NOTE, this path is temporary;  In the future it will need to change to
+    // be set per subscription.  Do not rely on this.
+    fs::path certPath = "/etc/ssl/certs/https/client.pem";
+    std::string cert = verifyOpensslKeyCert(certPath);
+
+    if (!getSslContext(sslCtx, cert))
+    {
+        return std::nullopt;
+    }
+
+    // Add a directory containing certificate authority files to be used
+    // for performing verification.
+    boost::system::error_code ec;
+    sslCtx.set_default_verify_paths(ec);
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR("SSL context set_default_verify failed");
+        return std::nullopt;
+    }
+
+    int mode = boost::asio::ssl::verify_peer;
+    if (verifyCertificate == VerifyCertificate::NoVerify)
+    {
+        mode = boost::asio::ssl::verify_none;
+    }
+
+    // Verify the remote server's certificate
+    sslCtx.set_verify_mode(mode, ec);
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR("SSL context set_verify_mode failed");
+        return std::nullopt;
+    }
+
+    if (SSL_CTX_set_cipher_list(sslCtx.native_handle(), mozillaIntermediate) !=
+        1)
+    {
+        BMCWEB_LOG_ERROR("SSL_CTX_set_cipher_list failed");
+        return std::nullopt;
+    }
+
+    return {std::move(sslCtx)};
+}
+
+} // namespace ensuressl
