xref: /openbmc/bmcweb/features/redfish/lib/certificate_service.hpp (revision 8d1b46d7f8d39db2ba048f9e9007106ca3a28c9b)
15968caeeSMarri Devender Rao #pragma once
25968caeeSMarri Devender Rao 
35968caeeSMarri Devender Rao #include "node.hpp"
45968caeeSMarri Devender Rao 
5e6604b11SIwona Klimaszewska #include <boost/convert.hpp>
6e6604b11SIwona Klimaszewska #include <boost/convert/strtol.hpp>
71214b7e7SGunnar Mills 
85968caeeSMarri Devender Rao #include <variant>
95968caeeSMarri Devender Rao namespace redfish
105968caeeSMarri Devender Rao {
115968caeeSMarri Devender Rao namespace certs
125968caeeSMarri Devender Rao {
135968caeeSMarri Devender Rao constexpr char const* httpsObjectPath =
145968caeeSMarri Devender Rao     "/xyz/openbmc_project/certs/server/https";
155968caeeSMarri Devender Rao constexpr char const* certInstallIntf = "xyz.openbmc_project.Certs.Install";
165968caeeSMarri Devender Rao constexpr char const* certReplaceIntf = "xyz.openbmc_project.Certs.Replace";
1707a60299SZbigniew Kurzynski constexpr char const* objDeleteIntf = "xyz.openbmc_project.Object.Delete";
185968caeeSMarri Devender Rao constexpr char const* certPropIntf = "xyz.openbmc_project.Certs.Certificate";
195968caeeSMarri Devender Rao constexpr char const* dbusPropIntf = "org.freedesktop.DBus.Properties";
205968caeeSMarri Devender Rao constexpr char const* dbusObjManagerIntf = "org.freedesktop.DBus.ObjectManager";
2137cce918SMarri Devender Rao constexpr char const* ldapObjectPath = "/xyz/openbmc_project/certs/client/ldap";
2237cce918SMarri Devender Rao constexpr char const* httpsServiceName =
2337cce918SMarri Devender Rao     "xyz.openbmc_project.Certs.Manager.Server.Https";
2437cce918SMarri Devender Rao constexpr char const* ldapServiceName =
2537cce918SMarri Devender Rao     "xyz.openbmc_project.Certs.Manager.Client.Ldap";
26cfcd5f6bSMarri Devender Rao constexpr char const* authorityServiceName =
27cfcd5f6bSMarri Devender Rao     "xyz.openbmc_project.Certs.Manager.Authority.Ldap";
28cfcd5f6bSMarri Devender Rao constexpr char const* authorityObjectPath =
29cfcd5f6bSMarri Devender Rao     "/xyz/openbmc_project/certs/authority/ldap";
305968caeeSMarri Devender Rao } // namespace certs
315968caeeSMarri Devender Rao 
325968caeeSMarri Devender Rao /**
335968caeeSMarri Devender Rao  * The Certificate schema defines a Certificate Service which represents the
345968caeeSMarri Devender Rao  * actions available to manage certificates and links to where certificates
355968caeeSMarri Devender Rao  * are installed.
365968caeeSMarri Devender Rao  */
375968caeeSMarri Devender Rao class CertificateService : public Node
385968caeeSMarri Devender Rao {
395968caeeSMarri Devender Rao   public:
4052cc112dSEd Tanous     CertificateService(App& app) : Node(app, "/redfish/v1/CertificateService/")
415968caeeSMarri Devender Rao     {
425968caeeSMarri Devender Rao         // TODO: Issue#61 No entries are available for Certificate
434e0453b1SGunnar Mills         // service at https://www.dmtf.org/standards/redfish
445968caeeSMarri Devender Rao         // "redfish standard registries". Need to modify after DMTF
455968caeeSMarri Devender Rao         // publish Privilege details for certificate service
465968caeeSMarri Devender Rao         entityPrivileges = {
475968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
485968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
495968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
505968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
515968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
525968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
535968caeeSMarri Devender Rao     }
545968caeeSMarri Devender Rao 
555968caeeSMarri Devender Rao   private:
56*8d1b46d7Szhanghch05     void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
57*8d1b46d7Szhanghch05                const crow::Request&, const std::vector<std::string>&) override
585968caeeSMarri Devender Rao     {
59*8d1b46d7Szhanghch05         asyncResp->res.jsonValue = {
605968caeeSMarri Devender Rao             {"@odata.type", "#CertificateService.v1_0_0.CertificateService"},
615968caeeSMarri Devender Rao             {"@odata.id", "/redfish/v1/CertificateService"},
625968caeeSMarri Devender Rao             {"Id", "CertificateService"},
635968caeeSMarri Devender Rao             {"Name", "Certificate Service"},
645968caeeSMarri Devender Rao             {"Description", "Actions available to manage certificates"}};
65*8d1b46d7Szhanghch05         asyncResp->res.jsonValue["CertificateLocations"] = {
665968caeeSMarri Devender Rao             {"@odata.id",
675968caeeSMarri Devender Rao              "/redfish/v1/CertificateService/CertificateLocations"}};
68*8d1b46d7Szhanghch05         asyncResp->res
69*8d1b46d7Szhanghch05             .jsonValue["Actions"]["#CertificateService.ReplaceCertificate"] = {
705968caeeSMarri Devender Rao             {"target", "/redfish/v1/CertificateService/Actions/"
715968caeeSMarri Devender Rao                        "CertificateService.ReplaceCertificate"},
725968caeeSMarri Devender Rao             {"CertificateType@Redfish.AllowableValues", {"PEM"}}};
73*8d1b46d7Szhanghch05         asyncResp->res.jsonValue["Actions"]["#CertificateService.GenerateCSR"] =
74*8d1b46d7Szhanghch05             {{"target", "/redfish/v1/CertificateService/Actions/"
7530215816SMarri Devender Rao                         "CertificateService.GenerateCSR"}};
765968caeeSMarri Devender Rao     }
775968caeeSMarri Devender Rao }; // CertificateService
7837cce918SMarri Devender Rao 
795968caeeSMarri Devender Rao /**
805968caeeSMarri Devender Rao  * @brief Find the ID specified in the URL
815968caeeSMarri Devender Rao  * Finds the numbers specified after the last "/" in the URL and returns.
825968caeeSMarri Devender Rao  * @param[in] path URL
835968caeeSMarri Devender Rao  * @return -1 on failure and number on success
845968caeeSMarri Devender Rao  */
8523a21a1cSEd Tanous inline long getIDFromURL(const std::string_view url)
865968caeeSMarri Devender Rao {
87f23b7296SEd Tanous     std::size_t found = url.rfind('/');
885968caeeSMarri Devender Rao     if (found == std::string::npos)
895968caeeSMarri Devender Rao     {
905968caeeSMarri Devender Rao         return -1;
915968caeeSMarri Devender Rao     }
92e6604b11SIwona Klimaszewska 
935968caeeSMarri Devender Rao     if ((found + 1) < url.length())
945968caeeSMarri Devender Rao     {
955968caeeSMarri Devender Rao         std::string_view str = url.substr(found + 1);
96e6604b11SIwona Klimaszewska 
97e6604b11SIwona Klimaszewska         return boost::convert<long>(str, boost::cnv::strtol()).value_or(-1);
985968caeeSMarri Devender Rao     }
99e6604b11SIwona Klimaszewska 
1005968caeeSMarri Devender Rao     return -1;
1015968caeeSMarri Devender Rao }
1025968caeeSMarri Devender Rao 
103*8d1b46d7Szhanghch05 inline std::string getCertificateFromReqBody(
104*8d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10558eb238fSKowalski, Kamil     const crow::Request& req)
10658eb238fSKowalski, Kamil {
10758eb238fSKowalski, Kamil     nlohmann::json reqJson = nlohmann::json::parse(req.body, nullptr, false);
10858eb238fSKowalski, Kamil 
10958eb238fSKowalski, Kamil     if (reqJson.is_discarded())
11058eb238fSKowalski, Kamil     {
11158eb238fSKowalski, Kamil         // We did not receive JSON request, proceed as it is RAW data
11258eb238fSKowalski, Kamil         return req.body;
11358eb238fSKowalski, Kamil     }
11458eb238fSKowalski, Kamil 
11558eb238fSKowalski, Kamil     std::string certificate;
11658eb238fSKowalski, Kamil     std::optional<std::string> certificateType = "PEM";
11758eb238fSKowalski, Kamil 
11858eb238fSKowalski, Kamil     if (!json_util::readJson(reqJson, asyncResp->res, "CertificateString",
11958eb238fSKowalski, Kamil                              certificate, "CertificateType", certificateType))
12058eb238fSKowalski, Kamil     {
12158eb238fSKowalski, Kamil         BMCWEB_LOG_ERROR << "Required parameters are missing";
12258eb238fSKowalski, Kamil         messages::internalError(asyncResp->res);
12358eb238fSKowalski, Kamil         return std::string();
12458eb238fSKowalski, Kamil     }
12558eb238fSKowalski, Kamil 
12658eb238fSKowalski, Kamil     if (*certificateType != "PEM")
12758eb238fSKowalski, Kamil     {
12858eb238fSKowalski, Kamil         messages::propertyValueNotInList(asyncResp->res, *certificateType,
12958eb238fSKowalski, Kamil                                          "CertificateType");
13058eb238fSKowalski, Kamil         return std::string();
13158eb238fSKowalski, Kamil     }
13258eb238fSKowalski, Kamil 
13358eb238fSKowalski, Kamil     return certificate;
13458eb238fSKowalski, Kamil }
13558eb238fSKowalski, Kamil 
1365968caeeSMarri Devender Rao /**
1375968caeeSMarri Devender Rao  * Class to create a temporary certificate file for uploading to system
1385968caeeSMarri Devender Rao  */
1395968caeeSMarri Devender Rao class CertificateFile
1405968caeeSMarri Devender Rao {
1415968caeeSMarri Devender Rao   public:
1425968caeeSMarri Devender Rao     CertificateFile() = delete;
1435968caeeSMarri Devender Rao     CertificateFile(const CertificateFile&) = delete;
1445968caeeSMarri Devender Rao     CertificateFile& operator=(const CertificateFile&) = delete;
1455968caeeSMarri Devender Rao     CertificateFile(CertificateFile&&) = delete;
1465968caeeSMarri Devender Rao     CertificateFile& operator=(CertificateFile&&) = delete;
1475968caeeSMarri Devender Rao     CertificateFile(const std::string& certString)
1485968caeeSMarri Devender Rao     {
14972d52d25SEd Tanous         std::array<char, 18> dirTemplate = {'/', 't', 'm', 'p', '/', 'C',
1505207438cSEd Tanous                                             'e', 'r', 't', 's', '.', 'X',
1515207438cSEd Tanous                                             'X', 'X', 'X', 'X', 'X', '\0'};
1525207438cSEd Tanous         char* tempDirectory = mkdtemp(dirTemplate.data());
1535968caeeSMarri Devender Rao         if (tempDirectory)
1545968caeeSMarri Devender Rao         {
1555968caeeSMarri Devender Rao             certDirectory = tempDirectory;
1565968caeeSMarri Devender Rao             certificateFile = certDirectory / "cert.pem";
1575968caeeSMarri Devender Rao             std::ofstream out(certificateFile, std::ofstream::out |
1585968caeeSMarri Devender Rao                                                    std::ofstream::binary |
1595968caeeSMarri Devender Rao                                                    std::ofstream::trunc);
1605968caeeSMarri Devender Rao             out << certString;
1615968caeeSMarri Devender Rao             out.close();
1625968caeeSMarri Devender Rao             BMCWEB_LOG_DEBUG << "Creating certificate file" << certificateFile;
1635968caeeSMarri Devender Rao         }
1645968caeeSMarri Devender Rao     }
1655968caeeSMarri Devender Rao     ~CertificateFile()
1665968caeeSMarri Devender Rao     {
1675968caeeSMarri Devender Rao         if (std::filesystem::exists(certDirectory))
1685968caeeSMarri Devender Rao         {
1695968caeeSMarri Devender Rao             BMCWEB_LOG_DEBUG << "Removing certificate file" << certificateFile;
17023a21a1cSEd Tanous             std::error_code ec;
17123a21a1cSEd Tanous             std::filesystem::remove_all(certDirectory, ec);
17223a21a1cSEd Tanous             if (ec)
1735968caeeSMarri Devender Rao             {
1745968caeeSMarri Devender Rao                 BMCWEB_LOG_ERROR << "Failed to remove temp directory"
1755968caeeSMarri Devender Rao                                  << certDirectory;
1765968caeeSMarri Devender Rao             }
1775968caeeSMarri Devender Rao         }
1785968caeeSMarri Devender Rao     }
1795968caeeSMarri Devender Rao     std::string getCertFilePath()
1805968caeeSMarri Devender Rao     {
1815968caeeSMarri Devender Rao         return certificateFile;
1825968caeeSMarri Devender Rao     }
1835968caeeSMarri Devender Rao 
1845968caeeSMarri Devender Rao   private:
1855968caeeSMarri Devender Rao     std::filesystem::path certificateFile;
1865968caeeSMarri Devender Rao     std::filesystem::path certDirectory;
1875968caeeSMarri Devender Rao };
1885968caeeSMarri Devender Rao 
18930215816SMarri Devender Rao static std::unique_ptr<sdbusplus::bus::match::match> csrMatcher;
19030215816SMarri Devender Rao /**
19130215816SMarri Devender Rao  * @brief Read data from CSR D-bus object and set to response
19230215816SMarri Devender Rao  *
19330215816SMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
19430215816SMarri Devender Rao  * @param[in] certURI Link to certifiate collection URI
19530215816SMarri Devender Rao  * @param[in] service D-Bus service name
19630215816SMarri Devender Rao  * @param[in] certObjPath certificate D-Bus object path
19730215816SMarri Devender Rao  * @param[in] csrObjPath CSR D-Bus object path
19830215816SMarri Devender Rao  * @return None
19930215816SMarri Devender Rao  */
200*8d1b46d7Szhanghch05 static void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
20130215816SMarri Devender Rao                    const std::string& certURI, const std::string& service,
20230215816SMarri Devender Rao                    const std::string& certObjPath,
20330215816SMarri Devender Rao                    const std::string& csrObjPath)
20430215816SMarri Devender Rao {
20530215816SMarri Devender Rao     BMCWEB_LOG_DEBUG << "getCSR CertObjectPath" << certObjPath
20630215816SMarri Devender Rao                      << " CSRObjectPath=" << csrObjPath
20730215816SMarri Devender Rao                      << " service=" << service;
20830215816SMarri Devender Rao     crow::connections::systemBus->async_method_call(
20930215816SMarri Devender Rao         [asyncResp, certURI](const boost::system::error_code ec,
21030215816SMarri Devender Rao                              const std::string& csr) {
21130215816SMarri Devender Rao             if (ec)
21230215816SMarri Devender Rao             {
21330215816SMarri Devender Rao                 BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
21430215816SMarri Devender Rao                 messages::internalError(asyncResp->res);
21530215816SMarri Devender Rao                 return;
21630215816SMarri Devender Rao             }
21730215816SMarri Devender Rao             if (csr.empty())
21830215816SMarri Devender Rao             {
21930215816SMarri Devender Rao                 BMCWEB_LOG_ERROR << "CSR read is empty";
22030215816SMarri Devender Rao                 messages::internalError(asyncResp->res);
22130215816SMarri Devender Rao                 return;
22230215816SMarri Devender Rao             }
22330215816SMarri Devender Rao             asyncResp->res.jsonValue["CSRString"] = csr;
22430215816SMarri Devender Rao             asyncResp->res.jsonValue["CertificateCollection"] = {
22530215816SMarri Devender Rao                 {"@odata.id", certURI}};
22630215816SMarri Devender Rao         },
22730215816SMarri Devender Rao         service, csrObjPath, "xyz.openbmc_project.Certs.CSR", "CSR");
22830215816SMarri Devender Rao }
22930215816SMarri Devender Rao 
23030215816SMarri Devender Rao /**
23130215816SMarri Devender Rao  * Action to Generate CSR
23230215816SMarri Devender Rao  */
23330215816SMarri Devender Rao class CertificateActionGenerateCSR : public Node
23430215816SMarri Devender Rao {
23530215816SMarri Devender Rao   public:
23652cc112dSEd Tanous     CertificateActionGenerateCSR(App& app) :
23730215816SMarri Devender Rao         Node(app, "/redfish/v1/CertificateService/Actions/"
23830215816SMarri Devender Rao                   "CertificateService.GenerateCSR/")
23930215816SMarri Devender Rao     {
24030215816SMarri Devender Rao         entityPrivileges = {
24130215816SMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
24230215816SMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
24330215816SMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
24430215816SMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
24530215816SMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
24630215816SMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
24730215816SMarri Devender Rao     }
24830215816SMarri Devender Rao 
24930215816SMarri Devender Rao   private:
250*8d1b46d7Szhanghch05     void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
251*8d1b46d7Szhanghch05                 const crow::Request& req,
252cb13a392SEd Tanous                 const std::vector<std::string>&) override
25330215816SMarri Devender Rao     {
2542c70f800SEd Tanous         static const int rsaKeyBitLength = 2048;
255*8d1b46d7Szhanghch05 
25630215816SMarri Devender Rao         // Required parameters
25730215816SMarri Devender Rao         std::string city;
25830215816SMarri Devender Rao         std::string commonName;
25930215816SMarri Devender Rao         std::string country;
26030215816SMarri Devender Rao         std::string organization;
26130215816SMarri Devender Rao         std::string organizationalUnit;
26230215816SMarri Devender Rao         std::string state;
26330215816SMarri Devender Rao         nlohmann::json certificateCollection;
26430215816SMarri Devender Rao 
26530215816SMarri Devender Rao         // Optional parameters
26630215816SMarri Devender Rao         std::optional<std::vector<std::string>> optAlternativeNames =
26730215816SMarri Devender Rao             std::vector<std::string>();
26830215816SMarri Devender Rao         std::optional<std::string> optContactPerson = "";
26930215816SMarri Devender Rao         std::optional<std::string> optChallengePassword = "";
27030215816SMarri Devender Rao         std::optional<std::string> optEmail = "";
27130215816SMarri Devender Rao         std::optional<std::string> optGivenName = "";
27230215816SMarri Devender Rao         std::optional<std::string> optInitials = "";
2732c70f800SEd Tanous         std::optional<int64_t> optKeyBitLength = rsaKeyBitLength;
274aaf3206fSVernon Mauery         std::optional<std::string> optKeyCurveId = "secp384r1";
27530215816SMarri Devender Rao         std::optional<std::string> optKeyPairAlgorithm = "EC";
27630215816SMarri Devender Rao         std::optional<std::vector<std::string>> optKeyUsage =
27730215816SMarri Devender Rao             std::vector<std::string>();
27830215816SMarri Devender Rao         std::optional<std::string> optSurname = "";
27930215816SMarri Devender Rao         std::optional<std::string> optUnstructuredName = "";
28030215816SMarri Devender Rao         if (!json_util::readJson(
28130215816SMarri Devender Rao                 req, asyncResp->res, "City", city, "CommonName", commonName,
28230215816SMarri Devender Rao                 "ContactPerson", optContactPerson, "Country", country,
28330215816SMarri Devender Rao                 "Organization", organization, "OrganizationalUnit",
28430215816SMarri Devender Rao                 organizationalUnit, "State", state, "CertificateCollection",
28530215816SMarri Devender Rao                 certificateCollection, "AlternativeNames", optAlternativeNames,
28630215816SMarri Devender Rao                 "ChallengePassword", optChallengePassword, "Email", optEmail,
28730215816SMarri Devender Rao                 "GivenName", optGivenName, "Initials", optInitials,
28830215816SMarri Devender Rao                 "KeyBitLength", optKeyBitLength, "KeyCurveId", optKeyCurveId,
28930215816SMarri Devender Rao                 "KeyPairAlgorithm", optKeyPairAlgorithm, "KeyUsage",
29030215816SMarri Devender Rao                 optKeyUsage, "Surname", optSurname, "UnstructuredName",
29130215816SMarri Devender Rao                 optUnstructuredName))
29230215816SMarri Devender Rao         {
29330215816SMarri Devender Rao             return;
29430215816SMarri Devender Rao         }
29530215816SMarri Devender Rao 
29630215816SMarri Devender Rao         // bmcweb has no way to store or decode a private key challenge
29730215816SMarri Devender Rao         // password, which will likely cause bmcweb to crash on startup if this
29830215816SMarri Devender Rao         // is not set on a post so not allowing the user to set value
29930215816SMarri Devender Rao         if (*optChallengePassword != "")
30030215816SMarri Devender Rao         {
30130215816SMarri Devender Rao             messages::actionParameterNotSupported(asyncResp->res, "GenerateCSR",
30230215816SMarri Devender Rao                                                   "ChallengePassword");
30330215816SMarri Devender Rao             return;
30430215816SMarri Devender Rao         }
30530215816SMarri Devender Rao 
30630215816SMarri Devender Rao         std::string certURI;
30730215816SMarri Devender Rao         if (!redfish::json_util::readJson(certificateCollection, asyncResp->res,
30830215816SMarri Devender Rao                                           "@odata.id", certURI))
30930215816SMarri Devender Rao         {
31030215816SMarri Devender Rao             return;
31130215816SMarri Devender Rao         }
31230215816SMarri Devender Rao 
31330215816SMarri Devender Rao         std::string objectPath;
31430215816SMarri Devender Rao         std::string service;
31530215816SMarri Devender Rao         if (boost::starts_with(
31630215816SMarri Devender Rao                 certURI,
31730215816SMarri Devender Rao                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
31830215816SMarri Devender Rao         {
31930215816SMarri Devender Rao             objectPath = certs::httpsObjectPath;
32030215816SMarri Devender Rao             service = certs::httpsServiceName;
32130215816SMarri Devender Rao         }
3223b7f0149SMarri Devender Rao         else if (boost::starts_with(
3233b7f0149SMarri Devender Rao                      certURI, "/redfish/v1/AccountService/LDAP/Certificates"))
3243b7f0149SMarri Devender Rao         {
3253b7f0149SMarri Devender Rao             objectPath = certs::ldapObjectPath;
3263b7f0149SMarri Devender Rao             service = certs::ldapServiceName;
3273b7f0149SMarri Devender Rao         }
32830215816SMarri Devender Rao         else
32930215816SMarri Devender Rao         {
33030215816SMarri Devender Rao             messages::actionParameterNotSupported(
33130215816SMarri Devender Rao                 asyncResp->res, "CertificateCollection", "GenerateCSR");
33230215816SMarri Devender Rao             return;
33330215816SMarri Devender Rao         }
33430215816SMarri Devender Rao 
33530215816SMarri Devender Rao         // supporting only EC and RSA algorithm
33630215816SMarri Devender Rao         if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
33730215816SMarri Devender Rao         {
33830215816SMarri Devender Rao             messages::actionParameterNotSupported(
33930215816SMarri Devender Rao                 asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
34030215816SMarri Devender Rao             return;
34130215816SMarri Devender Rao         }
34230215816SMarri Devender Rao 
34330215816SMarri Devender Rao         // supporting only 2048 key bit length for RSA algorithm due to time
34430215816SMarri Devender Rao         // consumed in generating private key
34530215816SMarri Devender Rao         if (*optKeyPairAlgorithm == "RSA" &&
3462c70f800SEd Tanous             *optKeyBitLength != rsaKeyBitLength)
34730215816SMarri Devender Rao         {
34830215816SMarri Devender Rao             messages::propertyValueNotInList(asyncResp->res,
34930215816SMarri Devender Rao                                              std::to_string(*optKeyBitLength),
35030215816SMarri Devender Rao                                              "KeyBitLength");
35130215816SMarri Devender Rao             return;
35230215816SMarri Devender Rao         }
35330215816SMarri Devender Rao 
35430215816SMarri Devender Rao         // validate KeyUsage supporting only 1 type based on URL
35530215816SMarri Devender Rao         if (boost::starts_with(
35630215816SMarri Devender Rao                 certURI,
35730215816SMarri Devender Rao                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
35830215816SMarri Devender Rao         {
35930215816SMarri Devender Rao             if (optKeyUsage->size() == 0)
36030215816SMarri Devender Rao             {
36130215816SMarri Devender Rao                 optKeyUsage->push_back("ServerAuthentication");
36230215816SMarri Devender Rao             }
36330215816SMarri Devender Rao             else if (optKeyUsage->size() == 1)
36430215816SMarri Devender Rao             {
36530215816SMarri Devender Rao                 if ((*optKeyUsage)[0] != "ServerAuthentication")
36630215816SMarri Devender Rao                 {
36730215816SMarri Devender Rao                     messages::propertyValueNotInList(
36830215816SMarri Devender Rao                         asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
36930215816SMarri Devender Rao                     return;
37030215816SMarri Devender Rao                 }
37130215816SMarri Devender Rao             }
37230215816SMarri Devender Rao             else
37330215816SMarri Devender Rao             {
37430215816SMarri Devender Rao                 messages::actionParameterNotSupported(
37530215816SMarri Devender Rao                     asyncResp->res, "KeyUsage", "GenerateCSR");
37630215816SMarri Devender Rao                 return;
37730215816SMarri Devender Rao             }
37830215816SMarri Devender Rao         }
3793b7f0149SMarri Devender Rao         else if (boost::starts_with(
3803b7f0149SMarri Devender Rao                      certURI, "/redfish/v1/AccountService/LDAP/Certificates"))
3813b7f0149SMarri Devender Rao         {
3823b7f0149SMarri Devender Rao             if (optKeyUsage->size() == 0)
3833b7f0149SMarri Devender Rao             {
3843b7f0149SMarri Devender Rao                 optKeyUsage->push_back("ClientAuthentication");
3853b7f0149SMarri Devender Rao             }
3863b7f0149SMarri Devender Rao             else if (optKeyUsage->size() == 1)
3873b7f0149SMarri Devender Rao             {
3883b7f0149SMarri Devender Rao                 if ((*optKeyUsage)[0] != "ClientAuthentication")
3893b7f0149SMarri Devender Rao                 {
3903b7f0149SMarri Devender Rao                     messages::propertyValueNotInList(
3913b7f0149SMarri Devender Rao                         asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
3923b7f0149SMarri Devender Rao                     return;
3933b7f0149SMarri Devender Rao                 }
3943b7f0149SMarri Devender Rao             }
3953b7f0149SMarri Devender Rao             else
3963b7f0149SMarri Devender Rao             {
3973b7f0149SMarri Devender Rao                 messages::actionParameterNotSupported(
3983b7f0149SMarri Devender Rao                     asyncResp->res, "KeyUsage", "GenerateCSR");
3993b7f0149SMarri Devender Rao                 return;
4003b7f0149SMarri Devender Rao             }
4013b7f0149SMarri Devender Rao         }
40230215816SMarri Devender Rao 
40330215816SMarri Devender Rao         // Only allow one CSR matcher at a time so setting retry time-out and
40430215816SMarri Devender Rao         // timer expiry to 10 seconds for now.
4052c70f800SEd Tanous         static const int timeOut = 10;
40630215816SMarri Devender Rao         if (csrMatcher)
40730215816SMarri Devender Rao         {
40830215816SMarri Devender Rao             messages::serviceTemporarilyUnavailable(asyncResp->res,
4092c70f800SEd Tanous                                                     std::to_string(timeOut));
41030215816SMarri Devender Rao             return;
41130215816SMarri Devender Rao         }
41230215816SMarri Devender Rao 
41330215816SMarri Devender Rao         // Make this static so it survives outside this method
41430215816SMarri Devender Rao         static boost::asio::steady_timer timeout(*req.ioService);
4152c70f800SEd Tanous         timeout.expires_after(std::chrono::seconds(timeOut));
41630215816SMarri Devender Rao         timeout.async_wait([asyncResp](const boost::system::error_code& ec) {
41730215816SMarri Devender Rao             csrMatcher = nullptr;
41830215816SMarri Devender Rao             if (ec)
41930215816SMarri Devender Rao             {
42030215816SMarri Devender Rao                 // operation_aborted is expected if timer is canceled before
42130215816SMarri Devender Rao                 // completion.
42230215816SMarri Devender Rao                 if (ec != boost::asio::error::operation_aborted)
42330215816SMarri Devender Rao                 {
42430215816SMarri Devender Rao                     BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
42530215816SMarri Devender Rao                 }
42630215816SMarri Devender Rao                 return;
42730215816SMarri Devender Rao             }
42830215816SMarri Devender Rao             BMCWEB_LOG_ERROR << "Timed out waiting for Generating CSR";
42930215816SMarri Devender Rao             messages::internalError(asyncResp->res);
43030215816SMarri Devender Rao         });
43130215816SMarri Devender Rao 
43230215816SMarri Devender Rao         // create a matcher to wait on CSR object
43330215816SMarri Devender Rao         BMCWEB_LOG_DEBUG << "create matcher with path " << objectPath;
43430215816SMarri Devender Rao         std::string match("type='signal',"
43530215816SMarri Devender Rao                           "interface='org.freedesktop.DBus.ObjectManager',"
43630215816SMarri Devender Rao                           "path='" +
43730215816SMarri Devender Rao                           objectPath +
43830215816SMarri Devender Rao                           "',"
43930215816SMarri Devender Rao                           "member='InterfacesAdded'");
44030215816SMarri Devender Rao         csrMatcher = std::make_unique<sdbusplus::bus::match::match>(
44130215816SMarri Devender Rao             *crow::connections::systemBus, match,
44230215816SMarri Devender Rao             [asyncResp, service, objectPath,
44330215816SMarri Devender Rao              certURI](sdbusplus::message::message& m) {
444271584abSEd Tanous                 timeout.cancel();
44530215816SMarri Devender Rao                 if (m.is_method_error())
44630215816SMarri Devender Rao                 {
44730215816SMarri Devender Rao                     BMCWEB_LOG_ERROR << "Dbus method error!!!";
44830215816SMarri Devender Rao                     messages::internalError(asyncResp->res);
44930215816SMarri Devender Rao                     return;
45030215816SMarri Devender Rao                 }
45130215816SMarri Devender Rao                 std::vector<std::pair<
45230215816SMarri Devender Rao                     std::string, std::vector<std::pair<
45330215816SMarri Devender Rao                                      std::string, std::variant<std::string>>>>>
45430215816SMarri Devender Rao                     interfacesProperties;
45530215816SMarri Devender Rao                 sdbusplus::message::object_path csrObjectPath;
45630215816SMarri Devender Rao                 m.read(csrObjectPath, interfacesProperties);
45730215816SMarri Devender Rao                 BMCWEB_LOG_DEBUG << "CSR object added" << csrObjectPath.str;
45830215816SMarri Devender Rao                 for (auto& interface : interfacesProperties)
45930215816SMarri Devender Rao                 {
46030215816SMarri Devender Rao                     if (interface.first == "xyz.openbmc_project.Certs.CSR")
46130215816SMarri Devender Rao                     {
46230215816SMarri Devender Rao                         getCSR(asyncResp, certURI, service, objectPath,
46330215816SMarri Devender Rao                                csrObjectPath.str);
46430215816SMarri Devender Rao                         break;
46530215816SMarri Devender Rao                     }
46630215816SMarri Devender Rao                 }
46730215816SMarri Devender Rao             });
46830215816SMarri Devender Rao         crow::connections::systemBus->async_method_call(
469271584abSEd Tanous             [asyncResp](const boost::system::error_code& ec,
470cb13a392SEd Tanous                         const std::string&) {
47130215816SMarri Devender Rao                 if (ec)
47230215816SMarri Devender Rao                 {
47330215816SMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec.message();
47430215816SMarri Devender Rao                     messages::internalError(asyncResp->res);
47530215816SMarri Devender Rao                     return;
47630215816SMarri Devender Rao                 }
47730215816SMarri Devender Rao             },
47830215816SMarri Devender Rao             service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
47930215816SMarri Devender Rao             "GenerateCSR", *optAlternativeNames, *optChallengePassword, city,
48030215816SMarri Devender Rao             commonName, *optContactPerson, country, *optEmail, *optGivenName,
48130215816SMarri Devender Rao             *optInitials, *optKeyBitLength, *optKeyCurveId,
48230215816SMarri Devender Rao             *optKeyPairAlgorithm, *optKeyUsage, organization,
48330215816SMarri Devender Rao             organizationalUnit, state, *optSurname, *optUnstructuredName);
48430215816SMarri Devender Rao     }
48530215816SMarri Devender Rao }; // CertificateActionGenerateCSR
48630215816SMarri Devender Rao 
4875968caeeSMarri Devender Rao /**
4884e0453b1SGunnar Mills  * @brief Parse and update Certificate Issue/Subject property
4895968caeeSMarri Devender Rao  *
4905968caeeSMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
4915968caeeSMarri Devender Rao  * @param[in] str  Issuer/Subject value in key=value pairs
4925968caeeSMarri Devender Rao  * @param[in] type Issuer/Subject
4935968caeeSMarri Devender Rao  * @return None
4945968caeeSMarri Devender Rao  */
4955968caeeSMarri Devender Rao static void updateCertIssuerOrSubject(nlohmann::json& out,
4965968caeeSMarri Devender Rao                                       const std::string_view value)
4975968caeeSMarri Devender Rao {
4985968caeeSMarri Devender Rao     // example: O=openbmc-project.xyz,CN=localhost
4995968caeeSMarri Devender Rao     std::string_view::iterator i = value.begin();
5005968caeeSMarri Devender Rao     while (i != value.end())
5015968caeeSMarri Devender Rao     {
5025968caeeSMarri Devender Rao         std::string_view::iterator tokenBegin = i;
5035968caeeSMarri Devender Rao         while (i != value.end() && *i != '=')
5045968caeeSMarri Devender Rao         {
50517a897dfSManojkiran Eda             ++i;
5065968caeeSMarri Devender Rao         }
5075968caeeSMarri Devender Rao         if (i == value.end())
5085968caeeSMarri Devender Rao         {
5095968caeeSMarri Devender Rao             break;
5105968caeeSMarri Devender Rao         }
511271584abSEd Tanous         const std::string_view key(tokenBegin,
512271584abSEd Tanous                                    static_cast<size_t>(i - tokenBegin));
51317a897dfSManojkiran Eda         ++i;
5145968caeeSMarri Devender Rao         tokenBegin = i;
5155968caeeSMarri Devender Rao         while (i != value.end() && *i != ',')
5165968caeeSMarri Devender Rao         {
51717a897dfSManojkiran Eda             ++i;
5185968caeeSMarri Devender Rao         }
519271584abSEd Tanous         const std::string_view val(tokenBegin,
520271584abSEd Tanous                                    static_cast<size_t>(i - tokenBegin));
5215968caeeSMarri Devender Rao         if (key == "L")
5225968caeeSMarri Devender Rao         {
5235968caeeSMarri Devender Rao             out["City"] = val;
5245968caeeSMarri Devender Rao         }
5255968caeeSMarri Devender Rao         else if (key == "CN")
5265968caeeSMarri Devender Rao         {
5275968caeeSMarri Devender Rao             out["CommonName"] = val;
5285968caeeSMarri Devender Rao         }
5295968caeeSMarri Devender Rao         else if (key == "C")
5305968caeeSMarri Devender Rao         {
5315968caeeSMarri Devender Rao             out["Country"] = val;
5325968caeeSMarri Devender Rao         }
5335968caeeSMarri Devender Rao         else if (key == "O")
5345968caeeSMarri Devender Rao         {
5355968caeeSMarri Devender Rao             out["Organization"] = val;
5365968caeeSMarri Devender Rao         }
5375968caeeSMarri Devender Rao         else if (key == "OU")
5385968caeeSMarri Devender Rao         {
5395968caeeSMarri Devender Rao             out["OrganizationalUnit"] = val;
5405968caeeSMarri Devender Rao         }
5415968caeeSMarri Devender Rao         else if (key == "ST")
5425968caeeSMarri Devender Rao         {
5435968caeeSMarri Devender Rao             out["State"] = val;
5445968caeeSMarri Devender Rao         }
5455968caeeSMarri Devender Rao         // skip comma character
5465968caeeSMarri Devender Rao         if (i != value.end())
5475968caeeSMarri Devender Rao         {
54817a897dfSManojkiran Eda             ++i;
5495968caeeSMarri Devender Rao         }
5505968caeeSMarri Devender Rao     }
5515968caeeSMarri Devender Rao }
5525968caeeSMarri Devender Rao 
5535968caeeSMarri Devender Rao /**
5545968caeeSMarri Devender Rao  * @brief Retrieve the certificates properties and append to the response
5555968caeeSMarri Devender Rao  * message
5565968caeeSMarri Devender Rao  *
5575968caeeSMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
5585968caeeSMarri Devender Rao  * @param[in] objectPath  Path of the D-Bus service object
5595968caeeSMarri Devender Rao  * @param[in] certId  Id of the certificate
5605968caeeSMarri Devender Rao  * @param[in] certURL  URL of the certificate object
5615968caeeSMarri Devender Rao  * @param[in] name  name of the certificate
5625968caeeSMarri Devender Rao  * @return None
5635968caeeSMarri Devender Rao  */
5645968caeeSMarri Devender Rao static void getCertificateProperties(
565*8d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
566*8d1b46d7Szhanghch05     const std::string& objectPath, const std::string& service, long certId,
567*8d1b46d7Szhanghch05     const std::string& certURL, const std::string& name)
5685968caeeSMarri Devender Rao {
5695968caeeSMarri Devender Rao     using PropertyType =
5705968caeeSMarri Devender Rao         std::variant<std::string, uint64_t, std::vector<std::string>>;
5715968caeeSMarri Devender Rao     using PropertiesMap = boost::container::flat_map<std::string, PropertyType>;
5725968caeeSMarri Devender Rao     BMCWEB_LOG_DEBUG << "getCertificateProperties Path=" << objectPath
5735968caeeSMarri Devender Rao                      << " certId=" << certId << " certURl=" << certURL;
5745968caeeSMarri Devender Rao     crow::connections::systemBus->async_method_call(
57537cce918SMarri Devender Rao         [asyncResp, certURL, certId, name](const boost::system::error_code ec,
5765968caeeSMarri Devender Rao                                            const PropertiesMap& properties) {
5775968caeeSMarri Devender Rao             if (ec)
5785968caeeSMarri Devender Rao             {
5795968caeeSMarri Devender Rao                 BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
5808aae75adSMarri Devender Rao                 messages::resourceNotFound(asyncResp->res, name,
5818aae75adSMarri Devender Rao                                            std::to_string(certId));
5825968caeeSMarri Devender Rao                 return;
5835968caeeSMarri Devender Rao             }
5845968caeeSMarri Devender Rao             asyncResp->res.jsonValue = {
5855968caeeSMarri Devender Rao                 {"@odata.id", certURL},
5865968caeeSMarri Devender Rao                 {"@odata.type", "#Certificate.v1_0_0.Certificate"},
5875968caeeSMarri Devender Rao                 {"Id", std::to_string(certId)},
5885968caeeSMarri Devender Rao                 {"Name", name},
5895968caeeSMarri Devender Rao                 {"Description", name}};
5905968caeeSMarri Devender Rao             for (const auto& property : properties)
5915968caeeSMarri Devender Rao             {
5925968caeeSMarri Devender Rao                 if (property.first == "CertificateString")
5935968caeeSMarri Devender Rao                 {
5945968caeeSMarri Devender Rao                     asyncResp->res.jsonValue["CertificateString"] = "";
5955968caeeSMarri Devender Rao                     const std::string* value =
5965968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
5975968caeeSMarri Devender Rao                     if (value)
5985968caeeSMarri Devender Rao                     {
59937cce918SMarri Devender Rao                         asyncResp->res.jsonValue["CertificateString"] = *value;
6005968caeeSMarri Devender Rao                     }
6015968caeeSMarri Devender Rao                 }
6025968caeeSMarri Devender Rao                 else if (property.first == "KeyUsage")
6035968caeeSMarri Devender Rao                 {
6045968caeeSMarri Devender Rao                     nlohmann::json& keyUsage =
6055968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["KeyUsage"];
6065968caeeSMarri Devender Rao                     keyUsage = nlohmann::json::array();
6075968caeeSMarri Devender Rao                     const std::vector<std::string>* value =
60837cce918SMarri Devender Rao                         std::get_if<std::vector<std::string>>(&property.second);
6095968caeeSMarri Devender Rao                     if (value)
6105968caeeSMarri Devender Rao                     {
6115968caeeSMarri Devender Rao                         for (const std::string& usage : *value)
6125968caeeSMarri Devender Rao                         {
6135968caeeSMarri Devender Rao                             keyUsage.push_back(usage);
6145968caeeSMarri Devender Rao                         }
6155968caeeSMarri Devender Rao                     }
6165968caeeSMarri Devender Rao                 }
6175968caeeSMarri Devender Rao                 else if (property.first == "Issuer")
6185968caeeSMarri Devender Rao                 {
6195968caeeSMarri Devender Rao                     const std::string* value =
6205968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
6215968caeeSMarri Devender Rao                     if (value)
6225968caeeSMarri Devender Rao                     {
6235968caeeSMarri Devender Rao                         updateCertIssuerOrSubject(
6245968caeeSMarri Devender Rao                             asyncResp->res.jsonValue["Issuer"], *value);
6255968caeeSMarri Devender Rao                     }
6265968caeeSMarri Devender Rao                 }
6275968caeeSMarri Devender Rao                 else if (property.first == "Subject")
6285968caeeSMarri Devender Rao                 {
6295968caeeSMarri Devender Rao                     const std::string* value =
6305968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
6315968caeeSMarri Devender Rao                     if (value)
6325968caeeSMarri Devender Rao                     {
6335968caeeSMarri Devender Rao                         updateCertIssuerOrSubject(
63437cce918SMarri Devender Rao                             asyncResp->res.jsonValue["Subject"], *value);
6355968caeeSMarri Devender Rao                     }
6365968caeeSMarri Devender Rao                 }
6375968caeeSMarri Devender Rao                 else if (property.first == "ValidNotAfter")
6385968caeeSMarri Devender Rao                 {
6395968caeeSMarri Devender Rao                     const uint64_t* value =
6405968caeeSMarri Devender Rao                         std::get_if<uint64_t>(&property.second);
6415968caeeSMarri Devender Rao                     if (value)
6425968caeeSMarri Devender Rao                     {
64337cce918SMarri Devender Rao                         std::time_t time = static_cast<std::time_t>(*value);
6445968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["ValidNotAfter"] =
6455968caeeSMarri Devender Rao                             crow::utility::getDateTime(time);
6465968caeeSMarri Devender Rao                     }
6475968caeeSMarri Devender Rao                 }
6485968caeeSMarri Devender Rao                 else if (property.first == "ValidNotBefore")
6495968caeeSMarri Devender Rao                 {
6505968caeeSMarri Devender Rao                     const uint64_t* value =
6515968caeeSMarri Devender Rao                         std::get_if<uint64_t>(&property.second);
6525968caeeSMarri Devender Rao                     if (value)
6535968caeeSMarri Devender Rao                     {
65437cce918SMarri Devender Rao                         std::time_t time = static_cast<std::time_t>(*value);
6555968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["ValidNotBefore"] =
6565968caeeSMarri Devender Rao                             crow::utility::getDateTime(time);
6575968caeeSMarri Devender Rao                     }
6585968caeeSMarri Devender Rao                 }
6595968caeeSMarri Devender Rao             }
6605968caeeSMarri Devender Rao             asyncResp->res.addHeader("Location", certURL);
6615968caeeSMarri Devender Rao         },
6625968caeeSMarri Devender Rao         service, objectPath, certs::dbusPropIntf, "GetAll",
6635968caeeSMarri Devender Rao         certs::certPropIntf);
6645968caeeSMarri Devender Rao }
6655968caeeSMarri Devender Rao 
6665968caeeSMarri Devender Rao using GetObjectType =
6675968caeeSMarri Devender Rao     std::vector<std::pair<std::string, std::vector<std::string>>>;
6685968caeeSMarri Devender Rao 
6695968caeeSMarri Devender Rao /**
6705968caeeSMarri Devender Rao  * Action to replace an existing certificate
6715968caeeSMarri Devender Rao  */
6725968caeeSMarri Devender Rao class CertificateActionsReplaceCertificate : public Node
6735968caeeSMarri Devender Rao {
6745968caeeSMarri Devender Rao   public:
67552cc112dSEd Tanous     CertificateActionsReplaceCertificate(App& app) :
6765968caeeSMarri Devender Rao         Node(app, "/redfish/v1/CertificateService/Actions/"
6775968caeeSMarri Devender Rao                   "CertificateService.ReplaceCertificate/")
6785968caeeSMarri Devender Rao     {
6795968caeeSMarri Devender Rao         entityPrivileges = {
6805968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
6815968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
6825968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
6835968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
6845968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
6855968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
6865968caeeSMarri Devender Rao     }
6875968caeeSMarri Devender Rao 
6885968caeeSMarri Devender Rao   private:
689*8d1b46d7Szhanghch05     void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
690*8d1b46d7Szhanghch05                 const crow::Request& req,
691cb13a392SEd Tanous                 const std::vector<std::string>&) override
6925968caeeSMarri Devender Rao     {
6935968caeeSMarri Devender Rao         std::string certificate;
6945968caeeSMarri Devender Rao         nlohmann::json certificateUri;
6955968caeeSMarri Devender Rao         std::optional<std::string> certificateType = "PEM";
696*8d1b46d7Szhanghch05 
6975968caeeSMarri Devender Rao         if (!json_util::readJson(req, asyncResp->res, "CertificateString",
6985968caeeSMarri Devender Rao                                  certificate, "CertificateUri", certificateUri,
6995968caeeSMarri Devender Rao                                  "CertificateType", certificateType))
7005968caeeSMarri Devender Rao         {
7015968caeeSMarri Devender Rao             BMCWEB_LOG_ERROR << "Required parameters are missing";
7025968caeeSMarri Devender Rao             messages::internalError(asyncResp->res);
7035968caeeSMarri Devender Rao             return;
7045968caeeSMarri Devender Rao         }
7055968caeeSMarri Devender Rao 
7065968caeeSMarri Devender Rao         if (!certificateType)
7075968caeeSMarri Devender Rao         {
7085968caeeSMarri Devender Rao             // should never happen, but it never hurts to be paranoid.
7095968caeeSMarri Devender Rao             return;
7105968caeeSMarri Devender Rao         }
7115968caeeSMarri Devender Rao         if (certificateType != "PEM")
7125968caeeSMarri Devender Rao         {
7135968caeeSMarri Devender Rao             messages::actionParameterNotSupported(
7145968caeeSMarri Devender Rao                 asyncResp->res, "CertificateType", "ReplaceCertificate");
7155968caeeSMarri Devender Rao             return;
7165968caeeSMarri Devender Rao         }
7175968caeeSMarri Devender Rao 
7185968caeeSMarri Devender Rao         std::string certURI;
7195968caeeSMarri Devender Rao         if (!redfish::json_util::readJson(certificateUri, asyncResp->res,
7205968caeeSMarri Devender Rao                                           "@odata.id", certURI))
7215968caeeSMarri Devender Rao         {
7225968caeeSMarri Devender Rao             messages::actionParameterMissing(
7235968caeeSMarri Devender Rao                 asyncResp->res, "ReplaceCertificate", "CertificateUri");
7245968caeeSMarri Devender Rao             return;
7255968caeeSMarri Devender Rao         }
7265968caeeSMarri Devender Rao 
7275968caeeSMarri Devender Rao         BMCWEB_LOG_INFO << "Certificate URI to replace" << certURI;
7285968caeeSMarri Devender Rao         long id = getIDFromURL(certURI);
7295968caeeSMarri Devender Rao         if (id < 0)
7305968caeeSMarri Devender Rao         {
7315968caeeSMarri Devender Rao             messages::actionParameterValueFormatError(asyncResp->res, certURI,
7325968caeeSMarri Devender Rao                                                       "CertificateUri",
7335968caeeSMarri Devender Rao                                                       "ReplaceCertificate");
7345968caeeSMarri Devender Rao             return;
7355968caeeSMarri Devender Rao         }
7365968caeeSMarri Devender Rao         std::string objectPath;
7375968caeeSMarri Devender Rao         std::string name;
73837cce918SMarri Devender Rao         std::string service;
7395968caeeSMarri Devender Rao         if (boost::starts_with(
7405968caeeSMarri Devender Rao                 certURI,
7415968caeeSMarri Devender Rao                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/"))
7425968caeeSMarri Devender Rao         {
7435968caeeSMarri Devender Rao             objectPath =
7445968caeeSMarri Devender Rao                 std::string(certs::httpsObjectPath) + "/" + std::to_string(id);
7455968caeeSMarri Devender Rao             name = "HTTPS certificate";
74637cce918SMarri Devender Rao             service = certs::httpsServiceName;
74737cce918SMarri Devender Rao         }
74837cce918SMarri Devender Rao         else if (boost::starts_with(
74937cce918SMarri Devender Rao                      certURI, "/redfish/v1/AccountService/LDAP/Certificates/"))
75037cce918SMarri Devender Rao         {
75137cce918SMarri Devender Rao             objectPath =
75237cce918SMarri Devender Rao                 std::string(certs::ldapObjectPath) + "/" + std::to_string(id);
75337cce918SMarri Devender Rao             name = "LDAP certificate";
75437cce918SMarri Devender Rao             service = certs::ldapServiceName;
7555968caeeSMarri Devender Rao         }
756cfcd5f6bSMarri Devender Rao         else if (boost::starts_with(
757cfcd5f6bSMarri Devender Rao                      certURI,
758cfcd5f6bSMarri Devender Rao                      "/redfish/v1/Managers/bmc/Truststore/Certificates/"))
759cfcd5f6bSMarri Devender Rao         {
760cfcd5f6bSMarri Devender Rao             objectPath = std::string(certs::authorityObjectPath) + "/" +
761cfcd5f6bSMarri Devender Rao                          std::to_string(id);
762cfcd5f6bSMarri Devender Rao             name = "TrustStore certificate";
763cfcd5f6bSMarri Devender Rao             service = certs::authorityServiceName;
764cfcd5f6bSMarri Devender Rao         }
7655968caeeSMarri Devender Rao         else
7665968caeeSMarri Devender Rao         {
7675968caeeSMarri Devender Rao             messages::actionParameterNotSupported(
7685968caeeSMarri Devender Rao                 asyncResp->res, "CertificateUri", "ReplaceCertificate");
7695968caeeSMarri Devender Rao             return;
7705968caeeSMarri Devender Rao         }
7715968caeeSMarri Devender Rao 
7725968caeeSMarri Devender Rao         std::shared_ptr<CertificateFile> certFile =
7735968caeeSMarri Devender Rao             std::make_shared<CertificateFile>(certificate);
7745968caeeSMarri Devender Rao         crow::connections::systemBus->async_method_call(
77537cce918SMarri Devender Rao             [asyncResp, certFile, objectPath, service, certURI, id,
7765968caeeSMarri Devender Rao              name](const boost::system::error_code ec) {
7775968caeeSMarri Devender Rao                 if (ec)
7785968caeeSMarri Devender Rao                 {
7795968caeeSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
7808aae75adSMarri Devender Rao                     messages::resourceNotFound(asyncResp->res, name,
7818aae75adSMarri Devender Rao                                                std::to_string(id));
7825968caeeSMarri Devender Rao                     return;
7835968caeeSMarri Devender Rao                 }
78437cce918SMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath, service, id,
7855968caeeSMarri Devender Rao                                          certURI, name);
7865968caeeSMarri Devender Rao                 BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
7875968caeeSMarri Devender Rao                                  << certFile->getCertFilePath();
7885968caeeSMarri Devender Rao             },
7895968caeeSMarri Devender Rao             service, objectPath, certs::certReplaceIntf, "Replace",
7905968caeeSMarri Devender Rao             certFile->getCertFilePath());
7915968caeeSMarri Devender Rao     }
7925968caeeSMarri Devender Rao }; // CertificateActionsReplaceCertificate
7935968caeeSMarri Devender Rao 
7945968caeeSMarri Devender Rao /**
7955968caeeSMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
7965968caeeSMarri Devender Rao  * of a component, account or service.
7975968caeeSMarri Devender Rao  */
7985968caeeSMarri Devender Rao class HTTPSCertificate : public Node
7995968caeeSMarri Devender Rao {
8005968caeeSMarri Devender Rao   public:
80152cc112dSEd Tanous     HTTPSCertificate(App& app) :
8025968caeeSMarri Devender Rao         Node(app,
8035968caeeSMarri Devender Rao              "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/"
8045968caeeSMarri Devender Rao              "<str>/",
8055968caeeSMarri Devender Rao              std::string())
8065968caeeSMarri Devender Rao     {
8075968caeeSMarri Devender Rao         entityPrivileges = {
8085968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
8095968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
8105968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
8115968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
8125968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
8135968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
8145968caeeSMarri Devender Rao     }
8155968caeeSMarri Devender Rao 
816*8d1b46d7Szhanghch05     void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
817*8d1b46d7Szhanghch05                const crow::Request& req,
8185968caeeSMarri Devender Rao                const std::vector<std::string>& params) override
8195968caeeSMarri Devender Rao     {
820*8d1b46d7Szhanghch05 
8215968caeeSMarri Devender Rao         if (params.size() != 1)
8225968caeeSMarri Devender Rao         {
8235968caeeSMarri Devender Rao             messages::internalError(asyncResp->res);
8245968caeeSMarri Devender Rao             return;
8255968caeeSMarri Devender Rao         }
8265968caeeSMarri Devender Rao         long id = getIDFromURL(req.url);
8275968caeeSMarri Devender Rao 
8285968caeeSMarri Devender Rao         BMCWEB_LOG_DEBUG << "HTTPSCertificate::doGet ID=" << std::to_string(id);
8295968caeeSMarri Devender Rao         std::string certURL =
8305968caeeSMarri Devender Rao             "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" +
8315968caeeSMarri Devender Rao             std::to_string(id);
8325968caeeSMarri Devender Rao         std::string objectPath = certs::httpsObjectPath;
8335968caeeSMarri Devender Rao         objectPath += "/";
8345968caeeSMarri Devender Rao         objectPath += std::to_string(id);
83537cce918SMarri Devender Rao         getCertificateProperties(asyncResp, objectPath, certs::httpsServiceName,
83637cce918SMarri Devender Rao                                  id, certURL, "HTTPS Certificate");
8375968caeeSMarri Devender Rao     }
8385968caeeSMarri Devender Rao 
8395968caeeSMarri Devender Rao }; // namespace redfish
8405968caeeSMarri Devender Rao 
8415968caeeSMarri Devender Rao /**
8425968caeeSMarri Devender Rao  * Collection of HTTPS certificates
8435968caeeSMarri Devender Rao  */
8445968caeeSMarri Devender Rao class HTTPSCertificateCollection : public Node
8455968caeeSMarri Devender Rao {
8465968caeeSMarri Devender Rao   public:
84752cc112dSEd Tanous     HTTPSCertificateCollection(App& app) :
8485968caeeSMarri Devender Rao         Node(app,
8495968caeeSMarri Devender Rao              "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
8505968caeeSMarri Devender Rao     {
8515968caeeSMarri Devender Rao         entityPrivileges = {
8525968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
8535968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
8545968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
8555968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
8565968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
8575968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
8585968caeeSMarri Devender Rao     }
859*8d1b46d7Szhanghch05     void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
860*8d1b46d7Szhanghch05                const crow::Request&, const std::vector<std::string>&) override
8615968caeeSMarri Devender Rao     {
862*8d1b46d7Szhanghch05         asyncResp->res.jsonValue = {
8635968caeeSMarri Devender Rao             {"@odata.id",
8645968caeeSMarri Devender Rao              "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"},
8655968caeeSMarri Devender Rao             {"@odata.type", "#CertificateCollection.CertificateCollection"},
8665968caeeSMarri Devender Rao             {"Name", "HTTPS Certificates Collection"},
8675968caeeSMarri Devender Rao             {"Description", "A Collection of HTTPS certificate instances"}};
868*8d1b46d7Szhanghch05 
8695968caeeSMarri Devender Rao         crow::connections::systemBus->async_method_call(
8705968caeeSMarri Devender Rao             [asyncResp](const boost::system::error_code ec,
8715968caeeSMarri Devender Rao                         const ManagedObjectType& certs) {
8725968caeeSMarri Devender Rao                 if (ec)
8735968caeeSMarri Devender Rao                 {
8745968caeeSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
8755968caeeSMarri Devender Rao                     messages::internalError(asyncResp->res);
8765968caeeSMarri Devender Rao                     return;
8775968caeeSMarri Devender Rao                 }
87837cce918SMarri Devender Rao                 nlohmann::json& members = asyncResp->res.jsonValue["Members"];
8795968caeeSMarri Devender Rao                 members = nlohmann::json::array();
8805968caeeSMarri Devender Rao                 for (const auto& cert : certs)
8815968caeeSMarri Devender Rao                 {
8825968caeeSMarri Devender Rao                     long id = getIDFromURL(cert.first.str);
88337cce918SMarri Devender Rao                     if (id >= 0)
8845968caeeSMarri Devender Rao                     {
8855968caeeSMarri Devender Rao                         members.push_back(
8865968caeeSMarri Devender Rao                             {{"@odata.id",
8875968caeeSMarri Devender Rao                               "/redfish/v1/Managers/bmc/"
8885968caeeSMarri Devender Rao                               "NetworkProtocol/HTTPS/Certificates/" +
8895968caeeSMarri Devender Rao                                   std::to_string(id)}});
8905968caeeSMarri Devender Rao                     }
8915968caeeSMarri Devender Rao                 }
8925968caeeSMarri Devender Rao                 asyncResp->res.jsonValue["Members@odata.count"] =
8935968caeeSMarri Devender Rao                     members.size();
8945968caeeSMarri Devender Rao             },
89537cce918SMarri Devender Rao             certs::httpsServiceName, certs::httpsObjectPath,
89637cce918SMarri Devender Rao             certs::dbusObjManagerIntf, "GetManagedObjects");
8975968caeeSMarri Devender Rao     }
8985968caeeSMarri Devender Rao 
899*8d1b46d7Szhanghch05     void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
900*8d1b46d7Szhanghch05                 const crow::Request& req,
901cb13a392SEd Tanous                 const std::vector<std::string>&) override
9025968caeeSMarri Devender Rao     {
9035968caeeSMarri Devender Rao         BMCWEB_LOG_DEBUG << "HTTPSCertificateCollection::doPost";
904*8d1b46d7Szhanghch05 
9055968caeeSMarri Devender Rao         asyncResp->res.jsonValue = {{"Name", "HTTPS Certificate"},
9065968caeeSMarri Devender Rao                                     {"Description", "HTTPS Certificate"}};
9075968caeeSMarri Devender Rao 
90858eb238fSKowalski, Kamil         std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
90958eb238fSKowalski, Kamil 
91058eb238fSKowalski, Kamil         if (certFileBody.empty())
91158eb238fSKowalski, Kamil         {
912a08752f5SZbigniew Kurzynski             BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
913a08752f5SZbigniew Kurzynski             messages::unrecognizedRequestBody(asyncResp->res);
91458eb238fSKowalski, Kamil             return;
91558eb238fSKowalski, Kamil         }
91658eb238fSKowalski, Kamil 
9175968caeeSMarri Devender Rao         std::shared_ptr<CertificateFile> certFile =
91858eb238fSKowalski, Kamil             std::make_shared<CertificateFile>(certFileBody);
9195968caeeSMarri Devender Rao 
9205968caeeSMarri Devender Rao         crow::connections::systemBus->async_method_call(
921656ec7e3SZbigniew Kurzynski             [asyncResp, certFile](const boost::system::error_code ec,
922656ec7e3SZbigniew Kurzynski                                   const std::string& objectPath) {
9235968caeeSMarri Devender Rao                 if (ec)
9245968caeeSMarri Devender Rao                 {
9255968caeeSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
9265968caeeSMarri Devender Rao                     messages::internalError(asyncResp->res);
9275968caeeSMarri Devender Rao                     return;
9285968caeeSMarri Devender Rao                 }
929656ec7e3SZbigniew Kurzynski                 long certId = getIDFromURL(objectPath);
930656ec7e3SZbigniew Kurzynski                 if (certId < 0)
931656ec7e3SZbigniew Kurzynski                 {
932656ec7e3SZbigniew Kurzynski                     BMCWEB_LOG_ERROR << "Invalid objectPath value"
933656ec7e3SZbigniew Kurzynski                                      << objectPath;
934656ec7e3SZbigniew Kurzynski                     messages::internalError(asyncResp->res);
935656ec7e3SZbigniew Kurzynski                     return;
936656ec7e3SZbigniew Kurzynski                 }
9375968caeeSMarri Devender Rao                 std::string certURL =
9385968caeeSMarri Devender Rao                     "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/"
9395968caeeSMarri Devender Rao                     "Certificates/" +
9405968caeeSMarri Devender Rao                     std::to_string(certId);
94137cce918SMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath,
94237cce918SMarri Devender Rao                                          certs::httpsServiceName, certId,
9435968caeeSMarri Devender Rao                                          certURL, "HTTPS Certificate");
9445968caeeSMarri Devender Rao                 BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
9455968caeeSMarri Devender Rao                                  << certFile->getCertFilePath();
9465968caeeSMarri Devender Rao             },
94737cce918SMarri Devender Rao             certs::httpsServiceName, certs::httpsObjectPath,
94837cce918SMarri Devender Rao             certs::certInstallIntf, "Install", certFile->getCertFilePath());
9495968caeeSMarri Devender Rao     }
9505968caeeSMarri Devender Rao }; // HTTPSCertificateCollection
9515968caeeSMarri Devender Rao 
9525968caeeSMarri Devender Rao /**
9535968caeeSMarri Devender Rao  * The certificate location schema defines a resource that an administrator
9545968caeeSMarri Devender Rao  * can use in order to locate all certificates installed on a given service.
9555968caeeSMarri Devender Rao  */
9565968caeeSMarri Devender Rao class CertificateLocations : public Node
9575968caeeSMarri Devender Rao {
9585968caeeSMarri Devender Rao   public:
95952cc112dSEd Tanous     CertificateLocations(App& app) :
9605968caeeSMarri Devender Rao         Node(app, "/redfish/v1/CertificateService/CertificateLocations/")
9615968caeeSMarri Devender Rao     {
9625968caeeSMarri Devender Rao         entityPrivileges = {
9635968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
9645968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
9655968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
9665968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
9675968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
9685968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
9695968caeeSMarri Devender Rao     }
9705968caeeSMarri Devender Rao 
9715968caeeSMarri Devender Rao   private:
972*8d1b46d7Szhanghch05     void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
973*8d1b46d7Szhanghch05                const crow::Request&, const std::vector<std::string>&) override
9745968caeeSMarri Devender Rao     {
975*8d1b46d7Szhanghch05         asyncResp->res.jsonValue = {
9765968caeeSMarri Devender Rao             {"@odata.id",
9775968caeeSMarri Devender Rao              "/redfish/v1/CertificateService/CertificateLocations"},
9785968caeeSMarri Devender Rao             {"@odata.type",
9795968caeeSMarri Devender Rao              "#CertificateLocations.v1_0_0.CertificateLocations"},
9805968caeeSMarri Devender Rao             {"Name", "Certificate Locations"},
9815968caeeSMarri Devender Rao             {"Id", "CertificateLocations"},
9825968caeeSMarri Devender Rao             {"Description",
9835968caeeSMarri Devender Rao              "Defines a resource that an administrator can use in order to "
9845968caeeSMarri Devender Rao              "locate all certificates installed on a given service"}};
985*8d1b46d7Szhanghch05 
9865968caeeSMarri Devender Rao         nlohmann::json& links =
9875968caeeSMarri Devender Rao             asyncResp->res.jsonValue["Links"]["Certificates"];
9885968caeeSMarri Devender Rao         links = nlohmann::json::array();
9895968caeeSMarri Devender Rao         getCertificateLocations(
9905968caeeSMarri Devender Rao             asyncResp,
9915968caeeSMarri Devender Rao             "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/",
99237cce918SMarri Devender Rao             certs::httpsObjectPath, certs::httpsServiceName);
99337cce918SMarri Devender Rao         getCertificateLocations(asyncResp,
99437cce918SMarri Devender Rao                                 "/redfish/v1/AccountService/LDAP/Certificates/",
99537cce918SMarri Devender Rao                                 certs::ldapObjectPath, certs::ldapServiceName);
996cfcd5f6bSMarri Devender Rao         getCertificateLocations(
997cfcd5f6bSMarri Devender Rao             asyncResp, "/redfish/v1/Managers/bmc/Truststore/Certificates/",
998cfcd5f6bSMarri Devender Rao             certs::authorityObjectPath, certs::authorityServiceName);
99937cce918SMarri Devender Rao     }
100037cce918SMarri Devender Rao     /**
100137cce918SMarri Devender Rao      * @brief Retrieve the certificates installed list and append to the
100237cce918SMarri Devender Rao      * response
100337cce918SMarri Devender Rao      *
100437cce918SMarri Devender Rao      * @param[in] asyncResp Shared pointer to the response message
100537cce918SMarri Devender Rao      * @param[in] certURL  Path of the certificate object
100637cce918SMarri Devender Rao      * @param[in] path  Path of the D-Bus service object
100737cce918SMarri Devender Rao      * @return None
100837cce918SMarri Devender Rao      */
1009*8d1b46d7Szhanghch05     void getCertificateLocations(
1010*8d1b46d7Szhanghch05         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1011*8d1b46d7Szhanghch05         const std::string& certURL, const std::string& path,
101237cce918SMarri Devender Rao         const std::string& service)
101337cce918SMarri Devender Rao     {
101437cce918SMarri Devender Rao         BMCWEB_LOG_DEBUG << "getCertificateLocations URI=" << certURL
101537cce918SMarri Devender Rao                          << " Path=" << path << " service= " << service;
101637cce918SMarri Devender Rao         crow::connections::systemBus->async_method_call(
101737cce918SMarri Devender Rao             [asyncResp, certURL](const boost::system::error_code ec,
101837cce918SMarri Devender Rao                                  const ManagedObjectType& certs) {
101937cce918SMarri Devender Rao                 if (ec)
102037cce918SMarri Devender Rao                 {
10219c8e039eSJonathan Doman                     BMCWEB_LOG_WARNING
10229c8e039eSJonathan Doman                         << "Certificate collection query failed: " << ec
10239c8e039eSJonathan Doman                         << ", skipping " << certURL;
102437cce918SMarri Devender Rao                     return;
102537cce918SMarri Devender Rao                 }
102637cce918SMarri Devender Rao                 nlohmann::json& links =
102737cce918SMarri Devender Rao                     asyncResp->res.jsonValue["Links"]["Certificates"];
102837cce918SMarri Devender Rao                 for (auto& cert : certs)
102937cce918SMarri Devender Rao                 {
103037cce918SMarri Devender Rao                     long id = getIDFromURL(cert.first.str);
103137cce918SMarri Devender Rao                     if (id >= 0)
103237cce918SMarri Devender Rao                     {
103337cce918SMarri Devender Rao                         links.push_back(
103437cce918SMarri Devender Rao                             {{"@odata.id", certURL + std::to_string(id)}});
103537cce918SMarri Devender Rao                     }
103637cce918SMarri Devender Rao                 }
103737cce918SMarri Devender Rao                 asyncResp->res.jsonValue["Links"]["Certificates@odata.count"] =
103837cce918SMarri Devender Rao                     links.size();
103937cce918SMarri Devender Rao             },
104037cce918SMarri Devender Rao             service, path, certs::dbusObjManagerIntf, "GetManagedObjects");
10415968caeeSMarri Devender Rao     }
10425968caeeSMarri Devender Rao }; // CertificateLocations
104337cce918SMarri Devender Rao 
104437cce918SMarri Devender Rao /**
104537cce918SMarri Devender Rao  * Collection of LDAP certificates
104637cce918SMarri Devender Rao  */
104737cce918SMarri Devender Rao class LDAPCertificateCollection : public Node
104837cce918SMarri Devender Rao {
104937cce918SMarri Devender Rao   public:
105052cc112dSEd Tanous     LDAPCertificateCollection(App& app) :
105137cce918SMarri Devender Rao         Node(app, "/redfish/v1/AccountService/LDAP/Certificates/")
105237cce918SMarri Devender Rao     {
105337cce918SMarri Devender Rao         entityPrivileges = {
105437cce918SMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
105537cce918SMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
105637cce918SMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
105737cce918SMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
105837cce918SMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
105937cce918SMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
106037cce918SMarri Devender Rao     }
1061*8d1b46d7Szhanghch05     void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1062*8d1b46d7Szhanghch05                const crow::Request&, const std::vector<std::string>&) override
106337cce918SMarri Devender Rao     {
1064*8d1b46d7Szhanghch05         asyncResp->res.jsonValue = {
106537cce918SMarri Devender Rao             {"@odata.id", "/redfish/v1/AccountService/LDAP/Certificates"},
106637cce918SMarri Devender Rao             {"@odata.type", "#CertificateCollection.CertificateCollection"},
106737cce918SMarri Devender Rao             {"Name", "LDAP Certificates Collection"},
106837cce918SMarri Devender Rao             {"Description", "A Collection of LDAP certificate instances"}};
1069*8d1b46d7Szhanghch05 
107037cce918SMarri Devender Rao         crow::connections::systemBus->async_method_call(
107137cce918SMarri Devender Rao             [asyncResp](const boost::system::error_code ec,
107237cce918SMarri Devender Rao                         const ManagedObjectType& certs) {
10739c8e039eSJonathan Doman                 nlohmann::json& members = asyncResp->res.jsonValue["Members"];
10749c8e039eSJonathan Doman                 nlohmann::json& count =
10759c8e039eSJonathan Doman                     asyncResp->res.jsonValue["Members@odata.count"];
10769c8e039eSJonathan Doman                 members = nlohmann::json::array();
10779c8e039eSJonathan Doman                 count = 0;
107837cce918SMarri Devender Rao                 if (ec)
107937cce918SMarri Devender Rao                 {
10809c8e039eSJonathan Doman                     BMCWEB_LOG_WARNING << "LDAP certificate query failed: "
10819c8e039eSJonathan Doman                                        << ec;
108237cce918SMarri Devender Rao                     return;
108337cce918SMarri Devender Rao                 }
108437cce918SMarri Devender Rao                 for (const auto& cert : certs)
108537cce918SMarri Devender Rao                 {
108637cce918SMarri Devender Rao                     long id = getIDFromURL(cert.first.str);
108737cce918SMarri Devender Rao                     if (id >= 0)
108837cce918SMarri Devender Rao                     {
108937cce918SMarri Devender Rao                         members.push_back(
109037cce918SMarri Devender Rao                             {{"@odata.id", "/redfish/v1/AccountService/"
109137cce918SMarri Devender Rao                                            "LDAP/Certificates/" +
109237cce918SMarri Devender Rao                                                std::to_string(id)}});
109337cce918SMarri Devender Rao                     }
109437cce918SMarri Devender Rao                 }
10959c8e039eSJonathan Doman                 count = members.size();
109637cce918SMarri Devender Rao             },
109737cce918SMarri Devender Rao             certs::ldapServiceName, certs::ldapObjectPath,
109837cce918SMarri Devender Rao             certs::dbusObjManagerIntf, "GetManagedObjects");
109937cce918SMarri Devender Rao     }
110037cce918SMarri Devender Rao 
1101*8d1b46d7Szhanghch05     void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1102*8d1b46d7Szhanghch05                 const crow::Request& req,
1103cb13a392SEd Tanous                 const std::vector<std::string>&) override
110437cce918SMarri Devender Rao     {
1105*8d1b46d7Szhanghch05 
110658eb238fSKowalski, Kamil         std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
110758eb238fSKowalski, Kamil 
110858eb238fSKowalski, Kamil         if (certFileBody.empty())
110958eb238fSKowalski, Kamil         {
1110a08752f5SZbigniew Kurzynski             BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
1111a08752f5SZbigniew Kurzynski             messages::unrecognizedRequestBody(asyncResp->res);
111258eb238fSKowalski, Kamil             return;
111358eb238fSKowalski, Kamil         }
111458eb238fSKowalski, Kamil 
111558eb238fSKowalski, Kamil         std::shared_ptr<CertificateFile> certFile =
111658eb238fSKowalski, Kamil             std::make_shared<CertificateFile>(certFileBody);
111758eb238fSKowalski, Kamil 
111837cce918SMarri Devender Rao         crow::connections::systemBus->async_method_call(
1119656ec7e3SZbigniew Kurzynski             [asyncResp, certFile](const boost::system::error_code ec,
1120656ec7e3SZbigniew Kurzynski                                   const std::string& objectPath) {
112137cce918SMarri Devender Rao                 if (ec)
112237cce918SMarri Devender Rao                 {
112337cce918SMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
112437cce918SMarri Devender Rao                     messages::internalError(asyncResp->res);
112537cce918SMarri Devender Rao                     return;
112637cce918SMarri Devender Rao                 }
1127656ec7e3SZbigniew Kurzynski                 long certId = getIDFromURL(objectPath);
1128656ec7e3SZbigniew Kurzynski                 if (certId < 0)
1129656ec7e3SZbigniew Kurzynski                 {
1130656ec7e3SZbigniew Kurzynski                     BMCWEB_LOG_ERROR << "Invalid objectPath value"
1131656ec7e3SZbigniew Kurzynski                                      << objectPath;
1132656ec7e3SZbigniew Kurzynski                     messages::internalError(asyncResp->res);
1133656ec7e3SZbigniew Kurzynski                     return;
1134656ec7e3SZbigniew Kurzynski                 }
113537cce918SMarri Devender Rao                 std::string certURL =
113637cce918SMarri Devender Rao                     "/redfish/v1/AccountService/LDAP/Certificates/" +
113737cce918SMarri Devender Rao                     std::to_string(certId);
113837cce918SMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath,
113937cce918SMarri Devender Rao                                          certs::ldapServiceName, certId,
114037cce918SMarri Devender Rao                                          certURL, "LDAP Certificate");
114137cce918SMarri Devender Rao                 BMCWEB_LOG_DEBUG << "LDAP certificate install file="
114237cce918SMarri Devender Rao                                  << certFile->getCertFilePath();
114337cce918SMarri Devender Rao             },
114437cce918SMarri Devender Rao             certs::ldapServiceName, certs::ldapObjectPath,
114537cce918SMarri Devender Rao             certs::certInstallIntf, "Install", certFile->getCertFilePath());
114637cce918SMarri Devender Rao     }
114737cce918SMarri Devender Rao }; // LDAPCertificateCollection
114837cce918SMarri Devender Rao 
114937cce918SMarri Devender Rao /**
115037cce918SMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
115137cce918SMarri Devender Rao  * of a component, account or service.
115237cce918SMarri Devender Rao  */
115337cce918SMarri Devender Rao class LDAPCertificate : public Node
115437cce918SMarri Devender Rao {
115537cce918SMarri Devender Rao   public:
115652cc112dSEd Tanous     LDAPCertificate(App& app) :
115737cce918SMarri Devender Rao         Node(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/",
115837cce918SMarri Devender Rao              std::string())
115937cce918SMarri Devender Rao     {
116037cce918SMarri Devender Rao         entityPrivileges = {
116137cce918SMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
116237cce918SMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
116337cce918SMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
116437cce918SMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
116537cce918SMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
116637cce918SMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
116737cce918SMarri Devender Rao     }
116837cce918SMarri Devender Rao 
1169*8d1b46d7Szhanghch05     void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1170*8d1b46d7Szhanghch05                const crow::Request& req,
1171cb13a392SEd Tanous                const std::vector<std::string>&) override
117237cce918SMarri Devender Rao     {
1173*8d1b46d7Szhanghch05 
117437cce918SMarri Devender Rao         long id = getIDFromURL(req.url);
117537cce918SMarri Devender Rao         if (id < 0)
117637cce918SMarri Devender Rao         {
117737cce918SMarri Devender Rao             BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
117837cce918SMarri Devender Rao             messages::internalError(asyncResp->res);
117937cce918SMarri Devender Rao             return;
118037cce918SMarri Devender Rao         }
118137cce918SMarri Devender Rao         BMCWEB_LOG_DEBUG << "LDAP Certificate ID=" << std::to_string(id);
118237cce918SMarri Devender Rao         std::string certURL = "/redfish/v1/AccountService/LDAP/Certificates/" +
118337cce918SMarri Devender Rao                               std::to_string(id);
118437cce918SMarri Devender Rao         std::string objectPath = certs::ldapObjectPath;
118537cce918SMarri Devender Rao         objectPath += "/";
118637cce918SMarri Devender Rao         objectPath += std::to_string(id);
118737cce918SMarri Devender Rao         getCertificateProperties(asyncResp, objectPath, certs::ldapServiceName,
118837cce918SMarri Devender Rao                                  id, certURL, "LDAP Certificate");
118937cce918SMarri Devender Rao     }
119037cce918SMarri Devender Rao }; // LDAPCertificate
1191cfcd5f6bSMarri Devender Rao /**
1192cfcd5f6bSMarri Devender Rao  * Collection of TrustStoreCertificate certificates
1193cfcd5f6bSMarri Devender Rao  */
1194cfcd5f6bSMarri Devender Rao class TrustStoreCertificateCollection : public Node
1195cfcd5f6bSMarri Devender Rao {
1196cfcd5f6bSMarri Devender Rao   public:
119752cc112dSEd Tanous     TrustStoreCertificateCollection(App& app) :
1198cfcd5f6bSMarri Devender Rao         Node(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
1199cfcd5f6bSMarri Devender Rao     {
1200cfcd5f6bSMarri Devender Rao         entityPrivileges = {
1201cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
1202cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
1203cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1204cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1205cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1206cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1207cfcd5f6bSMarri Devender Rao     }
1208*8d1b46d7Szhanghch05     void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1209*8d1b46d7Szhanghch05                const crow::Request&, const std::vector<std::string>&) override
1210cfcd5f6bSMarri Devender Rao     {
1211*8d1b46d7Szhanghch05         asyncResp->res.jsonValue = {
1212cfcd5f6bSMarri Devender Rao             {"@odata.id", "/redfish/v1/Managers/bmc/Truststore/Certificates/"},
1213cfcd5f6bSMarri Devender Rao             {"@odata.type", "#CertificateCollection.CertificateCollection"},
1214cfcd5f6bSMarri Devender Rao             {"Name", "TrustStore Certificates Collection"},
1215cfcd5f6bSMarri Devender Rao             {"Description",
1216cfcd5f6bSMarri Devender Rao              "A Collection of TrustStore certificate instances"}};
1217*8d1b46d7Szhanghch05 
1218cfcd5f6bSMarri Devender Rao         crow::connections::systemBus->async_method_call(
1219cfcd5f6bSMarri Devender Rao             [asyncResp](const boost::system::error_code ec,
1220cfcd5f6bSMarri Devender Rao                         const ManagedObjectType& certs) {
1221cfcd5f6bSMarri Devender Rao                 if (ec)
1222cfcd5f6bSMarri Devender Rao                 {
1223cfcd5f6bSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
1224cfcd5f6bSMarri Devender Rao                     messages::internalError(asyncResp->res);
1225cfcd5f6bSMarri Devender Rao                     return;
1226cfcd5f6bSMarri Devender Rao                 }
1227cfcd5f6bSMarri Devender Rao                 nlohmann::json& members = asyncResp->res.jsonValue["Members"];
1228cfcd5f6bSMarri Devender Rao                 members = nlohmann::json::array();
1229cfcd5f6bSMarri Devender Rao                 for (const auto& cert : certs)
1230cfcd5f6bSMarri Devender Rao                 {
1231cfcd5f6bSMarri Devender Rao                     long id = getIDFromURL(cert.first.str);
1232cfcd5f6bSMarri Devender Rao                     if (id >= 0)
1233cfcd5f6bSMarri Devender Rao                     {
1234cfcd5f6bSMarri Devender Rao                         members.push_back(
1235cfcd5f6bSMarri Devender Rao                             {{"@odata.id", "/redfish/v1/Managers/bmc/"
1236cfcd5f6bSMarri Devender Rao                                            "Truststore/Certificates/" +
1237cfcd5f6bSMarri Devender Rao                                                std::to_string(id)}});
1238cfcd5f6bSMarri Devender Rao                     }
1239cfcd5f6bSMarri Devender Rao                 }
1240cfcd5f6bSMarri Devender Rao                 asyncResp->res.jsonValue["Members@odata.count"] =
1241cfcd5f6bSMarri Devender Rao                     members.size();
1242cfcd5f6bSMarri Devender Rao             },
1243cfcd5f6bSMarri Devender Rao             certs::authorityServiceName, certs::authorityObjectPath,
1244cfcd5f6bSMarri Devender Rao             certs::dbusObjManagerIntf, "GetManagedObjects");
1245cfcd5f6bSMarri Devender Rao     }
1246cfcd5f6bSMarri Devender Rao 
1247*8d1b46d7Szhanghch05     void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1248*8d1b46d7Szhanghch05                 const crow::Request& req,
1249cb13a392SEd Tanous                 const std::vector<std::string>&) override
1250cfcd5f6bSMarri Devender Rao     {
1251*8d1b46d7Szhanghch05 
1252a08752f5SZbigniew Kurzynski         std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
1253a08752f5SZbigniew Kurzynski 
1254a08752f5SZbigniew Kurzynski         if (certFileBody.empty())
1255a08752f5SZbigniew Kurzynski         {
1256a08752f5SZbigniew Kurzynski             BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
1257a08752f5SZbigniew Kurzynski             messages::unrecognizedRequestBody(asyncResp->res);
1258a08752f5SZbigniew Kurzynski             return;
1259a08752f5SZbigniew Kurzynski         }
1260a08752f5SZbigniew Kurzynski 
1261a08752f5SZbigniew Kurzynski         std::shared_ptr<CertificateFile> certFile =
1262a08752f5SZbigniew Kurzynski             std::make_shared<CertificateFile>(certFileBody);
1263cfcd5f6bSMarri Devender Rao         crow::connections::systemBus->async_method_call(
1264656ec7e3SZbigniew Kurzynski             [asyncResp, certFile](const boost::system::error_code ec,
1265656ec7e3SZbigniew Kurzynski                                   const std::string& objectPath) {
1266cfcd5f6bSMarri Devender Rao                 if (ec)
1267cfcd5f6bSMarri Devender Rao                 {
1268cfcd5f6bSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
1269cfcd5f6bSMarri Devender Rao                     messages::internalError(asyncResp->res);
1270cfcd5f6bSMarri Devender Rao                     return;
1271cfcd5f6bSMarri Devender Rao                 }
1272656ec7e3SZbigniew Kurzynski                 long certId = getIDFromURL(objectPath);
1273656ec7e3SZbigniew Kurzynski                 if (certId < 0)
1274656ec7e3SZbigniew Kurzynski                 {
1275656ec7e3SZbigniew Kurzynski                     BMCWEB_LOG_ERROR << "Invalid objectPath value"
1276656ec7e3SZbigniew Kurzynski                                      << objectPath;
1277656ec7e3SZbigniew Kurzynski                     messages::internalError(asyncResp->res);
1278656ec7e3SZbigniew Kurzynski                     return;
1279656ec7e3SZbigniew Kurzynski                 }
1280cfcd5f6bSMarri Devender Rao                 std::string certURL = "/redfish/v1/Managers/bmc/"
1281cfcd5f6bSMarri Devender Rao                                       "Truststore/Certificates/" +
1282cfcd5f6bSMarri Devender Rao                                       std::to_string(certId);
1283656ec7e3SZbigniew Kurzynski 
1284cfcd5f6bSMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath,
1285cfcd5f6bSMarri Devender Rao                                          certs::authorityServiceName, certId,
1286cfcd5f6bSMarri Devender Rao                                          certURL, "TrustStore Certificate");
1287cfcd5f6bSMarri Devender Rao                 BMCWEB_LOG_DEBUG << "TrustStore certificate install file="
1288cfcd5f6bSMarri Devender Rao                                  << certFile->getCertFilePath();
1289cfcd5f6bSMarri Devender Rao             },
1290cfcd5f6bSMarri Devender Rao             certs::authorityServiceName, certs::authorityObjectPath,
1291cfcd5f6bSMarri Devender Rao             certs::certInstallIntf, "Install", certFile->getCertFilePath());
1292cfcd5f6bSMarri Devender Rao     }
1293cfcd5f6bSMarri Devender Rao }; // TrustStoreCertificateCollection
1294cfcd5f6bSMarri Devender Rao 
1295cfcd5f6bSMarri Devender Rao /**
1296cfcd5f6bSMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
1297cfcd5f6bSMarri Devender Rao  * of a component, account or service.
1298cfcd5f6bSMarri Devender Rao  */
1299cfcd5f6bSMarri Devender Rao class TrustStoreCertificate : public Node
1300cfcd5f6bSMarri Devender Rao {
1301cfcd5f6bSMarri Devender Rao   public:
130252cc112dSEd Tanous     TrustStoreCertificate(App& app) :
1303cfcd5f6bSMarri Devender Rao         Node(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/",
1304cfcd5f6bSMarri Devender Rao              std::string())
1305cfcd5f6bSMarri Devender Rao     {
1306cfcd5f6bSMarri Devender Rao         entityPrivileges = {
1307cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
1308cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
1309cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1310cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1311cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1312cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1313cfcd5f6bSMarri Devender Rao     }
1314cfcd5f6bSMarri Devender Rao 
1315*8d1b46d7Szhanghch05     void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1316*8d1b46d7Szhanghch05                const crow::Request& req,
1317cb13a392SEd Tanous                const std::vector<std::string>&) override
1318cfcd5f6bSMarri Devender Rao     {
1319*8d1b46d7Szhanghch05 
1320cfcd5f6bSMarri Devender Rao         long id = getIDFromURL(req.url);
1321cfcd5f6bSMarri Devender Rao         if (id < 0)
1322cfcd5f6bSMarri Devender Rao         {
1323cfcd5f6bSMarri Devender Rao             BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
1324cfcd5f6bSMarri Devender Rao             messages::internalError(asyncResp->res);
1325cfcd5f6bSMarri Devender Rao             return;
1326cfcd5f6bSMarri Devender Rao         }
1327cfcd5f6bSMarri Devender Rao         BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doGet ID="
1328cfcd5f6bSMarri Devender Rao                          << std::to_string(id);
1329cfcd5f6bSMarri Devender Rao         std::string certURL =
1330cfcd5f6bSMarri Devender Rao             "/redfish/v1/Managers/bmc/Truststore/Certificates/" +
1331cfcd5f6bSMarri Devender Rao             std::to_string(id);
1332cfcd5f6bSMarri Devender Rao         std::string objectPath = certs::authorityObjectPath;
1333cfcd5f6bSMarri Devender Rao         objectPath += "/";
1334cfcd5f6bSMarri Devender Rao         objectPath += std::to_string(id);
1335cfcd5f6bSMarri Devender Rao         getCertificateProperties(asyncResp, objectPath,
1336cfcd5f6bSMarri Devender Rao                                  certs::authorityServiceName, id, certURL,
1337cfcd5f6bSMarri Devender Rao                                  "TrustStore Certificate");
1338cfcd5f6bSMarri Devender Rao     }
133907a60299SZbigniew Kurzynski 
1340*8d1b46d7Szhanghch05     void doDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1341*8d1b46d7Szhanghch05                   const crow::Request& req,
134207a60299SZbigniew Kurzynski                   const std::vector<std::string>& params) override
134307a60299SZbigniew Kurzynski     {
134407a60299SZbigniew Kurzynski 
134507a60299SZbigniew Kurzynski         if (params.size() != 1)
134607a60299SZbigniew Kurzynski         {
134707a60299SZbigniew Kurzynski             messages::internalError(asyncResp->res);
134807a60299SZbigniew Kurzynski             return;
134907a60299SZbigniew Kurzynski         }
135007a60299SZbigniew Kurzynski 
135107a60299SZbigniew Kurzynski         long id = getIDFromURL(req.url);
135207a60299SZbigniew Kurzynski         if (id < 0)
135307a60299SZbigniew Kurzynski         {
135407a60299SZbigniew Kurzynski             BMCWEB_LOG_ERROR << "Invalid url value: " << req.url;
135507a60299SZbigniew Kurzynski             messages::resourceNotFound(asyncResp->res, "TrustStore Certificate",
135607a60299SZbigniew Kurzynski                                        std::string(req.url));
135707a60299SZbigniew Kurzynski             return;
135807a60299SZbigniew Kurzynski         }
135907a60299SZbigniew Kurzynski         BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doDelete ID="
136007a60299SZbigniew Kurzynski                          << std::to_string(id);
136107a60299SZbigniew Kurzynski         std::string certPath = certs::authorityObjectPath;
136207a60299SZbigniew Kurzynski         certPath += "/";
136307a60299SZbigniew Kurzynski         certPath += std::to_string(id);
136407a60299SZbigniew Kurzynski 
136507a60299SZbigniew Kurzynski         crow::connections::systemBus->async_method_call(
136607a60299SZbigniew Kurzynski             [asyncResp, id](const boost::system::error_code ec) {
136707a60299SZbigniew Kurzynski                 if (ec)
136807a60299SZbigniew Kurzynski                 {
136907a60299SZbigniew Kurzynski                     messages::resourceNotFound(asyncResp->res,
137007a60299SZbigniew Kurzynski                                                "TrustStore Certificate",
137107a60299SZbigniew Kurzynski                                                std::to_string(id));
137207a60299SZbigniew Kurzynski                     return;
137307a60299SZbigniew Kurzynski                 }
137407a60299SZbigniew Kurzynski                 BMCWEB_LOG_INFO << "Certificate deleted";
137507a60299SZbigniew Kurzynski                 asyncResp->res.result(boost::beast::http::status::no_content);
137607a60299SZbigniew Kurzynski             },
137707a60299SZbigniew Kurzynski             certs::authorityServiceName, certPath, certs::objDeleteIntf,
137807a60299SZbigniew Kurzynski             "Delete");
137907a60299SZbigniew Kurzynski     }
1380cfcd5f6bSMarri Devender Rao }; // TrustStoreCertificate
13815968caeeSMarri Devender Rao } // namespace redfish
1382