#pragma once

#include "app.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "http/parsing.hpp"
#include "http_response.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/collection.hpp"
#include "utils/dbus_utils.hpp"
#include "utils/json_utils.hpp"
#include "utils/time_utils.hpp"

#include <boost/system/linux_error.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/unpack_properties.hpp>

#include <array>
#include <memory>
#include <string_view>

#include "managed_store.hpp"

#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp" // NOLINT
#endif

namespace redfish
{
namespace certs
{
constexpr char const* certInstallIntf = "xyz.openbmc_project.Certs.Install";
constexpr char const* certReplaceIntf = "xyz.openbmc_project.Certs.Replace";
constexpr char const* objDeleteIntf = "xyz.openbmc_project.Object.Delete";
constexpr char const* certPropIntf = "xyz.openbmc_project.Certs.Certificate";
constexpr char const* dbusPropIntf = "org.freedesktop.DBus.Properties";
constexpr char const* dbusObjManagerIntf = "org.freedesktop.DBus.ObjectManager";
constexpr char const* httpsServiceName =
    "xyz.openbmc_project.Certs.Manager.Server.Https";
constexpr char const* ldapServiceName =
    "xyz.openbmc_project.Certs.Manager.Client.Ldap";
constexpr char const* authorityServiceName =
    "xyz.openbmc_project.Certs.Manager.Authority.Ldap";
constexpr char const* baseObjectPath = "/xyz/openbmc_project/certs";
constexpr char const* httpsObjectPath =
    "/xyz/openbmc_project/certs/server/https";
constexpr char const* ldapObjectPath = "/xyz/openbmc_project/certs/client/ldap";
constexpr char const* authorityObjectPath =
    "/xyz/openbmc_project/certs/authority/ldap";
constexpr char const* chassisObjectPath = "/xyz/openbmc_project/certs/chassis";
} // namespace certs

/**
 * The Certificate schema defines a Certificate Service which represents the
 * actions available to manage certificates and links to where certificates
 * are installed.
 */

inline std::string getCertificateFromReqBody(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const crow::Request& req)
{
    nlohmann::json reqJson;
    JsonParseResult ret = parseRequestAsJson(req, reqJson);
    if (ret != JsonParseResult::Success)
    {
        // We did not receive JSON request, proceed as it is RAW data
        return req.body();
    }

    std::string certificate;
    std::optional<std::string> certificateType = "PEM";

    if (!json_util::readJsonPatch(req, asyncResp->res, "CertificateString",
                                  certificate, "CertificateType",
                                  certificateType))
    {
        BMCWEB_LOG_ERROR << "Required parameters are missing";
        messages::internalError(asyncResp->res);
        return {};
    }

    if (*certificateType != "PEM")
    {
        messages::propertyValueNotInList(asyncResp->res, *certificateType,
                                         "CertificateType");
        return {};
    }

    return certificate;
}

/**
 * Class to create a temporary certificate file for uploading to system
 */
class CertificateFile
{
  public:
    CertificateFile() = delete;
    CertificateFile(const CertificateFile&) = delete;
    CertificateFile& operator=(const CertificateFile&) = delete;
    CertificateFile(CertificateFile&&) = delete;
    CertificateFile& operator=(CertificateFile&&) = delete;
    explicit CertificateFile(const std::string& certString)
    {
        std::array<char, 18> dirTemplate = {'/', 't', 'm', 'p', '/', 'C',
                                            'e', 'r', 't', 's', '.', 'X',
                                            'X', 'X', 'X', 'X', 'X', '\0'};
        char* tempDirectory = mkdtemp(dirTemplate.data());
        if (tempDirectory != nullptr)
        {
            certDirectory = tempDirectory;
            certificateFile = certDirectory / "cert.pem";
            std::ofstream out(certificateFile, std::ofstream::out |
                                                   std::ofstream::binary |
                                                   std::ofstream::trunc);
            out << certString;
            out.close();
            BMCWEB_LOG_DEBUG << "Creating certificate file"
                             << certificateFile.string();
        }
    }
    ~CertificateFile()
    {
        if (std::filesystem::exists(certDirectory))
        {
            BMCWEB_LOG_DEBUG << "Removing certificate file"
                             << certificateFile.string();
            std::error_code ec;
            std::filesystem::remove_all(certDirectory, ec);
            if (ec)
            {
                BMCWEB_LOG_ERROR << "Failed to remove temp directory"
                                 << certDirectory.string();
            }
        }
    }
    std::string getCertFilePath()
    {
        return certificateFile;
    }

  private:
    std::filesystem::path certificateFile;
    std::filesystem::path certDirectory;
};

/**
 * @brief Parse and update Certificate Issue/Subject property
 *
 * @param[in] asyncResp Shared pointer to the response message
 * @param[in] str  Issuer/Subject value in key=value pairs
 * @param[in] type Issuer/Subject
 * @return None
 */
static void updateCertIssuerOrSubject(nlohmann::json& out,
                                      std::string_view value)
{
    // example: O=openbmc-project.xyz,CN=localhost
    std::string_view::iterator i = value.begin();
    while (i != value.end())
    {
        std::string_view::iterator tokenBegin = i;
        while (i != value.end() && *i != '=')
        {
            ++i;
        }
        if (i == value.end())
        {
            break;
        }
        std::string_view key(tokenBegin, static_cast<size_t>(i - tokenBegin));
        ++i;
        tokenBegin = i;
        while (i != value.end() && *i != ',')
        {
            ++i;
        }
        std::string_view val(tokenBegin, static_cast<size_t>(i - tokenBegin));
        if (key == "L")
        {
            out["City"] = val;
        }
        else if (key == "CN")
        {
            out["CommonName"] = val;
        }
        else if (key == "C")
        {
            out["Country"] = val;
        }
        else if (key == "O")
        {
            out["Organization"] = val;
        }
        else if (key == "OU")
        {
            out["OrganizationalUnit"] = val;
        }
        else if (key == "ST")
        {
            out["State"] = val;
        }
        // skip comma character
        if (i != value.end())
        {
            ++i;
        }
    }
}

/**
 * @brief Retrieve the installed certificate list
 *
 * @param[in] asyncResp Shared pointer to the response message
 * @param[in] basePath DBus object path to search
 * @param[in] listPtr Json pointer to the list in asyncResp
 * @param[in] countPtr Json pointer to the count in asyncResp
 * @return None
 */
static void
    getCertificateList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const std::string& basePath,
                       const nlohmann::json::json_pointer& listPtr,
                       const nlohmann::json::json_pointer& countPtr)
{
    constexpr std::array<std::string_view, 1> interfaces = {
        certs::certPropIntf};
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTreePaths(
        basePath, 0, interfaces, requestContext,
        [asyncResp, listPtr, countPtr](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreePathsResponse& certPaths) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "Certificate collection query failed: " << ec;
            messages::internalError(asyncResp->res);
            return;
        }

        nlohmann::json& links = asyncResp->res.jsonValue[listPtr];
        links = nlohmann::json::array();
        for (const auto& certPath : certPaths)
        {
            sdbusplus::message::object_path objPath(certPath);
            std::string certId = objPath.filename();
            if (certId.empty())
            {
                BMCWEB_LOG_ERROR << "Invalid certificate objPath " << certPath;
                continue;
            }

            boost::urls::url certURL;
            if (objPath.parent_path() == certs::httpsObjectPath)
            {
                certURL = crow::utility::urlFromPieces(
                    "redfish", "v1", "Managers", "bmc", "NetworkProtocol",
                    "HTTPS", "Certificates", certId);
            }
            else if (objPath.parent_path() == certs::ldapObjectPath)
            {
                certURL = crow::utility::urlFromPieces("redfish", "v1",
                                                       "AccountService", "LDAP",
                                                       "Certificates", certId);
            }
            else if (objPath.parent_path() == certs::authorityObjectPath)
            {
                certURL = crow::utility::urlFromPieces(
                    "redfish", "v1", "Managers", "bmc", "Truststore",
                    "Certificates", certId);
            }
            else
            {
                continue;
            }

            nlohmann::json::object_t link;
            link["@odata.id"] = certURL;
            links.emplace_back(std::move(link));
        }

        asyncResp->res.jsonValue[countPtr] = links.size();
    });
}

/**
 * @brief Retrieve the certificates properties and append to the response
 * message
 *
 * @param[in] asyncResp Shared pointer to the response message
 * @param[in] objectPath  Path of the D-Bus service object
 * @param[in] certId  Id of the certificate
 * @param[in] certURL  URL of the certificate object
 * @param[in] name  name of the certificate
 * @return None
 */
static void getCertificateProperties(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& objectPath, const std::string& service,
    const std::string& certId, const boost::urls::url& certURL,
    const std::string& name)
{
    BMCWEB_LOG_DEBUG << "getCertificateProperties Path=" << objectPath
                     << " certId=" << certId << " certURl=" << certURL;
    managedStore::ManagedObjectStoreContext context(asyncResp);
    managedStore::GetManagedObjectStore()->getAllProperties(
        service, objectPath, certs::certPropIntf, context,
        [asyncResp, certURL, certId,
         name](const boost::system::error_code& ec,
               const dbus::utility::DBusPropertiesMap& properties) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
            messages::resourceNotFound(asyncResp->res, "Certificate", certId);
            return;
        }

        const std::string* certificateString = nullptr;
        const std::vector<std::string>* keyUsage = nullptr;
        const std::string* issuer = nullptr;
        const std::string* subject = nullptr;
        const uint64_t* validNotAfter = nullptr;
        const uint64_t* validNotBefore = nullptr;

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), properties, "CertificateString",
            certificateString, "KeyUsage", keyUsage, "Issuer", issuer,
            "Subject", subject, "ValidNotAfter", validNotAfter,
            "ValidNotBefore", validNotBefore);

        if (!success)
        {
            messages::internalError(asyncResp->res);
            return;
        }

        asyncResp->res.jsonValue["@odata.id"] = certURL;
        asyncResp->res.jsonValue["@odata.type"] =
            "#Certificate.v1_0_0.Certificate";
        asyncResp->res.jsonValue["Id"] = certId;
        asyncResp->res.jsonValue["Name"] = name;
        asyncResp->res.jsonValue["Description"] = name;
        asyncResp->res.jsonValue["CertificateString"] = "";
        asyncResp->res.jsonValue["KeyUsage"] = nlohmann::json::array();

        if (certificateString != nullptr)
        {
            asyncResp->res.jsonValue["CertificateString"] = *certificateString;
        }

        if (keyUsage != nullptr)
        {
            asyncResp->res.jsonValue["KeyUsage"] = *keyUsage;
        }

        if (issuer != nullptr)
        {
            updateCertIssuerOrSubject(asyncResp->res.jsonValue["Issuer"],
                                      *issuer);
        }

        if (subject != nullptr)
        {
            updateCertIssuerOrSubject(asyncResp->res.jsonValue["Subject"],
                                      *subject);
        }

        if (validNotAfter != nullptr)
        {
            asyncResp->res.jsonValue["ValidNotAfter"] =
                redfish::time_utils::getDateTimeUint(*validNotAfter);
        }

        if (validNotBefore != nullptr)
        {
            asyncResp->res.jsonValue["ValidNotBefore"] =
                redfish::time_utils::getDateTimeUint(*validNotBefore);
        }

        asyncResp->res.addHeader(
            boost::beast::http::field::location,
            std::string_view(certURL.data(), certURL.size()));
        });
}

static void
    deleteCertificate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                      const std::string& service,
                      const sdbusplus::message::object_path& objectPath)
{
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [asyncResp,
         id{objectPath.filename()}](const boost::system::error_code& ec) {
        if (ec)
        {
            messages::resourceNotFound(asyncResp->res, "Certificate", id);
            return;
        }
        BMCWEB_LOG_INFO << "Certificate deleted";
        asyncResp->res.result(boost::beast::http::status::no_content);
        },
        service, objectPath, certs::objDeleteIntf, "Delete");
}

inline void handleCertificateServiceGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    asyncResp->res.jsonValue["@odata.type"] =
        "#CertificateService.v1_0_0.CertificateService";
    asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/CertificateService";
    asyncResp->res.jsonValue["Id"] = "CertificateService";
    asyncResp->res.jsonValue["Name"] = "Certificate Service";
    asyncResp->res.jsonValue["Description"] =
        "Actions available to manage certificates";
    // /redfish/v1/CertificateService/CertificateLocations is something
    // only ConfigureManager can access then only display when the user
    // has permissions ConfigureManager
    Privileges effectiveUserPrivileges =
        redfish::getUserPrivileges(req.userRole);
    if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
                                         effectiveUserPrivileges))
    {
        asyncResp->res.jsonValue["CertificateLocations"]["@odata.id"] =
            "/redfish/v1/CertificateService/CertificateLocations";
    }
    nlohmann::json& actions = asyncResp->res.jsonValue["Actions"];
    nlohmann::json& replace = actions["#CertificateService.ReplaceCertificate"];
    replace["target"] =
        "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate";
    nlohmann::json::array_t allowed;
    allowed.emplace_back("PEM");
    replace["CertificateType@Redfish.AllowableValues"] = std::move(allowed);
    actions["#CertificateService.GenerateCSR"]["target"] =
        "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR";
}

inline void handleCertificateLocationsGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/CertificateService/CertificateLocations";
    asyncResp->res.jsonValue["@odata.type"] =
        "#CertificateLocations.v1_0_0.CertificateLocations";
    asyncResp->res.jsonValue["Name"] = "Certificate Locations";
    asyncResp->res.jsonValue["Id"] = "CertificateLocations";
    asyncResp->res.jsonValue["Description"] =
        "Defines a resource that an administrator can use in order to "
        "locate all certificates installed on a given service";

    getCertificateList(asyncResp, certs::baseObjectPath,
                       "/Links/Certificates"_json_pointer,
                       "/Links/Certificates@odata.count"_json_pointer);
}

inline void handleReplaceCertificateAction(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    std::string certificate;
    nlohmann::json certificateUri;
    std::optional<std::string> certificateType = "PEM";

    if (!json_util::readJsonAction(req, asyncResp->res, "CertificateString",
                                   certificate, "CertificateUri",
                                   certificateUri, "CertificateType",
                                   certificateType))
    {
        BMCWEB_LOG_ERROR << "Required parameters are missing";
        messages::internalError(asyncResp->res);
        return;
    }

    if (!certificateType)
    {
        // should never happen, but it never hurts to be paranoid.
        return;
    }
    if (certificateType != "PEM")
    {
        messages::actionParameterNotSupported(asyncResp->res, "CertificateType",
                                              "ReplaceCertificate");
        return;
    }

    std::string certURI;
    if (!redfish::json_util::readJson(certificateUri, asyncResp->res,
                                      "@odata.id", certURI))
    {
        messages::actionParameterMissing(asyncResp->res, "ReplaceCertificate",
                                         "CertificateUri");
        return;
    }
    BMCWEB_LOG_INFO << "Certificate URI to replace: " << certURI;

    auto parsedUrl = boost::urls::parse_relative_ref(certURI);
    if (!parsedUrl)
    {
        messages::actionParameterValueFormatError(
            asyncResp->res, certURI, "CertificateUri", "ReplaceCertificate");
        return;
    }

    std::string id;
    sdbusplus::message::object_path objectPath;
    std::string name;
    std::string service;
    if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1", "Managers",
                                       "bmc", "NetworkProtocol", "HTTPS",
                                       "Certificates", std::ref(id)))
    {
        objectPath =
            sdbusplus::message::object_path(certs::httpsObjectPath) / id;
        name = "HTTPS certificate";
        service = certs::httpsServiceName;
    }
    else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
                                            "AccountService", "LDAP",
                                            "Certificates", std::ref(id)))
    {
        objectPath =
            sdbusplus::message::object_path(certs::ldapObjectPath) / id;
        name = "LDAP certificate";
        service = certs::ldapServiceName;
    }
    else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
                                            "Managers", "bmc", "Truststore",
                                            "Certificates", std::ref(id)))
    {
        objectPath =
            sdbusplus::message::object_path(certs::authorityObjectPath) / id;
        name = "TrustStore certificate";
        service = certs::authorityServiceName;
    }
    else
    {
        messages::actionParameterNotSupported(asyncResp->res, "CertificateUri",
                                              "ReplaceCertificate");
        return;
    }

    std::shared_ptr<CertificateFile> certFile =
        std::make_shared<CertificateFile>(certificate);
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [asyncResp, certFile, objectPath, service, url{*parsedUrl}, id,
         name](const boost::system::error_code& ec) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
            if (ec.value() ==
                boost::system::linux_error::bad_request_descriptor)
            {
                messages::resourceNotFound(asyncResp->res, "Certificate", id);
                return;
            }
            messages::internalError(asyncResp->res);
            return;
        }
        getCertificateProperties(asyncResp, objectPath, service, id, url, name);
        BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
                         << certFile->getCertFilePath();
        },
        service, objectPath, certs::certReplaceIntf, "Replace",
        certFile->getCertFilePath());
}

// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static std::unique_ptr<sdbusplus::bus::match_t> csrMatcher;
/**
 * @brief Read data from CSR D-bus object and set to response
 *
 * @param[in] asyncResp Shared pointer to the response message
 * @param[in] certURI Link to certifiate collection URI
 * @param[in] service D-Bus service name
 * @param[in] certObjPath certificate D-Bus object path
 * @param[in] csrObjPath CSR D-Bus object path
 * @return None
 */
static void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                   const std::string& certURI, const std::string& service,
                   const std::string& certObjPath,
                   const std::string& csrObjPath)
{
    BMCWEB_LOG_DEBUG << "getCSR CertObjectPath" << certObjPath
                     << " CSRObjectPath=" << csrObjPath
                     << " service=" << service;
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [asyncResp, certURI](const boost::system::error_code& ec,
                             const std::string& csr) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
            messages::internalError(asyncResp->res);
            return;
        }
        if (csr.empty())
        {
            BMCWEB_LOG_ERROR << "CSR read is empty";
            messages::internalError(asyncResp->res);
            return;
        }
        asyncResp->res.jsonValue["CSRString"] = csr;
        asyncResp->res.jsonValue["CertificateCollection"]["@odata.id"] =
            certURI;
        },
        service, csrObjPath, "xyz.openbmc_project.Certs.CSR", "CSR");
}

inline void
    handleGenerateCSRAction(App& app, const crow::Request& req,
                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    static const int rsaKeyBitLength = 2048;

    // Required parameters
    std::string city;
    std::string commonName;
    std::string country;
    std::string organization;
    std::string organizationalUnit;
    std::string state;
    nlohmann::json certificateCollection;

    // Optional parameters
    std::optional<std::vector<std::string>> optAlternativeNames =
        std::vector<std::string>();
    std::optional<std::string> optContactPerson = "";
    std::optional<std::string> optChallengePassword = "";
    std::optional<std::string> optEmail = "";
    std::optional<std::string> optGivenName = "";
    std::optional<std::string> optInitials = "";
    std::optional<int64_t> optKeyBitLength = rsaKeyBitLength;
    std::optional<std::string> optKeyCurveId = "secp384r1";
    std::optional<std::string> optKeyPairAlgorithm = "EC";
    std::optional<std::vector<std::string>> optKeyUsage =
        std::vector<std::string>();
    std::optional<std::string> optSurname = "";
    std::optional<std::string> optUnstructuredName = "";
    if (!json_util::readJsonAction(
            req, asyncResp->res, "City", city, "CommonName", commonName,
            "ContactPerson", optContactPerson, "Country", country,
            "Organization", organization, "OrganizationalUnit",
            organizationalUnit, "State", state, "CertificateCollection",
            certificateCollection, "AlternativeNames", optAlternativeNames,
            "ChallengePassword", optChallengePassword, "Email", optEmail,
            "GivenName", optGivenName, "Initials", optInitials, "KeyBitLength",
            optKeyBitLength, "KeyCurveId", optKeyCurveId, "KeyPairAlgorithm",
            optKeyPairAlgorithm, "KeyUsage", optKeyUsage, "Surname", optSurname,
            "UnstructuredName", optUnstructuredName))
    {
        return;
    }

    // bmcweb has no way to store or decode a private key challenge
    // password, which will likely cause bmcweb to crash on startup
    // if this is not set on a post so not allowing the user to set
    // value
    if (!optChallengePassword->empty())
    {
        messages::actionParameterNotSupported(asyncResp->res, "GenerateCSR",
                                              "ChallengePassword");
        return;
    }

    std::string certURI;
    if (!redfish::json_util::readJson(certificateCollection, asyncResp->res,
                                      "@odata.id", certURI))
    {
        return;
    }

    std::string objectPath;
    std::string service;
    if (certURI.starts_with(
            "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
    {
        objectPath = certs::httpsObjectPath;
        service = certs::httpsServiceName;
    }
    else if (certURI.starts_with(
                 "/redfish/v1/AccountService/LDAP/Certificates"))
    {
        objectPath = certs::ldapObjectPath;
        service = certs::ldapServiceName;
    }
    else
    {
        messages::actionParameterNotSupported(
            asyncResp->res, "CertificateCollection", "GenerateCSR");
        return;
    }

    // supporting only EC and RSA algorithm
    if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
    {
        messages::actionParameterNotSupported(
            asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
        return;
    }

    // supporting only 2048 key bit length for RSA algorithm due to
    // time consumed in generating private key
    if (*optKeyPairAlgorithm == "RSA" && *optKeyBitLength != rsaKeyBitLength)
    {
        messages::propertyValueNotInList(
            asyncResp->res, std::to_string(*optKeyBitLength), "KeyBitLength");
        return;
    }

    // validate KeyUsage supporting only 1 type based on URL
    if (certURI.starts_with(
            "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
    {
        if (optKeyUsage->empty())
        {
            optKeyUsage->emplace_back("ServerAuthentication");
        }
        else if (optKeyUsage->size() == 1)
        {
            if ((*optKeyUsage)[0] != "ServerAuthentication")
            {
                messages::propertyValueNotInList(asyncResp->res,
                                                 (*optKeyUsage)[0], "KeyUsage");
                return;
            }
        }
        else
        {
            messages::actionParameterNotSupported(asyncResp->res, "KeyUsage",
                                                  "GenerateCSR");
            return;
        }
    }
    else if (certURI.starts_with(
                 "/redfish/v1/AccountService/LDAP/Certificates"))
    {
        if (optKeyUsage->empty())
        {
            optKeyUsage->emplace_back("ClientAuthentication");
        }
        else if (optKeyUsage->size() == 1)
        {
            if ((*optKeyUsage)[0] != "ClientAuthentication")
            {
                messages::propertyValueNotInList(asyncResp->res,
                                                 (*optKeyUsage)[0], "KeyUsage");
                return;
            }
        }
        else
        {
            messages::actionParameterNotSupported(asyncResp->res, "KeyUsage",
                                                  "GenerateCSR");
            return;
        }
    }

    // Only allow one CSR matcher at a time so setting retry
    // time-out and timer expiry to 10 seconds for now.
    static const int timeOut = 10;
    if (csrMatcher)
    {
        messages::serviceTemporarilyUnavailable(asyncResp->res,
                                                std::to_string(timeOut));
        return;
    }

    // Make this static so it survives outside this method
    static boost::asio::steady_timer timeout(*req.ioService);
    timeout.expires_after(std::chrono::seconds(timeOut));
    timeout.async_wait([asyncResp](const boost::system::error_code& ec) {
        csrMatcher = nullptr;
        if (ec)
        {
            // operation_aborted is expected if timer is canceled
            // before completion.
            if (ec != boost::asio::error::operation_aborted)
            {
                BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
            }
            return;
        }
        BMCWEB_LOG_ERROR << "Timed out waiting for Generating CSR";
        messages::internalError(asyncResp->res);
    });

    // create a matcher to wait on CSR object
    BMCWEB_LOG_DEBUG << "create matcher with path " << objectPath;
    std::string match("type='signal',"
                      "interface='org.freedesktop.DBus.ObjectManager',"
                      "path='" +
                      objectPath +
                      "',"
                      "member='InterfacesAdded'");
    csrMatcher = std::make_unique<sdbusplus::bus::match_t>(
        *(managedStore::GetManagedObjectStore()->GetDeprecatedThreadUnsafeSystemBus()), match,
        [asyncResp, service, objectPath, certURI](sdbusplus::message_t& m) {
        timeout.cancel();
        if (m.is_method_error())
        {
            BMCWEB_LOG_ERROR << "Dbus method error!!!";
            messages::internalError(asyncResp->res);
            return;
        }

        dbus::utility::DBusInteracesMap interfacesProperties;

        sdbusplus::message::object_path csrObjectPath;
        m.read(csrObjectPath, interfacesProperties);
        BMCWEB_LOG_DEBUG << "CSR object added" << csrObjectPath.str;
        for (const auto& interface : interfacesProperties)
        {
            if (interface.first == "xyz.openbmc_project.Certs.CSR")
            {
                getCSR(asyncResp, certURI, service, objectPath,
                       csrObjectPath.str);
                break;
            }
        }
        });
#ifndef UNIT_TEST_BUILD
// Mocking this seems to break
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [asyncResp](const boost::system::error_code& ec, const std::string&) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBUS response error: " << ec.message();
            messages::internalError(asyncResp->res);
            return;
        }
        },
        service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
        "GenerateCSR", *optAlternativeNames, *optChallengePassword, city,
        commonName, *optContactPerson, country, *optEmail, *optGivenName,
        *optInitials, *optKeyBitLength, *optKeyCurveId, *optKeyPairAlgorithm,
        *optKeyUsage, organization, organizationalUnit, state, *optSurname,
        *optUnstructuredName);
#endif
}

inline void requestRoutesCertificateService(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/")
        .privileges(redfish::privileges::getCertificateService)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleCertificateServiceGet, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/CertificateLocations/")
        .privileges(redfish::privileges::getCertificateLocations)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleCertificateLocationsGet, std::ref(app)));

    BMCWEB_ROUTE(
        app,
        "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate/")
        .privileges(redfish::privileges::postCertificateService)
        .methods(boost::beast::http::verb::post)(
            std::bind_front(handleReplaceCertificateAction, std::ref(app)));

    BMCWEB_ROUTE(
        app,
        "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR/")
        .privileges(redfish::privileges::postCertificateService)
        .methods(boost::beast::http::verb::post)(
            std::bind_front(handleGenerateCSRAction, std::ref(app)));
} // requestRoutesCertificateService

inline void handleHTTPSCertificateCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates";
    asyncResp->res.jsonValue["@odata.type"] =
        "#CertificateCollection.CertificateCollection";
    asyncResp->res.jsonValue["Name"] = "HTTPS Certificates Collection";
    asyncResp->res.jsonValue["Description"] =
        "A Collection of HTTPS certificate instances";

    getCertificateList(asyncResp, certs::httpsObjectPath,
                       "/Members"_json_pointer,
                       "/Members@odata.count"_json_pointer);
}

inline void handleHTTPSCertificateCollectionPost(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    BMCWEB_LOG_DEBUG << "HTTPSCertificateCollection::doPost";

    asyncResp->res.jsonValue["Name"] = "HTTPS Certificate";
    asyncResp->res.jsonValue["Description"] = "HTTPS Certificate";

    std::string certFileBody = getCertificateFromReqBody(asyncResp, req);

    if (certFileBody.empty())
    {
        BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
        messages::unrecognizedRequestBody(asyncResp->res);
        return;
    }

    std::shared_ptr<CertificateFile> certFile =
        std::make_shared<CertificateFile>(certFileBody);

    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [asyncResp, certFile](const boost::system::error_code& ec,
                              const std::string& objectPath) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
            messages::internalError(asyncResp->res);
            return;
        }

        sdbusplus::message::object_path path(objectPath);
        std::string certId = path.filename();
        const boost::urls::url certURL = crow::utility::urlFromPieces(
            "redfish", "v1", "Managers", "bmc", "NetworkProtocol", "HTTPS",
            "Certificates", certId);
        getCertificateProperties(asyncResp, objectPath, certs::httpsServiceName,
                                 certId, certURL, "HTTPS Certificate");
        BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
                         << certFile->getCertFilePath();
        },
        certs::httpsServiceName, certs::httpsObjectPath, certs::certInstallIntf,
        "Install", certFile->getCertFilePath());
}

inline void handleHTTPSCertificateGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    BMCWEB_LOG_DEBUG << "HTTPS Certificate ID=" << id;
    const boost::urls::url certURL = crow::utility::urlFromPieces(
        "redfish", "v1", "Managers", "bmc", "NetworkProtocol", "HTTPS",
        "Certificates", id);
    std::string objPath =
        sdbusplus::message::object_path(certs::httpsObjectPath) / id;
    getCertificateProperties(asyncResp, objPath, certs::httpsServiceName, id,
                             certURL, "HTTPS Certificate");
}

inline void requestRoutesHTTPSCertificate(App& app)
{
    BMCWEB_ROUTE(app,
                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
        .privileges(redfish::privileges::getCertificateCollection)
        .methods(boost::beast::http::verb::get)(std::bind_front(
            handleHTTPSCertificateCollectionGet, std::ref(app)));

    BMCWEB_ROUTE(app,
                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
        .privileges(redfish::privileges::postCertificateCollection)
        .methods(boost::beast::http::verb::post)(std::bind_front(
            handleHTTPSCertificateCollectionPost, std::ref(app)));

    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/<str>/")
        .privileges(redfish::privileges::getCertificate)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleHTTPSCertificateGet, std::ref(app)));
}

inline void handleLDAPCertificateCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/AccountService/LDAP/Certificates";
    asyncResp->res.jsonValue["@odata.type"] =
        "#CertificateCollection.CertificateCollection";
    asyncResp->res.jsonValue["Name"] = "LDAP Certificates Collection";
    asyncResp->res.jsonValue["Description"] =
        "A Collection of LDAP certificate instances";

    getCertificateList(asyncResp, certs::ldapObjectPath,
                       "/Members"_json_pointer,
                       "/Members@odata.count"_json_pointer);
}

inline void handleLDAPCertificateCollectionPost(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    std::string certFileBody = getCertificateFromReqBody(asyncResp, req);

    if (certFileBody.empty())
    {
        BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
        messages::unrecognizedRequestBody(asyncResp->res);
        return;
    }

    std::shared_ptr<CertificateFile> certFile =
        std::make_shared<CertificateFile>(certFileBody);

    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [asyncResp, certFile](const boost::system::error_code& ec,
                              const std::string& objectPath) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
            messages::internalError(asyncResp->res);
            return;
        }

        sdbusplus::message::object_path path(objectPath);
        std::string certId = path.filename();
        const boost::urls::url certURL = crow::utility::urlFromPieces(
            "redfish", "v1", "AccountService", "LDAP", "Certificates", certId);
        getCertificateProperties(asyncResp, objectPath, certs::ldapServiceName,
                                 certId, certURL, "LDAP Certificate");
        BMCWEB_LOG_DEBUG << "LDAP certificate install file="
                         << certFile->getCertFilePath();
        },
        certs::ldapServiceName, certs::ldapObjectPath, certs::certInstallIntf,
        "Install", certFile->getCertFilePath());
}

inline void handleLDAPCertificateGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    BMCWEB_LOG_DEBUG << "LDAP Certificate ID=" << id;
    const boost::urls::url certURL = crow::utility::urlFromPieces(
        "redfish", "v1", "AccountService", "LDAP", "Certificates", id);
    std::string objPath =
        sdbusplus::message::object_path(certs::ldapObjectPath) / id;
    getCertificateProperties(asyncResp, objPath, certs::ldapServiceName, id,
                             certURL, "LDAP Certificate");
}

inline void handleLDAPCertificateDelete(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    BMCWEB_LOG_DEBUG << "Delete LDAP Certificate ID=" << id;
    std::string objPath =
        sdbusplus::message::object_path(certs::ldapObjectPath) / id;

    deleteCertificate(asyncResp, certs::ldapServiceName, objPath);
}

inline void requestRoutesLDAPCertificate(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
        .privileges(redfish::privileges::getCertificateCollection)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleLDAPCertificateCollectionGet, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
        .privileges(redfish::privileges::postCertificateCollection)
        .methods(boost::beast::http::verb::post)(std::bind_front(
            handleLDAPCertificateCollectionPost, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
        .privileges(redfish::privileges::getCertificate)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleLDAPCertificateGet, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
        .privileges(redfish::privileges::deleteCertificate)
        .methods(boost::beast::http::verb::delete_)(
            std::bind_front(handleLDAPCertificateDelete, std::ref(app)));
} // requestRoutesLDAPCertificate

inline void handleTrustStoreCertificateCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Managers/bmc/Truststore/Certificates/";
    asyncResp->res.jsonValue["@odata.type"] =
        "#CertificateCollection.CertificateCollection";
    asyncResp->res.jsonValue["Name"] = "TrustStore Certificates Collection";
    asyncResp->res.jsonValue["Description"] =
        "A Collection of TrustStore certificate instances";

    getCertificateList(asyncResp, certs::authorityObjectPath,
                       "/Members"_json_pointer,
                       "/Members@odata.count"_json_pointer);
}

inline void handleTrustStoreCertificateCollectionPost(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }
    std::string certFileBody = getCertificateFromReqBody(asyncResp, req);

    if (certFileBody.empty())
    {
        BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
        messages::unrecognizedRequestBody(asyncResp->res);
        return;
    }

    std::shared_ptr<CertificateFile> certFile =
        std::make_shared<CertificateFile>(certFileBody);
    managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
        asyncResp->strand_,
        [asyncResp, certFile](const boost::system::error_code& ec,
                              const std::string& objectPath) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
            messages::internalError(asyncResp->res);
            return;
        }

        sdbusplus::message::object_path path(objectPath);
        std::string certId = path.filename();
        const boost::urls::url certURL =
            crow::utility::urlFromPieces("redfish", "v1", "Managers", "bmc",
                                         "Truststore", "Certificates", certId);
        getCertificateProperties(asyncResp, objectPath,
                                 certs::authorityServiceName, certId, certURL,
                                 "TrustStore Certificate");
        BMCWEB_LOG_DEBUG << "TrustStore certificate install file="
                         << certFile->getCertFilePath();
        },
        certs::authorityServiceName, certs::authorityObjectPath,
        certs::certInstallIntf, "Install", certFile->getCertFilePath());
}

inline void handleTrustStoreCertificateGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    BMCWEB_LOG_DEBUG << "Truststore Certificate ID=" << id;
    const boost::urls::url certURL = crow::utility::urlFromPieces(
        "redfish", "v1", "Managers", "bmc", "Truststore", "Certificates", id);
    std::string objPath =
        sdbusplus::message::object_path(certs::authorityObjectPath) / id;
    getCertificateProperties(asyncResp, objPath, certs::authorityServiceName,
                             id, certURL, "TrustStore Certificate");
}

inline void handleTrustStoreCertificateDelete(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    BMCWEB_LOG_DEBUG << "Delete TrustStore Certificate ID=" << id;
    std::string objPath =
        sdbusplus::message::object_path(certs::authorityObjectPath) / id;

    deleteCertificate(asyncResp, certs::authorityServiceName, objPath);
}

inline void requestRoutesTrustStoreCertificate(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
        .privileges(redfish::privileges::getCertificate)
        .methods(boost::beast::http::verb::get)(std::bind_front(
            handleTrustStoreCertificateCollectionGet, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
        .privileges(redfish::privileges::postCertificateCollection)
        .methods(boost::beast::http::verb::post)(std::bind_front(
            handleTrustStoreCertificateCollectionPost, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/")
        .privileges(redfish::privileges::getCertificate)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleTrustStoreCertificateGet, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/")
        .privileges(redfish::privileges::deleteCertificate)
        .methods(boost::beast::http::verb::delete_)(
            std::bind_front(handleTrustStoreCertificateDelete, std::ref(app)));
} // requestRoutesTrustStoreCertificate

/**
 * Collection of Chassis Certificates
 */
inline void handleChassisCertificateCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    boost::urls::url url = crow::utility::urlFromPieces(
        "redfish", "v1", "Chassis", chassisId, "Certificates");

    asyncResp->res.jsonValue["@odata.id"] = url.buffer();
    asyncResp->res.jsonValue["@odata.type"] =
        "#CertificateCollection.CertificateCollection";
    asyncResp->res.jsonValue["Name"] = "Chassis Certificates Collection";
    asyncResp->res.jsonValue["Description"] =
        "A Collection of Chassis Certificate instances";

    constexpr std::array<std::string_view, 1> certInterfaces = {
        "xyz.openbmc_project.Certs.Certificate"};
    std::string certPath =
        sdbusplus::message::object_path(certs::chassisObjectPath) / chassisId;

    collection_util::getCollectionMembers(asyncResp, url, certInterfaces,
                                          certPath.c_str());
}

inline void handleChassisCertificateGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& certId)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    if (chassisId.empty() || certId.empty())
    {
        messages::internalError(asyncResp->res);
        return;
    }

    // GetSubTree on interfaces which provide info about certificate.
    constexpr std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.Certs.Certificate"};
    std::string certCollectionPath =
        sdbusplus::message::object_path(certs::chassisObjectPath) / chassisId;

    managedStore::ManagedObjectStoreContext context(asyncResp);
    dbus_utils::getSubTree(
        certCollectionPath, 0, interfaces, context,
        [asyncResp, chassisId,
         certId](const boost::system::error_code& ec,
                 const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
            messages::internalError(asyncResp->res);
            return;
        }

        const boost::urls::url certURL = crow::utility::urlFromPieces(
            "redfish", "v1", "Chassis", chassisId, "Certificates", certId);
        sdbusplus::message::object_path certPath =
            std::string(certs::chassisObjectPath) + "/" + chassisId + "/" +
            certId;

        for (const auto& [objectPath, serviceMap] : subtree)
        {
            // Ignore any objects which don't match certPath
            if (!objectPath.starts_with(certPath.str))
            {
                continue;
            }

            // Should only match one service and one cert object
            for (const auto& [serviceName, interfaceList] : serviceMap)
            {
                getCertificateProperties(asyncResp, certPath, serviceName,
                                         certId, certURL,
                                         "Chassis Certificate");
            }
        }
    });
}

inline void requestRoutesChassisCertificate(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Certificates/")
        .privileges(redfish::privileges::getCertificateCollection)
        .methods(boost::beast::http::verb::get)(std::bind_front(
            handleChassisCertificateCollectionGet, std::ref(app)));

    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Certificates/<str>/")
        .privileges(redfish::privileges::getCertificate)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleChassisCertificateGet, std::ref(app)));
} // requestRoutesChassisCertificate

} // namespace redfish
