xref: /openbmc/bmcweb/features/redfish/lib/certificate_service.hpp (revision 1476687deb1697d865b20458a0097c9ab5fd44e2)
15968caeeSMarri Devender Rao #pragma once
25968caeeSMarri Devender Rao 
37e860f15SJohn Edward Broadbent #include <app.hpp>
4e6604b11SIwona Klimaszewska #include <boost/convert.hpp>
5e6604b11SIwona Klimaszewska #include <boost/convert/strtol.hpp>
690d2d1e8SJiaqing Zhao #include <boost/system/linux_error.hpp>
7168e20c1SEd Tanous #include <dbus_utility.hpp>
845ca1b86SEd Tanous #include <query.hpp>
9ed398213SEd Tanous #include <registries/privilege_registry.hpp>
101214b7e7SGunnar Mills 
115968caeeSMarri Devender Rao namespace redfish
125968caeeSMarri Devender Rao {
135968caeeSMarri Devender Rao namespace certs
145968caeeSMarri Devender Rao {
155968caeeSMarri Devender Rao constexpr char const* httpsObjectPath =
165968caeeSMarri Devender Rao     "/xyz/openbmc_project/certs/server/https";
175968caeeSMarri Devender Rao constexpr char const* certInstallIntf = "xyz.openbmc_project.Certs.Install";
185968caeeSMarri Devender Rao constexpr char const* certReplaceIntf = "xyz.openbmc_project.Certs.Replace";
1907a60299SZbigniew Kurzynski constexpr char const* objDeleteIntf = "xyz.openbmc_project.Object.Delete";
205968caeeSMarri Devender Rao constexpr char const* certPropIntf = "xyz.openbmc_project.Certs.Certificate";
215968caeeSMarri Devender Rao constexpr char const* dbusPropIntf = "org.freedesktop.DBus.Properties";
225968caeeSMarri Devender Rao constexpr char const* dbusObjManagerIntf = "org.freedesktop.DBus.ObjectManager";
2337cce918SMarri Devender Rao constexpr char const* ldapObjectPath = "/xyz/openbmc_project/certs/client/ldap";
2437cce918SMarri Devender Rao constexpr char const* httpsServiceName =
2537cce918SMarri Devender Rao     "xyz.openbmc_project.Certs.Manager.Server.Https";
2637cce918SMarri Devender Rao constexpr char const* ldapServiceName =
2737cce918SMarri Devender Rao     "xyz.openbmc_project.Certs.Manager.Client.Ldap";
28cfcd5f6bSMarri Devender Rao constexpr char const* authorityServiceName =
29cfcd5f6bSMarri Devender Rao     "xyz.openbmc_project.Certs.Manager.Authority.Ldap";
30cfcd5f6bSMarri Devender Rao constexpr char const* authorityObjectPath =
31cfcd5f6bSMarri Devender Rao     "/xyz/openbmc_project/certs/authority/ldap";
325968caeeSMarri Devender Rao } // namespace certs
335968caeeSMarri Devender Rao 
345968caeeSMarri Devender Rao /**
355968caeeSMarri Devender Rao  * The Certificate schema defines a Certificate Service which represents the
365968caeeSMarri Devender Rao  * actions available to manage certificates and links to where certificates
375968caeeSMarri Devender Rao  * are installed.
385968caeeSMarri Devender Rao  */
397e860f15SJohn Edward Broadbent 
405968caeeSMarri Devender Rao // TODO: Issue#61 No entries are available for Certificate
414e0453b1SGunnar Mills // service at https://www.dmtf.org/standards/redfish
425968caeeSMarri Devender Rao // "redfish standard registries". Need to modify after DMTF
435968caeeSMarri Devender Rao // publish Privilege details for certificate service
445968caeeSMarri Devender Rao 
457e860f15SJohn Edward Broadbent inline void requestRoutesCertificateService(App& app)
465968caeeSMarri Devender Rao {
477e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/")
48ed398213SEd Tanous         .privileges(redfish::privileges::getCertificateService)
4945ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)([&app](const crow::Request& req,
5045ca1b86SEd Tanous                                                        const std::shared_ptr<
5145ca1b86SEd Tanous                                                            bmcweb::AsyncResp>&
5245ca1b86SEd Tanous                                                            asyncResp) {
5345ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
5445ca1b86SEd Tanous             {
5545ca1b86SEd Tanous                 return;
5645ca1b86SEd Tanous             }
57*1476687dSEd Tanous 
58*1476687dSEd Tanous             asyncResp->res.jsonValue["@odata.type"] =
59*1476687dSEd Tanous                 "#CertificateService.v1_0_0.CertificateService";
60*1476687dSEd Tanous             asyncResp->res.jsonValue["@odata.id"] =
61*1476687dSEd Tanous                 "/redfish/v1/CertificateService";
62*1476687dSEd Tanous             asyncResp->res.jsonValue["Id"] = "CertificateService";
63*1476687dSEd Tanous             asyncResp->res.jsonValue["Name"] = "Certificate Service";
64*1476687dSEd Tanous             asyncResp->res.jsonValue["Description"] =
65*1476687dSEd Tanous                 "Actions available to manage certificates";
6672048780SAbhishek Patel             // /redfish/v1/CertificateService/CertificateLocations is something
6772048780SAbhishek Patel             // only ConfigureManager can access then only display when the user
6872048780SAbhishek Patel             // has permissions ConfigureManager
6972048780SAbhishek Patel             Privileges effectiveUserPrivileges =
7072048780SAbhishek Patel                 redfish::getUserPrivileges(req.userRole);
7172048780SAbhishek Patel             if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
7272048780SAbhishek Patel                                                  effectiveUserPrivileges))
7372048780SAbhishek Patel             {
74*1476687dSEd Tanous                 asyncResp->res.jsonValue["CertificateLocations"]["@odata.id"] =
75*1476687dSEd Tanous                     "/redfish/v1/CertificateService/CertificateLocations";
7672048780SAbhishek Patel             }
770fda0f12SGeorge Liu             asyncResp->res
780fda0f12SGeorge Liu                 .jsonValue["Actions"]
790fda0f12SGeorge Liu                           ["#CertificateService.ReplaceCertificate"] = {
800fda0f12SGeorge Liu                 {"target",
810fda0f12SGeorge Liu                  "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate"},
825968caeeSMarri Devender Rao                 {"CertificateType@Redfish.AllowableValues", {"PEM"}}};
837e860f15SJohn Edward Broadbent             asyncResp->res
847e860f15SJohn Edward Broadbent                 .jsonValue["Actions"]["#CertificateService.GenerateCSR"] = {
850fda0f12SGeorge Liu                 {"target",
860fda0f12SGeorge Liu                  "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR"}};
877e860f15SJohn Edward Broadbent         });
887e860f15SJohn Edward Broadbent } // requestRoutesCertificateService
8937cce918SMarri Devender Rao 
905968caeeSMarri Devender Rao /**
915968caeeSMarri Devender Rao  * @brief Find the ID specified in the URL
925968caeeSMarri Devender Rao  * Finds the numbers specified after the last "/" in the URL and returns.
935968caeeSMarri Devender Rao  * @param[in] path URL
945968caeeSMarri Devender Rao  * @return -1 on failure and number on success
955968caeeSMarri Devender Rao  */
9623a21a1cSEd Tanous inline long getIDFromURL(const std::string_view url)
975968caeeSMarri Devender Rao {
98f23b7296SEd Tanous     std::size_t found = url.rfind('/');
995968caeeSMarri Devender Rao     if (found == std::string::npos)
1005968caeeSMarri Devender Rao     {
1015968caeeSMarri Devender Rao         return -1;
1025968caeeSMarri Devender Rao     }
103e6604b11SIwona Klimaszewska 
1045968caeeSMarri Devender Rao     if ((found + 1) < url.length())
1055968caeeSMarri Devender Rao     {
1065968caeeSMarri Devender Rao         std::string_view str = url.substr(found + 1);
107e6604b11SIwona Klimaszewska 
108e6604b11SIwona Klimaszewska         return boost::convert<long>(str, boost::cnv::strtol()).value_or(-1);
1095968caeeSMarri Devender Rao     }
110e6604b11SIwona Klimaszewska 
1115968caeeSMarri Devender Rao     return -1;
1125968caeeSMarri Devender Rao }
1135968caeeSMarri Devender Rao 
1148d1b46d7Szhanghch05 inline std::string getCertificateFromReqBody(
1158d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11658eb238fSKowalski, Kamil     const crow::Request& req)
11758eb238fSKowalski, Kamil {
11858eb238fSKowalski, Kamil     nlohmann::json reqJson = nlohmann::json::parse(req.body, nullptr, false);
11958eb238fSKowalski, Kamil 
12058eb238fSKowalski, Kamil     if (reqJson.is_discarded())
12158eb238fSKowalski, Kamil     {
12258eb238fSKowalski, Kamil         // We did not receive JSON request, proceed as it is RAW data
12358eb238fSKowalski, Kamil         return req.body;
12458eb238fSKowalski, Kamil     }
12558eb238fSKowalski, Kamil 
12658eb238fSKowalski, Kamil     std::string certificate;
12758eb238fSKowalski, Kamil     std::optional<std::string> certificateType = "PEM";
12858eb238fSKowalski, Kamil 
12915ed6780SWilly Tu     if (!json_util::readJsonPatch(req, asyncResp->res, "CertificateString",
13015ed6780SWilly Tu                                   certificate, "CertificateType",
13115ed6780SWilly Tu                                   certificateType))
13258eb238fSKowalski, Kamil     {
13358eb238fSKowalski, Kamil         BMCWEB_LOG_ERROR << "Required parameters are missing";
13458eb238fSKowalski, Kamil         messages::internalError(asyncResp->res);
135abb93cddSEd Tanous         return {};
13658eb238fSKowalski, Kamil     }
13758eb238fSKowalski, Kamil 
13858eb238fSKowalski, Kamil     if (*certificateType != "PEM")
13958eb238fSKowalski, Kamil     {
14058eb238fSKowalski, Kamil         messages::propertyValueNotInList(asyncResp->res, *certificateType,
14158eb238fSKowalski, Kamil                                          "CertificateType");
142abb93cddSEd Tanous         return {};
14358eb238fSKowalski, Kamil     }
14458eb238fSKowalski, Kamil 
14558eb238fSKowalski, Kamil     return certificate;
14658eb238fSKowalski, Kamil }
14758eb238fSKowalski, Kamil 
1485968caeeSMarri Devender Rao /**
1495968caeeSMarri Devender Rao  * Class to create a temporary certificate file for uploading to system
1505968caeeSMarri Devender Rao  */
1515968caeeSMarri Devender Rao class CertificateFile
1525968caeeSMarri Devender Rao {
1535968caeeSMarri Devender Rao   public:
1545968caeeSMarri Devender Rao     CertificateFile() = delete;
1555968caeeSMarri Devender Rao     CertificateFile(const CertificateFile&) = delete;
1565968caeeSMarri Devender Rao     CertificateFile& operator=(const CertificateFile&) = delete;
1575968caeeSMarri Devender Rao     CertificateFile(CertificateFile&&) = delete;
1585968caeeSMarri Devender Rao     CertificateFile& operator=(CertificateFile&&) = delete;
1595968caeeSMarri Devender Rao     CertificateFile(const std::string& certString)
1605968caeeSMarri Devender Rao     {
16172d52d25SEd Tanous         std::array<char, 18> dirTemplate = {'/', 't', 'm', 'p', '/', 'C',
1625207438cSEd Tanous                                             'e', 'r', 't', 's', '.', 'X',
1635207438cSEd Tanous                                             'X', 'X', 'X', 'X', 'X', '\0'};
1645207438cSEd Tanous         char* tempDirectory = mkdtemp(dirTemplate.data());
165e662eae8SEd Tanous         if (tempDirectory != nullptr)
1665968caeeSMarri Devender Rao         {
1675968caeeSMarri Devender Rao             certDirectory = tempDirectory;
1685968caeeSMarri Devender Rao             certificateFile = certDirectory / "cert.pem";
1695968caeeSMarri Devender Rao             std::ofstream out(certificateFile, std::ofstream::out |
1705968caeeSMarri Devender Rao                                                    std::ofstream::binary |
1715968caeeSMarri Devender Rao                                                    std::ofstream::trunc);
1725968caeeSMarri Devender Rao             out << certString;
1735968caeeSMarri Devender Rao             out.close();
1748cc8edecSEd Tanous             BMCWEB_LOG_DEBUG << "Creating certificate file"
1758cc8edecSEd Tanous                              << certificateFile.string();
1765968caeeSMarri Devender Rao         }
1775968caeeSMarri Devender Rao     }
1785968caeeSMarri Devender Rao     ~CertificateFile()
1795968caeeSMarri Devender Rao     {
1805968caeeSMarri Devender Rao         if (std::filesystem::exists(certDirectory))
1815968caeeSMarri Devender Rao         {
1828cc8edecSEd Tanous             BMCWEB_LOG_DEBUG << "Removing certificate file"
1838cc8edecSEd Tanous                              << certificateFile.string();
18423a21a1cSEd Tanous             std::error_code ec;
18523a21a1cSEd Tanous             std::filesystem::remove_all(certDirectory, ec);
18623a21a1cSEd Tanous             if (ec)
1875968caeeSMarri Devender Rao             {
1885968caeeSMarri Devender Rao                 BMCWEB_LOG_ERROR << "Failed to remove temp directory"
1898cc8edecSEd Tanous                                  << certDirectory.string();
1905968caeeSMarri Devender Rao             }
1915968caeeSMarri Devender Rao         }
1925968caeeSMarri Devender Rao     }
1935968caeeSMarri Devender Rao     std::string getCertFilePath()
1945968caeeSMarri Devender Rao     {
1955968caeeSMarri Devender Rao         return certificateFile;
1965968caeeSMarri Devender Rao     }
1975968caeeSMarri Devender Rao 
1985968caeeSMarri Devender Rao   private:
1995968caeeSMarri Devender Rao     std::filesystem::path certificateFile;
2005968caeeSMarri Devender Rao     std::filesystem::path certDirectory;
2015968caeeSMarri Devender Rao };
2025968caeeSMarri Devender Rao 
20330215816SMarri Devender Rao static std::unique_ptr<sdbusplus::bus::match::match> csrMatcher;
20430215816SMarri Devender Rao /**
20530215816SMarri Devender Rao  * @brief Read data from CSR D-bus object and set to response
20630215816SMarri Devender Rao  *
20730215816SMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
20830215816SMarri Devender Rao  * @param[in] certURI Link to certifiate collection URI
20930215816SMarri Devender Rao  * @param[in] service D-Bus service name
21030215816SMarri Devender Rao  * @param[in] certObjPath certificate D-Bus object path
21130215816SMarri Devender Rao  * @param[in] csrObjPath CSR D-Bus object path
21230215816SMarri Devender Rao  * @return None
21330215816SMarri Devender Rao  */
2148d1b46d7Szhanghch05 static void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
21530215816SMarri Devender Rao                    const std::string& certURI, const std::string& service,
21630215816SMarri Devender Rao                    const std::string& certObjPath,
21730215816SMarri Devender Rao                    const std::string& csrObjPath)
21830215816SMarri Devender Rao {
21930215816SMarri Devender Rao     BMCWEB_LOG_DEBUG << "getCSR CertObjectPath" << certObjPath
22030215816SMarri Devender Rao                      << " CSRObjectPath=" << csrObjPath
22130215816SMarri Devender Rao                      << " service=" << service;
22230215816SMarri Devender Rao     crow::connections::systemBus->async_method_call(
22330215816SMarri Devender Rao         [asyncResp, certURI](const boost::system::error_code ec,
22430215816SMarri Devender Rao                              const std::string& csr) {
22530215816SMarri Devender Rao             if (ec)
22630215816SMarri Devender Rao             {
22730215816SMarri Devender Rao                 BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
22830215816SMarri Devender Rao                 messages::internalError(asyncResp->res);
22930215816SMarri Devender Rao                 return;
23030215816SMarri Devender Rao             }
23130215816SMarri Devender Rao             if (csr.empty())
23230215816SMarri Devender Rao             {
23330215816SMarri Devender Rao                 BMCWEB_LOG_ERROR << "CSR read is empty";
23430215816SMarri Devender Rao                 messages::internalError(asyncResp->res);
23530215816SMarri Devender Rao                 return;
23630215816SMarri Devender Rao             }
23730215816SMarri Devender Rao             asyncResp->res.jsonValue["CSRString"] = csr;
238*1476687dSEd Tanous             asyncResp->res.jsonValue["CertificateCollection"]["@odata.id"] =
239*1476687dSEd Tanous                 certURI;
24030215816SMarri Devender Rao         },
24130215816SMarri Devender Rao         service, csrObjPath, "xyz.openbmc_project.Certs.CSR", "CSR");
24230215816SMarri Devender Rao }
24330215816SMarri Devender Rao 
24430215816SMarri Devender Rao /**
24530215816SMarri Devender Rao  * Action to Generate CSR
24630215816SMarri Devender Rao  */
2477e860f15SJohn Edward Broadbent inline void requestRoutesCertificateActionGenerateCSR(App& app)
24830215816SMarri Devender Rao {
2490fda0f12SGeorge Liu     BMCWEB_ROUTE(
2500fda0f12SGeorge Liu         app,
2510fda0f12SGeorge Liu         "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR/")
2525344ab8eSAbhishek Patel         .privileges(redfish::privileges::postCertificateService)
2530fda0f12SGeorge Liu         .methods(
2540fda0f12SGeorge Liu             boost::beast::http::verb::
25545ca1b86SEd Tanous                 post)([&app](
25645ca1b86SEd Tanous                           const crow::Request& req,
2577e860f15SJohn Edward Broadbent                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
25845ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
25945ca1b86SEd Tanous             {
26045ca1b86SEd Tanous                 return;
26145ca1b86SEd Tanous             }
2622c70f800SEd Tanous             static const int rsaKeyBitLength = 2048;
2638d1b46d7Szhanghch05 
26430215816SMarri Devender Rao             // Required parameters
26530215816SMarri Devender Rao             std::string city;
26630215816SMarri Devender Rao             std::string commonName;
26730215816SMarri Devender Rao             std::string country;
26830215816SMarri Devender Rao             std::string organization;
26930215816SMarri Devender Rao             std::string organizationalUnit;
27030215816SMarri Devender Rao             std::string state;
27130215816SMarri Devender Rao             nlohmann::json certificateCollection;
27230215816SMarri Devender Rao 
27330215816SMarri Devender Rao             // Optional parameters
27430215816SMarri Devender Rao             std::optional<std::vector<std::string>> optAlternativeNames =
27530215816SMarri Devender Rao                 std::vector<std::string>();
27630215816SMarri Devender Rao             std::optional<std::string> optContactPerson = "";
27730215816SMarri Devender Rao             std::optional<std::string> optChallengePassword = "";
27830215816SMarri Devender Rao             std::optional<std::string> optEmail = "";
27930215816SMarri Devender Rao             std::optional<std::string> optGivenName = "";
28030215816SMarri Devender Rao             std::optional<std::string> optInitials = "";
2812c70f800SEd Tanous             std::optional<int64_t> optKeyBitLength = rsaKeyBitLength;
282aaf3206fSVernon Mauery             std::optional<std::string> optKeyCurveId = "secp384r1";
28330215816SMarri Devender Rao             std::optional<std::string> optKeyPairAlgorithm = "EC";
28430215816SMarri Devender Rao             std::optional<std::vector<std::string>> optKeyUsage =
28530215816SMarri Devender Rao                 std::vector<std::string>();
28630215816SMarri Devender Rao             std::optional<std::string> optSurname = "";
28730215816SMarri Devender Rao             std::optional<std::string> optUnstructuredName = "";
28815ed6780SWilly Tu             if (!json_util::readJsonAction(
2890fda0f12SGeorge Liu                     req, asyncResp->res, "City", city, "CommonName", commonName,
2900fda0f12SGeorge Liu                     "ContactPerson", optContactPerson, "Country", country,
2910fda0f12SGeorge Liu                     "Organization", organization, "OrganizationalUnit",
2920fda0f12SGeorge Liu                     organizationalUnit, "State", state, "CertificateCollection",
2930fda0f12SGeorge Liu                     certificateCollection, "AlternativeNames",
2940fda0f12SGeorge Liu                     optAlternativeNames, "ChallengePassword",
2950fda0f12SGeorge Liu                     optChallengePassword, "Email", optEmail, "GivenName",
2960fda0f12SGeorge Liu                     optGivenName, "Initials", optInitials, "KeyBitLength",
2970fda0f12SGeorge Liu                     optKeyBitLength, "KeyCurveId", optKeyCurveId,
2980fda0f12SGeorge Liu                     "KeyPairAlgorithm", optKeyPairAlgorithm, "KeyUsage",
2990fda0f12SGeorge Liu                     optKeyUsage, "Surname", optSurname, "UnstructuredName",
3000fda0f12SGeorge Liu                     optUnstructuredName))
30130215816SMarri Devender Rao             {
30230215816SMarri Devender Rao                 return;
30330215816SMarri Devender Rao             }
30430215816SMarri Devender Rao 
30530215816SMarri Devender Rao             // bmcweb has no way to store or decode a private key challenge
3067e860f15SJohn Edward Broadbent             // password, which will likely cause bmcweb to crash on startup
3077e860f15SJohn Edward Broadbent             // if this is not set on a post so not allowing the user to set
3087e860f15SJohn Edward Broadbent             // value
30926f6976fSEd Tanous             if (!optChallengePassword->empty())
31030215816SMarri Devender Rao             {
3117e860f15SJohn Edward Broadbent                 messages::actionParameterNotSupported(
3127e860f15SJohn Edward Broadbent                     asyncResp->res, "GenerateCSR", "ChallengePassword");
31330215816SMarri Devender Rao                 return;
31430215816SMarri Devender Rao             }
31530215816SMarri Devender Rao 
31630215816SMarri Devender Rao             std::string certURI;
3177e860f15SJohn Edward Broadbent             if (!redfish::json_util::readJson(certificateCollection,
3187e860f15SJohn Edward Broadbent                                               asyncResp->res, "@odata.id",
3197e860f15SJohn Edward Broadbent                                               certURI))
32030215816SMarri Devender Rao             {
32130215816SMarri Devender Rao                 return;
32230215816SMarri Devender Rao             }
32330215816SMarri Devender Rao 
32430215816SMarri Devender Rao             std::string objectPath;
32530215816SMarri Devender Rao             std::string service;
3260fda0f12SGeorge Liu             if (boost::starts_with(
3270fda0f12SGeorge Liu                     certURI,
3280fda0f12SGeorge Liu                     "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
32930215816SMarri Devender Rao             {
33030215816SMarri Devender Rao                 objectPath = certs::httpsObjectPath;
33130215816SMarri Devender Rao                 service = certs::httpsServiceName;
33230215816SMarri Devender Rao             }
3333b7f0149SMarri Devender Rao             else if (boost::starts_with(
3347e860f15SJohn Edward Broadbent                          certURI,
3357e860f15SJohn Edward Broadbent                          "/redfish/v1/AccountService/LDAP/Certificates"))
3363b7f0149SMarri Devender Rao             {
3373b7f0149SMarri Devender Rao                 objectPath = certs::ldapObjectPath;
3383b7f0149SMarri Devender Rao                 service = certs::ldapServiceName;
3393b7f0149SMarri Devender Rao             }
34030215816SMarri Devender Rao             else
34130215816SMarri Devender Rao             {
34230215816SMarri Devender Rao                 messages::actionParameterNotSupported(
34330215816SMarri Devender Rao                     asyncResp->res, "CertificateCollection", "GenerateCSR");
34430215816SMarri Devender Rao                 return;
34530215816SMarri Devender Rao             }
34630215816SMarri Devender Rao 
34730215816SMarri Devender Rao             // supporting only EC and RSA algorithm
3480fda0f12SGeorge Liu             if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
34930215816SMarri Devender Rao             {
35030215816SMarri Devender Rao                 messages::actionParameterNotSupported(
35130215816SMarri Devender Rao                     asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
35230215816SMarri Devender Rao                 return;
35330215816SMarri Devender Rao             }
35430215816SMarri Devender Rao 
3557e860f15SJohn Edward Broadbent             // supporting only 2048 key bit length for RSA algorithm due to
3567e860f15SJohn Edward Broadbent             // time consumed in generating private key
35730215816SMarri Devender Rao             if (*optKeyPairAlgorithm == "RSA" &&
3582c70f800SEd Tanous                 *optKeyBitLength != rsaKeyBitLength)
35930215816SMarri Devender Rao             {
3607e860f15SJohn Edward Broadbent                 messages::propertyValueNotInList(
3617e860f15SJohn Edward Broadbent                     asyncResp->res, std::to_string(*optKeyBitLength),
36230215816SMarri Devender Rao                     "KeyBitLength");
36330215816SMarri Devender Rao                 return;
36430215816SMarri Devender Rao             }
36530215816SMarri Devender Rao 
36630215816SMarri Devender Rao             // validate KeyUsage supporting only 1 type based on URL
3670fda0f12SGeorge Liu             if (boost::starts_with(
3680fda0f12SGeorge Liu                     certURI,
3690fda0f12SGeorge Liu                     "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
37030215816SMarri Devender Rao             {
37126f6976fSEd Tanous                 if (optKeyUsage->empty())
37230215816SMarri Devender Rao                 {
37330215816SMarri Devender Rao                     optKeyUsage->push_back("ServerAuthentication");
37430215816SMarri Devender Rao                 }
37530215816SMarri Devender Rao                 else if (optKeyUsage->size() == 1)
37630215816SMarri Devender Rao                 {
37730215816SMarri Devender Rao                     if ((*optKeyUsage)[0] != "ServerAuthentication")
37830215816SMarri Devender Rao                     {
37930215816SMarri Devender Rao                         messages::propertyValueNotInList(
38030215816SMarri Devender Rao                             asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
38130215816SMarri Devender Rao                         return;
38230215816SMarri Devender Rao                     }
38330215816SMarri Devender Rao                 }
38430215816SMarri Devender Rao                 else
38530215816SMarri Devender Rao                 {
38630215816SMarri Devender Rao                     messages::actionParameterNotSupported(
38730215816SMarri Devender Rao                         asyncResp->res, "KeyUsage", "GenerateCSR");
38830215816SMarri Devender Rao                     return;
38930215816SMarri Devender Rao                 }
39030215816SMarri Devender Rao             }
3913b7f0149SMarri Devender Rao             else if (boost::starts_with(
3927e860f15SJohn Edward Broadbent                          certURI,
3937e860f15SJohn Edward Broadbent                          "/redfish/v1/AccountService/LDAP/Certificates"))
3943b7f0149SMarri Devender Rao             {
39526f6976fSEd Tanous                 if (optKeyUsage->empty())
3963b7f0149SMarri Devender Rao                 {
3973b7f0149SMarri Devender Rao                     optKeyUsage->push_back("ClientAuthentication");
3983b7f0149SMarri Devender Rao                 }
3993b7f0149SMarri Devender Rao                 else if (optKeyUsage->size() == 1)
4003b7f0149SMarri Devender Rao                 {
4013b7f0149SMarri Devender Rao                     if ((*optKeyUsage)[0] != "ClientAuthentication")
4023b7f0149SMarri Devender Rao                     {
4033b7f0149SMarri Devender Rao                         messages::propertyValueNotInList(
4043b7f0149SMarri Devender Rao                             asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
4053b7f0149SMarri Devender Rao                         return;
4063b7f0149SMarri Devender Rao                     }
4073b7f0149SMarri Devender Rao                 }
4083b7f0149SMarri Devender Rao                 else
4093b7f0149SMarri Devender Rao                 {
4103b7f0149SMarri Devender Rao                     messages::actionParameterNotSupported(
4113b7f0149SMarri Devender Rao                         asyncResp->res, "KeyUsage", "GenerateCSR");
4123b7f0149SMarri Devender Rao                     return;
4133b7f0149SMarri Devender Rao                 }
4143b7f0149SMarri Devender Rao             }
41530215816SMarri Devender Rao 
4167e860f15SJohn Edward Broadbent             // Only allow one CSR matcher at a time so setting retry
4177e860f15SJohn Edward Broadbent             // time-out and timer expiry to 10 seconds for now.
4182c70f800SEd Tanous             static const int timeOut = 10;
41930215816SMarri Devender Rao             if (csrMatcher)
42030215816SMarri Devender Rao             {
4217e860f15SJohn Edward Broadbent                 messages::serviceTemporarilyUnavailable(
4227e860f15SJohn Edward Broadbent                     asyncResp->res, std::to_string(timeOut));
42330215816SMarri Devender Rao                 return;
42430215816SMarri Devender Rao             }
42530215816SMarri Devender Rao 
42630215816SMarri Devender Rao             // Make this static so it survives outside this method
42730215816SMarri Devender Rao             static boost::asio::steady_timer timeout(*req.ioService);
4282c70f800SEd Tanous             timeout.expires_after(std::chrono::seconds(timeOut));
4290fda0f12SGeorge Liu             timeout.async_wait(
4300fda0f12SGeorge Liu                 [asyncResp](const boost::system::error_code& ec) {
43130215816SMarri Devender Rao                     csrMatcher = nullptr;
43230215816SMarri Devender Rao                     if (ec)
43330215816SMarri Devender Rao                     {
4347e860f15SJohn Edward Broadbent                         // operation_aborted is expected if timer is canceled
4357e860f15SJohn Edward Broadbent                         // before completion.
43630215816SMarri Devender Rao                         if (ec != boost::asio::error::operation_aborted)
43730215816SMarri Devender Rao                         {
43830215816SMarri Devender Rao                             BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
43930215816SMarri Devender Rao                         }
44030215816SMarri Devender Rao                         return;
44130215816SMarri Devender Rao                     }
44230215816SMarri Devender Rao                     BMCWEB_LOG_ERROR << "Timed out waiting for Generating CSR";
44330215816SMarri Devender Rao                     messages::internalError(asyncResp->res);
44430215816SMarri Devender Rao                 });
44530215816SMarri Devender Rao 
44630215816SMarri Devender Rao             // create a matcher to wait on CSR object
44730215816SMarri Devender Rao             BMCWEB_LOG_DEBUG << "create matcher with path " << objectPath;
4480fda0f12SGeorge Liu             std::string match("type='signal',"
44930215816SMarri Devender Rao                               "interface='org.freedesktop.DBus.ObjectManager',"
45030215816SMarri Devender Rao                               "path='" +
45130215816SMarri Devender Rao                               objectPath +
45230215816SMarri Devender Rao                               "',"
45330215816SMarri Devender Rao                               "member='InterfacesAdded'");
45430215816SMarri Devender Rao             csrMatcher = std::make_unique<sdbusplus::bus::match::match>(
45530215816SMarri Devender Rao                 *crow::connections::systemBus, match,
45630215816SMarri Devender Rao                 [asyncResp, service, objectPath,
45730215816SMarri Devender Rao                  certURI](sdbusplus::message::message& m) {
458271584abSEd Tanous                     timeout.cancel();
45930215816SMarri Devender Rao                     if (m.is_method_error())
46030215816SMarri Devender Rao                     {
46130215816SMarri Devender Rao                         BMCWEB_LOG_ERROR << "Dbus method error!!!";
46230215816SMarri Devender Rao                         messages::internalError(asyncResp->res);
46330215816SMarri Devender Rao                         return;
46430215816SMarri Devender Rao                     }
465b9d36b47SEd Tanous 
466b9d36b47SEd Tanous                     dbus::utility::DBusInteracesMap interfacesProperties;
467b9d36b47SEd Tanous 
46830215816SMarri Devender Rao                     sdbusplus::message::object_path csrObjectPath;
46930215816SMarri Devender Rao                     m.read(csrObjectPath, interfacesProperties);
4700fda0f12SGeorge Liu                     BMCWEB_LOG_DEBUG << "CSR object added" << csrObjectPath.str;
47130215816SMarri Devender Rao                     for (auto& interface : interfacesProperties)
47230215816SMarri Devender Rao                     {
4730fda0f12SGeorge Liu                         if (interface.first == "xyz.openbmc_project.Certs.CSR")
47430215816SMarri Devender Rao                         {
47530215816SMarri Devender Rao                             getCSR(asyncResp, certURI, service, objectPath,
47630215816SMarri Devender Rao                                    csrObjectPath.str);
47730215816SMarri Devender Rao                             break;
47830215816SMarri Devender Rao                         }
47930215816SMarri Devender Rao                     }
48030215816SMarri Devender Rao                 });
48130215816SMarri Devender Rao             crow::connections::systemBus->async_method_call(
482914e2d5dSEd Tanous                 [asyncResp](const boost::system::error_code ec,
483cb13a392SEd Tanous                             const std::string&) {
48430215816SMarri Devender Rao                     if (ec)
48530215816SMarri Devender Rao                     {
4867e860f15SJohn Edward Broadbent                         BMCWEB_LOG_ERROR << "DBUS response error: "
4877e860f15SJohn Edward Broadbent                                          << ec.message();
48830215816SMarri Devender Rao                         messages::internalError(asyncResp->res);
48930215816SMarri Devender Rao                         return;
49030215816SMarri Devender Rao                     }
49130215816SMarri Devender Rao                 },
49230215816SMarri Devender Rao                 service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
4937e860f15SJohn Edward Broadbent                 "GenerateCSR", *optAlternativeNames, *optChallengePassword,
4947e860f15SJohn Edward Broadbent                 city, commonName, *optContactPerson, country, *optEmail,
4950fda0f12SGeorge Liu                 *optGivenName, *optInitials, *optKeyBitLength, *optKeyCurveId,
4960fda0f12SGeorge Liu                 *optKeyPairAlgorithm, *optKeyUsage, organization,
4970fda0f12SGeorge Liu                 organizationalUnit, state, *optSurname, *optUnstructuredName);
4987e860f15SJohn Edward Broadbent         });
4997e860f15SJohn Edward Broadbent } // requestRoutesCertificateActionGenerateCSR
50030215816SMarri Devender Rao 
5015968caeeSMarri Devender Rao /**
5024e0453b1SGunnar Mills  * @brief Parse and update Certificate Issue/Subject property
5035968caeeSMarri Devender Rao  *
5045968caeeSMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
5055968caeeSMarri Devender Rao  * @param[in] str  Issuer/Subject value in key=value pairs
5065968caeeSMarri Devender Rao  * @param[in] type Issuer/Subject
5075968caeeSMarri Devender Rao  * @return None
5085968caeeSMarri Devender Rao  */
5095968caeeSMarri Devender Rao static void updateCertIssuerOrSubject(nlohmann::json& out,
5105968caeeSMarri Devender Rao                                       const std::string_view value)
5115968caeeSMarri Devender Rao {
5125968caeeSMarri Devender Rao     // example: O=openbmc-project.xyz,CN=localhost
5135968caeeSMarri Devender Rao     std::string_view::iterator i = value.begin();
5145968caeeSMarri Devender Rao     while (i != value.end())
5155968caeeSMarri Devender Rao     {
5165968caeeSMarri Devender Rao         std::string_view::iterator tokenBegin = i;
5175968caeeSMarri Devender Rao         while (i != value.end() && *i != '=')
5185968caeeSMarri Devender Rao         {
51917a897dfSManojkiran Eda             ++i;
5205968caeeSMarri Devender Rao         }
5215968caeeSMarri Devender Rao         if (i == value.end())
5225968caeeSMarri Devender Rao         {
5235968caeeSMarri Devender Rao             break;
5245968caeeSMarri Devender Rao         }
525271584abSEd Tanous         const std::string_view key(tokenBegin,
526271584abSEd Tanous                                    static_cast<size_t>(i - tokenBegin));
52717a897dfSManojkiran Eda         ++i;
5285968caeeSMarri Devender Rao         tokenBegin = i;
5295968caeeSMarri Devender Rao         while (i != value.end() && *i != ',')
5305968caeeSMarri Devender Rao         {
53117a897dfSManojkiran Eda             ++i;
5325968caeeSMarri Devender Rao         }
533271584abSEd Tanous         const std::string_view val(tokenBegin,
534271584abSEd Tanous                                    static_cast<size_t>(i - tokenBegin));
5355968caeeSMarri Devender Rao         if (key == "L")
5365968caeeSMarri Devender Rao         {
5375968caeeSMarri Devender Rao             out["City"] = val;
5385968caeeSMarri Devender Rao         }
5395968caeeSMarri Devender Rao         else if (key == "CN")
5405968caeeSMarri Devender Rao         {
5415968caeeSMarri Devender Rao             out["CommonName"] = val;
5425968caeeSMarri Devender Rao         }
5435968caeeSMarri Devender Rao         else if (key == "C")
5445968caeeSMarri Devender Rao         {
5455968caeeSMarri Devender Rao             out["Country"] = val;
5465968caeeSMarri Devender Rao         }
5475968caeeSMarri Devender Rao         else if (key == "O")
5485968caeeSMarri Devender Rao         {
5495968caeeSMarri Devender Rao             out["Organization"] = val;
5505968caeeSMarri Devender Rao         }
5515968caeeSMarri Devender Rao         else if (key == "OU")
5525968caeeSMarri Devender Rao         {
5535968caeeSMarri Devender Rao             out["OrganizationalUnit"] = val;
5545968caeeSMarri Devender Rao         }
5555968caeeSMarri Devender Rao         else if (key == "ST")
5565968caeeSMarri Devender Rao         {
5575968caeeSMarri Devender Rao             out["State"] = val;
5585968caeeSMarri Devender Rao         }
5595968caeeSMarri Devender Rao         // skip comma character
5605968caeeSMarri Devender Rao         if (i != value.end())
5615968caeeSMarri Devender Rao         {
56217a897dfSManojkiran Eda             ++i;
5635968caeeSMarri Devender Rao         }
5645968caeeSMarri Devender Rao     }
5655968caeeSMarri Devender Rao }
5665968caeeSMarri Devender Rao 
5675968caeeSMarri Devender Rao /**
5685968caeeSMarri Devender Rao  * @brief Retrieve the certificates properties and append to the response
5695968caeeSMarri Devender Rao  * message
5705968caeeSMarri Devender Rao  *
5715968caeeSMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
5725968caeeSMarri Devender Rao  * @param[in] objectPath  Path of the D-Bus service object
5735968caeeSMarri Devender Rao  * @param[in] certId  Id of the certificate
5745968caeeSMarri Devender Rao  * @param[in] certURL  URL of the certificate object
5755968caeeSMarri Devender Rao  * @param[in] name  name of the certificate
5765968caeeSMarri Devender Rao  * @return None
5775968caeeSMarri Devender Rao  */
5785968caeeSMarri Devender Rao static void getCertificateProperties(
5798d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
5808d1b46d7Szhanghch05     const std::string& objectPath, const std::string& service, long certId,
5818d1b46d7Szhanghch05     const std::string& certURL, const std::string& name)
5825968caeeSMarri Devender Rao {
5835968caeeSMarri Devender Rao     BMCWEB_LOG_DEBUG << "getCertificateProperties Path=" << objectPath
5845968caeeSMarri Devender Rao                      << " certId=" << certId << " certURl=" << certURL;
5855968caeeSMarri Devender Rao     crow::connections::systemBus->async_method_call(
586b9d36b47SEd Tanous         [asyncResp, certURL, certId,
587b9d36b47SEd Tanous          name](const boost::system::error_code ec,
588b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
5895968caeeSMarri Devender Rao             if (ec)
5905968caeeSMarri Devender Rao             {
5915968caeeSMarri Devender Rao                 BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
5928aae75adSMarri Devender Rao                 messages::resourceNotFound(asyncResp->res, name,
5938aae75adSMarri Devender Rao                                            std::to_string(certId));
5945968caeeSMarri Devender Rao                 return;
5955968caeeSMarri Devender Rao             }
596*1476687dSEd Tanous             asyncResp->res.jsonValue["@odata.id"] = certURL;
597*1476687dSEd Tanous             asyncResp->res.jsonValue["@odata.type"] =
598*1476687dSEd Tanous                 "#Certificate.v1_0_0.Certificate";
599*1476687dSEd Tanous             asyncResp->res.jsonValue["Id"] = std::to_string(certId);
600*1476687dSEd Tanous             asyncResp->res.jsonValue["Name"] = name;
601*1476687dSEd Tanous             asyncResp->res.jsonValue["Description"] = name;
6025968caeeSMarri Devender Rao             for (const auto& property : properties)
6035968caeeSMarri Devender Rao             {
6045968caeeSMarri Devender Rao                 if (property.first == "CertificateString")
6055968caeeSMarri Devender Rao                 {
6065968caeeSMarri Devender Rao                     asyncResp->res.jsonValue["CertificateString"] = "";
6075968caeeSMarri Devender Rao                     const std::string* value =
6085968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
609e662eae8SEd Tanous                     if (value != nullptr)
6105968caeeSMarri Devender Rao                     {
61137cce918SMarri Devender Rao                         asyncResp->res.jsonValue["CertificateString"] = *value;
6125968caeeSMarri Devender Rao                     }
6135968caeeSMarri Devender Rao                 }
6145968caeeSMarri Devender Rao                 else if (property.first == "KeyUsage")
6155968caeeSMarri Devender Rao                 {
6165968caeeSMarri Devender Rao                     nlohmann::json& keyUsage =
6175968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["KeyUsage"];
6185968caeeSMarri Devender Rao                     keyUsage = nlohmann::json::array();
6195968caeeSMarri Devender Rao                     const std::vector<std::string>* value =
62037cce918SMarri Devender Rao                         std::get_if<std::vector<std::string>>(&property.second);
621e662eae8SEd Tanous                     if (value != nullptr)
6225968caeeSMarri Devender Rao                     {
6235968caeeSMarri Devender Rao                         for (const std::string& usage : *value)
6245968caeeSMarri Devender Rao                         {
6255968caeeSMarri Devender Rao                             keyUsage.push_back(usage);
6265968caeeSMarri Devender Rao                         }
6275968caeeSMarri Devender Rao                     }
6285968caeeSMarri Devender Rao                 }
6295968caeeSMarri Devender Rao                 else if (property.first == "Issuer")
6305968caeeSMarri Devender Rao                 {
6315968caeeSMarri Devender Rao                     const std::string* value =
6325968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
633e662eae8SEd Tanous                     if (value != nullptr)
6345968caeeSMarri Devender Rao                     {
6355968caeeSMarri Devender Rao                         updateCertIssuerOrSubject(
6365968caeeSMarri Devender Rao                             asyncResp->res.jsonValue["Issuer"], *value);
6375968caeeSMarri Devender Rao                     }
6385968caeeSMarri Devender Rao                 }
6395968caeeSMarri Devender Rao                 else if (property.first == "Subject")
6405968caeeSMarri Devender Rao                 {
6415968caeeSMarri Devender Rao                     const std::string* value =
6425968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
643e662eae8SEd Tanous                     if (value != nullptr)
6445968caeeSMarri Devender Rao                     {
6455968caeeSMarri Devender Rao                         updateCertIssuerOrSubject(
64637cce918SMarri Devender Rao                             asyncResp->res.jsonValue["Subject"], *value);
6475968caeeSMarri Devender Rao                     }
6485968caeeSMarri Devender Rao                 }
6495968caeeSMarri Devender Rao                 else if (property.first == "ValidNotAfter")
6505968caeeSMarri Devender Rao                 {
6515968caeeSMarri Devender Rao                     const uint64_t* value =
6525968caeeSMarri Devender Rao                         std::get_if<uint64_t>(&property.second);
653e662eae8SEd Tanous                     if (value != nullptr)
6545968caeeSMarri Devender Rao                     {
6555968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["ValidNotAfter"] =
6561d8782e7SNan Zhou                             crow::utility::getDateTimeUint(*value);
6575968caeeSMarri Devender Rao                     }
6585968caeeSMarri Devender Rao                 }
6595968caeeSMarri Devender Rao                 else if (property.first == "ValidNotBefore")
6605968caeeSMarri Devender Rao                 {
6615968caeeSMarri Devender Rao                     const uint64_t* value =
6625968caeeSMarri Devender Rao                         std::get_if<uint64_t>(&property.second);
663e662eae8SEd Tanous                     if (value != nullptr)
6645968caeeSMarri Devender Rao                     {
6655968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["ValidNotBefore"] =
6661d8782e7SNan Zhou                             crow::utility::getDateTimeUint(*value);
6675968caeeSMarri Devender Rao                     }
6685968caeeSMarri Devender Rao                 }
6695968caeeSMarri Devender Rao             }
6705968caeeSMarri Devender Rao             asyncResp->res.addHeader("Location", certURL);
6715968caeeSMarri Devender Rao         },
6725968caeeSMarri Devender Rao         service, objectPath, certs::dbusPropIntf, "GetAll",
6735968caeeSMarri Devender Rao         certs::certPropIntf);
6745968caeeSMarri Devender Rao }
6755968caeeSMarri Devender Rao 
6765968caeeSMarri Devender Rao /**
6775968caeeSMarri Devender Rao  * Action to replace an existing certificate
6785968caeeSMarri Devender Rao  */
6797e860f15SJohn Edward Broadbent inline void requestRoutesCertificateActionsReplaceCertificate(App& app)
6805968caeeSMarri Devender Rao {
6810fda0f12SGeorge Liu     BMCWEB_ROUTE(
6820fda0f12SGeorge Liu         app,
6830fda0f12SGeorge Liu         "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate/")
684ed398213SEd Tanous         .privileges(redfish::privileges::postCertificateService)
6857e860f15SJohn Edward Broadbent         .methods(
6867e860f15SJohn Edward Broadbent             boost::beast::http::verb::
68745ca1b86SEd Tanous                 post)([&app](
68845ca1b86SEd Tanous                           const crow::Request& req,
6897e860f15SJohn Edward Broadbent                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
69045ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
69145ca1b86SEd Tanous             {
69245ca1b86SEd Tanous                 return;
69345ca1b86SEd Tanous             }
6945968caeeSMarri Devender Rao             std::string certificate;
6955968caeeSMarri Devender Rao             nlohmann::json certificateUri;
6965968caeeSMarri Devender Rao             std::optional<std::string> certificateType = "PEM";
6978d1b46d7Szhanghch05 
69815ed6780SWilly Tu             if (!json_util::readJsonAction(req, asyncResp->res,
69915ed6780SWilly Tu                                            "CertificateString", certificate,
70015ed6780SWilly Tu                                            "CertificateUri", certificateUri,
70115ed6780SWilly Tu                                            "CertificateType", certificateType))
7025968caeeSMarri Devender Rao             {
7035968caeeSMarri Devender Rao                 BMCWEB_LOG_ERROR << "Required parameters are missing";
7045968caeeSMarri Devender Rao                 messages::internalError(asyncResp->res);
7055968caeeSMarri Devender Rao                 return;
7065968caeeSMarri Devender Rao             }
7075968caeeSMarri Devender Rao 
7085968caeeSMarri Devender Rao             if (!certificateType)
7095968caeeSMarri Devender Rao             {
7105968caeeSMarri Devender Rao                 // should never happen, but it never hurts to be paranoid.
7115968caeeSMarri Devender Rao                 return;
7125968caeeSMarri Devender Rao             }
7135968caeeSMarri Devender Rao             if (certificateType != "PEM")
7145968caeeSMarri Devender Rao             {
7155968caeeSMarri Devender Rao                 messages::actionParameterNotSupported(
7165968caeeSMarri Devender Rao                     asyncResp->res, "CertificateType", "ReplaceCertificate");
7175968caeeSMarri Devender Rao                 return;
7185968caeeSMarri Devender Rao             }
7195968caeeSMarri Devender Rao 
7205968caeeSMarri Devender Rao             std::string certURI;
7215968caeeSMarri Devender Rao             if (!redfish::json_util::readJson(certificateUri, asyncResp->res,
7225968caeeSMarri Devender Rao                                               "@odata.id", certURI))
7235968caeeSMarri Devender Rao             {
7245968caeeSMarri Devender Rao                 messages::actionParameterMissing(
7255968caeeSMarri Devender Rao                     asyncResp->res, "ReplaceCertificate", "CertificateUri");
7265968caeeSMarri Devender Rao                 return;
7275968caeeSMarri Devender Rao             }
7285968caeeSMarri Devender Rao 
7295968caeeSMarri Devender Rao             BMCWEB_LOG_INFO << "Certificate URI to replace" << certURI;
7305968caeeSMarri Devender Rao             long id = getIDFromURL(certURI);
7315968caeeSMarri Devender Rao             if (id < 0)
7325968caeeSMarri Devender Rao             {
7337e860f15SJohn Edward Broadbent                 messages::actionParameterValueFormatError(
7347e860f15SJohn Edward Broadbent                     asyncResp->res, certURI, "CertificateUri",
7355968caeeSMarri Devender Rao                     "ReplaceCertificate");
7365968caeeSMarri Devender Rao                 return;
7375968caeeSMarri Devender Rao             }
7385968caeeSMarri Devender Rao             std::string objectPath;
7395968caeeSMarri Devender Rao             std::string name;
74037cce918SMarri Devender Rao             std::string service;
7410fda0f12SGeorge Liu             if (boost::starts_with(
7420fda0f12SGeorge Liu                     certURI,
7430fda0f12SGeorge Liu                     "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/"))
7445968caeeSMarri Devender Rao             {
7457e860f15SJohn Edward Broadbent                 objectPath = std::string(certs::httpsObjectPath) + "/" +
7467e860f15SJohn Edward Broadbent                              std::to_string(id);
7475968caeeSMarri Devender Rao                 name = "HTTPS certificate";
74837cce918SMarri Devender Rao                 service = certs::httpsServiceName;
74937cce918SMarri Devender Rao             }
75037cce918SMarri Devender Rao             else if (boost::starts_with(
7517e860f15SJohn Edward Broadbent                          certURI,
7527e860f15SJohn Edward Broadbent                          "/redfish/v1/AccountService/LDAP/Certificates/"))
75337cce918SMarri Devender Rao             {
7547e860f15SJohn Edward Broadbent                 objectPath = std::string(certs::ldapObjectPath) + "/" +
7557e860f15SJohn Edward Broadbent                              std::to_string(id);
75637cce918SMarri Devender Rao                 name = "LDAP certificate";
75737cce918SMarri Devender Rao                 service = certs::ldapServiceName;
7585968caeeSMarri Devender Rao             }
759cfcd5f6bSMarri Devender Rao             else if (boost::starts_with(
760cfcd5f6bSMarri Devender Rao                          certURI,
761cfcd5f6bSMarri Devender Rao                          "/redfish/v1/Managers/bmc/Truststore/Certificates/"))
762cfcd5f6bSMarri Devender Rao             {
763cfcd5f6bSMarri Devender Rao                 objectPath = std::string(certs::authorityObjectPath) + "/" +
764cfcd5f6bSMarri Devender Rao                              std::to_string(id);
765cfcd5f6bSMarri Devender Rao                 name = "TrustStore certificate";
766cfcd5f6bSMarri Devender Rao                 service = certs::authorityServiceName;
767cfcd5f6bSMarri Devender Rao             }
7685968caeeSMarri Devender Rao             else
7695968caeeSMarri Devender Rao             {
7705968caeeSMarri Devender Rao                 messages::actionParameterNotSupported(
7715968caeeSMarri Devender Rao                     asyncResp->res, "CertificateUri", "ReplaceCertificate");
7725968caeeSMarri Devender Rao                 return;
7735968caeeSMarri Devender Rao             }
7745968caeeSMarri Devender Rao 
7755968caeeSMarri Devender Rao             std::shared_ptr<CertificateFile> certFile =
7765968caeeSMarri Devender Rao                 std::make_shared<CertificateFile>(certificate);
7775968caeeSMarri Devender Rao             crow::connections::systemBus->async_method_call(
77837cce918SMarri Devender Rao                 [asyncResp, certFile, objectPath, service, certURI, id,
7795968caeeSMarri Devender Rao                  name](const boost::system::error_code ec) {
7805968caeeSMarri Devender Rao                     if (ec)
7815968caeeSMarri Devender Rao                     {
7825968caeeSMarri Devender Rao                         BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
78390d2d1e8SJiaqing Zhao                         if (ec.value() ==
78490d2d1e8SJiaqing Zhao                             boost::system::linux_error::bad_request_descriptor)
78590d2d1e8SJiaqing Zhao                         {
7868aae75adSMarri Devender Rao                             messages::resourceNotFound(asyncResp->res, name,
7878aae75adSMarri Devender Rao                                                        std::to_string(id));
7885968caeeSMarri Devender Rao                             return;
7895968caeeSMarri Devender Rao                         }
79090d2d1e8SJiaqing Zhao                         messages::internalError(asyncResp->res);
79190d2d1e8SJiaqing Zhao                         return;
79290d2d1e8SJiaqing Zhao                     }
79337cce918SMarri Devender Rao                     getCertificateProperties(asyncResp, objectPath, service, id,
7945968caeeSMarri Devender Rao                                              certURI, name);
7955968caeeSMarri Devender Rao                     BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
7965968caeeSMarri Devender Rao                                      << certFile->getCertFilePath();
7975968caeeSMarri Devender Rao                 },
7985968caeeSMarri Devender Rao                 service, objectPath, certs::certReplaceIntf, "Replace",
7995968caeeSMarri Devender Rao                 certFile->getCertFilePath());
8007e860f15SJohn Edward Broadbent         });
8017e860f15SJohn Edward Broadbent } // requestRoutesCertificateActionsReplaceCertificate
8025968caeeSMarri Devender Rao 
8035968caeeSMarri Devender Rao /**
8045968caeeSMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
8055968caeeSMarri Devender Rao  * of a component, account or service.
8065968caeeSMarri Devender Rao  */
8075968caeeSMarri Devender Rao 
8087e860f15SJohn Edward Broadbent inline void requestRoutesHTTPSCertificate(App& app)
8095968caeeSMarri Devender Rao {
8107e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
8117e860f15SJohn Edward Broadbent         app,
8127e860f15SJohn Edward Broadbent         "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/<str>/")
813ed398213SEd Tanous         .privileges(redfish::privileges::getCertificate)
8147e860f15SJohn Edward Broadbent         .methods(
8157e860f15SJohn Edward Broadbent             boost::beast::http::verb::
81645ca1b86SEd Tanous                 get)([&app](const crow::Request& req,
8177e860f15SJohn Edward Broadbent                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8187e860f15SJohn Edward Broadbent                             const std::string& param) -> void {
81945ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
82045ca1b86SEd Tanous             {
82145ca1b86SEd Tanous                 return;
82245ca1b86SEd Tanous             }
8237e860f15SJohn Edward Broadbent             if (param.empty())
8245968caeeSMarri Devender Rao             {
8255968caeeSMarri Devender Rao                 messages::internalError(asyncResp->res);
8265968caeeSMarri Devender Rao                 return;
8275968caeeSMarri Devender Rao             }
8285968caeeSMarri Devender Rao             long id = getIDFromURL(req.url);
8295968caeeSMarri Devender Rao 
8307e860f15SJohn Edward Broadbent             BMCWEB_LOG_DEBUG << "HTTPSCertificate::doGet ID="
8317e860f15SJohn Edward Broadbent                              << std::to_string(id);
8325968caeeSMarri Devender Rao             std::string certURL =
8335968caeeSMarri Devender Rao                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" +
8345968caeeSMarri Devender Rao                 std::to_string(id);
8355968caeeSMarri Devender Rao             std::string objectPath = certs::httpsObjectPath;
8365968caeeSMarri Devender Rao             objectPath += "/";
8375968caeeSMarri Devender Rao             objectPath += std::to_string(id);
8387e860f15SJohn Edward Broadbent             getCertificateProperties(asyncResp, objectPath,
8397e860f15SJohn Edward Broadbent                                      certs::httpsServiceName, id, certURL,
8407e860f15SJohn Edward Broadbent                                      "HTTPS Certificate");
8417e860f15SJohn Edward Broadbent         });
8425968caeeSMarri Devender Rao }
8435968caeeSMarri Devender Rao 
8445968caeeSMarri Devender Rao /**
8455968caeeSMarri Devender Rao  * Collection of HTTPS certificates
8465968caeeSMarri Devender Rao  */
8477e860f15SJohn Edward Broadbent inline void requestRoutesHTTPSCertificateCollection(App& app)
8485968caeeSMarri Devender Rao {
8497e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
8505968caeeSMarri Devender Rao                  "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
851ed398213SEd Tanous         .privileges(redfish::privileges::getCertificateCollection)
85245ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)([&app](const crow::Request& req,
85345ca1b86SEd Tanous                                                        const std::shared_ptr<
85445ca1b86SEd Tanous                                                            bmcweb::AsyncResp>&
85545ca1b86SEd Tanous                                                            asyncResp) {
85645ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
85745ca1b86SEd Tanous             {
85845ca1b86SEd Tanous                 return;
85945ca1b86SEd Tanous             }
860*1476687dSEd Tanous 
861*1476687dSEd Tanous             asyncResp->res.jsonValue["@odata.id"] =
862*1476687dSEd Tanous                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates";
863*1476687dSEd Tanous             asyncResp->res.jsonValue["@odata.type"] =
864*1476687dSEd Tanous                 "#CertificateCollection.CertificateCollection";
865*1476687dSEd Tanous             asyncResp->res.jsonValue["Name"] = "HTTPS Certificates Collection";
866*1476687dSEd Tanous             asyncResp->res.jsonValue["Description"] =
867*1476687dSEd Tanous                 "A Collection of HTTPS certificate instances";
8688d1b46d7Szhanghch05 
8695968caeeSMarri Devender Rao             crow::connections::systemBus->async_method_call(
8705968caeeSMarri Devender Rao                 [asyncResp](const boost::system::error_code ec,
871711ac7a9SEd Tanous                             const dbus::utility::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                     }
8787e860f15SJohn Edward Broadbent                     nlohmann::json& members =
8797e860f15SJohn Edward Broadbent                         asyncResp->res.jsonValue["Members"];
8805968caeeSMarri Devender Rao                     members = nlohmann::json::array();
8815968caeeSMarri Devender Rao                     for (const auto& cert : certs)
8825968caeeSMarri Devender Rao                     {
8835968caeeSMarri Devender Rao                         long id = getIDFromURL(cert.first.str);
88437cce918SMarri Devender Rao                         if (id >= 0)
8855968caeeSMarri Devender Rao                         {
886*1476687dSEd Tanous                             nlohmann::json::object_t member;
887*1476687dSEd Tanous                             member["@odata.id"] =
8880fda0f12SGeorge Liu                                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" +
889*1476687dSEd Tanous                                 std::to_string(id);
890*1476687dSEd Tanous                             members.push_back(std::move(member));
8915968caeeSMarri Devender Rao                         }
8925968caeeSMarri Devender Rao                     }
8935968caeeSMarri Devender Rao                     asyncResp->res.jsonValue["Members@odata.count"] =
8945968caeeSMarri Devender Rao                         members.size();
8955968caeeSMarri Devender Rao                 },
89637cce918SMarri Devender Rao                 certs::httpsServiceName, certs::httpsObjectPath,
89737cce918SMarri Devender Rao                 certs::dbusObjManagerIntf, "GetManagedObjects");
8987e860f15SJohn Edward Broadbent         });
8995968caeeSMarri Devender Rao 
9007e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
9017e860f15SJohn Edward Broadbent                  "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
902ed398213SEd Tanous         .privileges(redfish::privileges::postCertificateCollection)
9030fda0f12SGeorge Liu         .methods(
9040fda0f12SGeorge Liu             boost::beast::http::verb::
90545ca1b86SEd Tanous                 post)([&app](
90645ca1b86SEd Tanous                           const crow::Request& req,
9077e860f15SJohn Edward Broadbent                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
90845ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
90945ca1b86SEd Tanous             {
91045ca1b86SEd Tanous                 return;
91145ca1b86SEd Tanous             }
9125968caeeSMarri Devender Rao             BMCWEB_LOG_DEBUG << "HTTPSCertificateCollection::doPost";
9138d1b46d7Szhanghch05 
914*1476687dSEd Tanous             asyncResp->res.jsonValue["Name"] = "HTTPS Certificate";
915*1476687dSEd Tanous             asyncResp->res.jsonValue["Description"] = "HTTPS Certificate";
9165968caeeSMarri Devender Rao 
9177e860f15SJohn Edward Broadbent             std::string certFileBody =
9187e860f15SJohn Edward Broadbent                 getCertificateFromReqBody(asyncResp, req);
91958eb238fSKowalski, Kamil 
92058eb238fSKowalski, Kamil             if (certFileBody.empty())
92158eb238fSKowalski, Kamil             {
9220fda0f12SGeorge Liu                 BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
923a08752f5SZbigniew Kurzynski                 messages::unrecognizedRequestBody(asyncResp->res);
92458eb238fSKowalski, Kamil                 return;
92558eb238fSKowalski, Kamil             }
92658eb238fSKowalski, Kamil 
9275968caeeSMarri Devender Rao             std::shared_ptr<CertificateFile> certFile =
92858eb238fSKowalski, Kamil                 std::make_shared<CertificateFile>(certFileBody);
9295968caeeSMarri Devender Rao 
9305968caeeSMarri Devender Rao             crow::connections::systemBus->async_method_call(
931656ec7e3SZbigniew Kurzynski                 [asyncResp, certFile](const boost::system::error_code ec,
932656ec7e3SZbigniew Kurzynski                                       const std::string& objectPath) {
9335968caeeSMarri Devender Rao                     if (ec)
9345968caeeSMarri Devender Rao                     {
9355968caeeSMarri Devender Rao                         BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
9365968caeeSMarri Devender Rao                         messages::internalError(asyncResp->res);
9375968caeeSMarri Devender Rao                         return;
9385968caeeSMarri Devender Rao                     }
939656ec7e3SZbigniew Kurzynski                     long certId = getIDFromURL(objectPath);
940656ec7e3SZbigniew Kurzynski                     if (certId < 0)
941656ec7e3SZbigniew Kurzynski                     {
942656ec7e3SZbigniew Kurzynski                         BMCWEB_LOG_ERROR << "Invalid objectPath value"
943656ec7e3SZbigniew Kurzynski                                          << objectPath;
944656ec7e3SZbigniew Kurzynski                         messages::internalError(asyncResp->res);
945656ec7e3SZbigniew Kurzynski                         return;
946656ec7e3SZbigniew Kurzynski                     }
9475968caeeSMarri Devender Rao                     std::string certURL =
9480fda0f12SGeorge Liu                         "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" +
9495968caeeSMarri Devender Rao                         std::to_string(certId);
9500fda0f12SGeorge Liu                     getCertificateProperties(asyncResp, objectPath,
9510fda0f12SGeorge Liu                                              certs::httpsServiceName, certId,
9520fda0f12SGeorge Liu                                              certURL, "HTTPS Certificate");
9535968caeeSMarri Devender Rao                     BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
9545968caeeSMarri Devender Rao                                      << certFile->getCertFilePath();
9555968caeeSMarri Devender Rao                 },
95637cce918SMarri Devender Rao                 certs::httpsServiceName, certs::httpsObjectPath,
9570fda0f12SGeorge Liu                 certs::certInstallIntf, "Install", certFile->getCertFilePath());
9587e860f15SJohn Edward Broadbent         });
9597e860f15SJohn Edward Broadbent } // requestRoutesHTTPSCertificateCollection
9605968caeeSMarri Devender Rao 
9615968caeeSMarri Devender Rao /**
96237cce918SMarri Devender Rao  * @brief Retrieve the certificates installed list and append to the
96337cce918SMarri Devender Rao  * response
96437cce918SMarri Devender Rao  *
96537cce918SMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
96637cce918SMarri Devender Rao  * @param[in] certURL  Path of the certificate object
96737cce918SMarri Devender Rao  * @param[in] path  Path of the D-Bus service object
96837cce918SMarri Devender Rao  * @return None
96937cce918SMarri Devender Rao  */
9704f48d5f6SEd Tanous inline void
9714f48d5f6SEd Tanous     getCertificateLocations(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9728d1b46d7Szhanghch05                             const std::string& certURL, const std::string& path,
97337cce918SMarri Devender Rao                             const std::string& service)
97437cce918SMarri Devender Rao {
97537cce918SMarri Devender Rao     BMCWEB_LOG_DEBUG << "getCertificateLocations URI=" << certURL
97637cce918SMarri Devender Rao                      << " Path=" << path << " service= " << service;
97737cce918SMarri Devender Rao     crow::connections::systemBus->async_method_call(
97837cce918SMarri Devender Rao         [asyncResp, certURL](const boost::system::error_code ec,
979711ac7a9SEd Tanous                              const dbus::utility::ManagedObjectType& certs) {
98037cce918SMarri Devender Rao             if (ec)
98137cce918SMarri Devender Rao             {
9829c8e039eSJonathan Doman                 BMCWEB_LOG_WARNING
9839c8e039eSJonathan Doman                     << "Certificate collection query failed: " << ec
9849c8e039eSJonathan Doman                     << ", skipping " << certURL;
98537cce918SMarri Devender Rao                 return;
98637cce918SMarri Devender Rao             }
98737cce918SMarri Devender Rao             nlohmann::json& links =
98837cce918SMarri Devender Rao                 asyncResp->res.jsonValue["Links"]["Certificates"];
9899eb808c1SEd Tanous             for (const auto& cert : certs)
99037cce918SMarri Devender Rao             {
99137cce918SMarri Devender Rao                 long id = getIDFromURL(cert.first.str);
99237cce918SMarri Devender Rao                 if (id >= 0)
99337cce918SMarri Devender Rao                 {
994*1476687dSEd Tanous                     nlohmann::json::object_t link;
995*1476687dSEd Tanous                     link["@odata.id"] = certURL + std::to_string(id);
996*1476687dSEd Tanous                     links.push_back(std::move(link));
99737cce918SMarri Devender Rao                 }
99837cce918SMarri Devender Rao             }
99937cce918SMarri Devender Rao             asyncResp->res.jsonValue["Links"]["Certificates@odata.count"] =
100037cce918SMarri Devender Rao                 links.size();
100137cce918SMarri Devender Rao         },
100237cce918SMarri Devender Rao         service, path, certs::dbusObjManagerIntf, "GetManagedObjects");
10035968caeeSMarri Devender Rao }
10047e860f15SJohn Edward Broadbent 
10057e860f15SJohn Edward Broadbent /**
10067e860f15SJohn Edward Broadbent  * The certificate location schema defines a resource that an administrator
10077e860f15SJohn Edward Broadbent  * can use in order to locate all certificates installed on a given service.
10087e860f15SJohn Edward Broadbent  */
10097e860f15SJohn Edward Broadbent inline void requestRoutesCertificateLocations(App& app)
10107e860f15SJohn Edward Broadbent {
10117e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/CertificateLocations/")
1012ed398213SEd Tanous         .privileges(redfish::privileges::getCertificateLocations)
101345ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)([&app](const crow::Request& req,
101445ca1b86SEd Tanous                                                        const std::shared_ptr<
101545ca1b86SEd Tanous                                                            bmcweb::AsyncResp>&
101645ca1b86SEd Tanous                                                            asyncResp) {
101745ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
101845ca1b86SEd Tanous             {
101945ca1b86SEd Tanous                 return;
102045ca1b86SEd Tanous             }
1021*1476687dSEd Tanous             asyncResp->res.jsonValue["@odata.id"] =
1022*1476687dSEd Tanous                 "/redfish/v1/CertificateService/CertificateLocations";
1023*1476687dSEd Tanous             asyncResp->res.jsonValue["@odata.type"] =
1024*1476687dSEd Tanous                 "#CertificateLocations.v1_0_0.CertificateLocations";
1025*1476687dSEd Tanous             asyncResp->res.jsonValue["Name"] = "Certificate Locations";
1026*1476687dSEd Tanous             asyncResp->res.jsonValue["Id"] = "CertificateLocations";
1027*1476687dSEd Tanous             asyncResp->res.jsonValue["Description"] =
10287e860f15SJohn Edward Broadbent                 "Defines a resource that an administrator can use in order to "
1029*1476687dSEd Tanous                 "locate all certificates installed on a given service";
10307e860f15SJohn Edward Broadbent 
10317e860f15SJohn Edward Broadbent             nlohmann::json& links =
10327e860f15SJohn Edward Broadbent                 asyncResp->res.jsonValue["Links"]["Certificates"];
10337e860f15SJohn Edward Broadbent             links = nlohmann::json::array();
10347e860f15SJohn Edward Broadbent             getCertificateLocations(
10357e860f15SJohn Edward Broadbent                 asyncResp,
10367e860f15SJohn Edward Broadbent                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/",
10377e860f15SJohn Edward Broadbent                 certs::httpsObjectPath, certs::httpsServiceName);
10387e860f15SJohn Edward Broadbent             getCertificateLocations(
10397e860f15SJohn Edward Broadbent                 asyncResp, "/redfish/v1/AccountService/LDAP/Certificates/",
10407e860f15SJohn Edward Broadbent                 certs::ldapObjectPath, certs::ldapServiceName);
10417e860f15SJohn Edward Broadbent             getCertificateLocations(
10427e860f15SJohn Edward Broadbent                 asyncResp, "/redfish/v1/Managers/bmc/Truststore/Certificates/",
10437e860f15SJohn Edward Broadbent                 certs::authorityObjectPath, certs::authorityServiceName);
10447e860f15SJohn Edward Broadbent         });
10457e860f15SJohn Edward Broadbent }
10467e860f15SJohn Edward Broadbent // requestRoutesCertificateLocations
104737cce918SMarri Devender Rao 
104837cce918SMarri Devender Rao /**
104937cce918SMarri Devender Rao  * Collection of LDAP certificates
105037cce918SMarri Devender Rao  */
10517e860f15SJohn Edward Broadbent inline void requestRoutesLDAPCertificateCollection(App& app)
105237cce918SMarri Devender Rao {
10537e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
1054ed398213SEd Tanous         .privileges(redfish::privileges::getCertificateCollection)
105545ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)([&app](const crow::Request& req,
105645ca1b86SEd Tanous                                                        const std::shared_ptr<
105745ca1b86SEd Tanous                                                            bmcweb::AsyncResp>&
105845ca1b86SEd Tanous                                                            asyncResp) {
105945ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
106045ca1b86SEd Tanous             {
106145ca1b86SEd Tanous                 return;
106245ca1b86SEd Tanous             }
1063*1476687dSEd Tanous 
1064*1476687dSEd Tanous             asyncResp->res.jsonValue["@odata.id"] =
1065*1476687dSEd Tanous                 "/redfish/v1/AccountService/LDAP/Certificates";
1066*1476687dSEd Tanous             asyncResp->res.jsonValue["@odata.type"] =
1067*1476687dSEd Tanous                 "#CertificateCollection.CertificateCollection";
1068*1476687dSEd Tanous             asyncResp->res.jsonValue["Name"] = "LDAP Certificates Collection";
1069*1476687dSEd Tanous             asyncResp->res.jsonValue["Description"] =
1070*1476687dSEd Tanous                 "A Collection of LDAP certificate instances";
10718d1b46d7Szhanghch05 
107237cce918SMarri Devender Rao             crow::connections::systemBus->async_method_call(
107337cce918SMarri Devender Rao                 [asyncResp](const boost::system::error_code ec,
1074711ac7a9SEd Tanous                             const dbus::utility::ManagedObjectType& certs) {
10757e860f15SJohn Edward Broadbent                     nlohmann::json& members =
10767e860f15SJohn Edward Broadbent                         asyncResp->res.jsonValue["Members"];
10779c8e039eSJonathan Doman                     nlohmann::json& count =
10789c8e039eSJonathan Doman                         asyncResp->res.jsonValue["Members@odata.count"];
10799c8e039eSJonathan Doman                     members = nlohmann::json::array();
10809c8e039eSJonathan Doman                     count = 0;
108137cce918SMarri Devender Rao                     if (ec)
108237cce918SMarri Devender Rao                     {
10830fda0f12SGeorge Liu                         BMCWEB_LOG_WARNING << "LDAP certificate query failed: "
10840fda0f12SGeorge Liu                                            << ec;
108537cce918SMarri Devender Rao                         return;
108637cce918SMarri Devender Rao                     }
108737cce918SMarri Devender Rao                     for (const auto& cert : certs)
108837cce918SMarri Devender Rao                     {
108937cce918SMarri Devender Rao                         long id = getIDFromURL(cert.first.str);
109037cce918SMarri Devender Rao                         if (id >= 0)
109137cce918SMarri Devender Rao                         {
1092*1476687dSEd Tanous                             nlohmann::json::object_t member;
1093*1476687dSEd Tanous                             member["@odata.id"] =
10940fda0f12SGeorge Liu                                 "/redfish/v1/AccountService/LDAP/Certificates/" +
1095*1476687dSEd Tanous                                 std::to_string(id);
1096*1476687dSEd Tanous                             members.push_back(std::move(member));
109737cce918SMarri Devender Rao                         }
109837cce918SMarri Devender Rao                     }
10999c8e039eSJonathan Doman                     count = members.size();
110037cce918SMarri Devender Rao                 },
110137cce918SMarri Devender Rao                 certs::ldapServiceName, certs::ldapObjectPath,
110237cce918SMarri Devender Rao                 certs::dbusObjManagerIntf, "GetManagedObjects");
11037e860f15SJohn Edward Broadbent         });
110437cce918SMarri Devender Rao 
11057e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
1106ed398213SEd Tanous         .privileges(redfish::privileges::postCertificateCollection)
11077e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::post)(
110845ca1b86SEd Tanous             [&app](const crow::Request& req,
11097e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
111045ca1b86SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
111145ca1b86SEd Tanous                 {
111245ca1b86SEd Tanous                     return;
111345ca1b86SEd Tanous                 }
11147e860f15SJohn Edward Broadbent                 std::string certFileBody =
11157e860f15SJohn Edward Broadbent                     getCertificateFromReqBody(asyncResp, req);
111658eb238fSKowalski, Kamil 
111758eb238fSKowalski, Kamil                 if (certFileBody.empty())
111858eb238fSKowalski, Kamil                 {
11197e860f15SJohn Edward Broadbent                     BMCWEB_LOG_ERROR
11207e860f15SJohn Edward Broadbent                         << "Cannot get certificate from request body.";
1121a08752f5SZbigniew Kurzynski                     messages::unrecognizedRequestBody(asyncResp->res);
112258eb238fSKowalski, Kamil                     return;
112358eb238fSKowalski, Kamil                 }
112458eb238fSKowalski, Kamil 
112558eb238fSKowalski, Kamil                 std::shared_ptr<CertificateFile> certFile =
112658eb238fSKowalski, Kamil                     std::make_shared<CertificateFile>(certFileBody);
112758eb238fSKowalski, Kamil 
112837cce918SMarri Devender Rao                 crow::connections::systemBus->async_method_call(
1129656ec7e3SZbigniew Kurzynski                     [asyncResp, certFile](const boost::system::error_code ec,
1130656ec7e3SZbigniew Kurzynski                                           const std::string& objectPath) {
113137cce918SMarri Devender Rao                         if (ec)
113237cce918SMarri Devender Rao                         {
113337cce918SMarri Devender Rao                             BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
113437cce918SMarri Devender Rao                             messages::internalError(asyncResp->res);
113537cce918SMarri Devender Rao                             return;
113637cce918SMarri Devender Rao                         }
1137656ec7e3SZbigniew Kurzynski                         long certId = getIDFromURL(objectPath);
1138656ec7e3SZbigniew Kurzynski                         if (certId < 0)
1139656ec7e3SZbigniew Kurzynski                         {
1140656ec7e3SZbigniew Kurzynski                             BMCWEB_LOG_ERROR << "Invalid objectPath value"
1141656ec7e3SZbigniew Kurzynski                                              << objectPath;
1142656ec7e3SZbigniew Kurzynski                             messages::internalError(asyncResp->res);
1143656ec7e3SZbigniew Kurzynski                             return;
1144656ec7e3SZbigniew Kurzynski                         }
114537cce918SMarri Devender Rao                         std::string certURL =
114637cce918SMarri Devender Rao                             "/redfish/v1/AccountService/LDAP/Certificates/" +
114737cce918SMarri Devender Rao                             std::to_string(certId);
114837cce918SMarri Devender Rao                         getCertificateProperties(asyncResp, objectPath,
114937cce918SMarri Devender Rao                                                  certs::ldapServiceName, certId,
115037cce918SMarri Devender Rao                                                  certURL, "LDAP Certificate");
115137cce918SMarri Devender Rao                         BMCWEB_LOG_DEBUG << "LDAP certificate install file="
115237cce918SMarri Devender Rao                                          << certFile->getCertFilePath();
115337cce918SMarri Devender Rao                     },
115437cce918SMarri Devender Rao                     certs::ldapServiceName, certs::ldapObjectPath,
11557e860f15SJohn Edward Broadbent                     certs::certInstallIntf, "Install",
11567e860f15SJohn Edward Broadbent                     certFile->getCertFilePath());
11577e860f15SJohn Edward Broadbent             });
11587e860f15SJohn Edward Broadbent } // requestRoutesLDAPCertificateCollection
115937cce918SMarri Devender Rao 
116037cce918SMarri Devender Rao /**
116137cce918SMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
116237cce918SMarri Devender Rao  * of a component, account or service.
116337cce918SMarri Devender Rao  */
11647e860f15SJohn Edward Broadbent inline void requestRoutesLDAPCertificate(App& app)
116537cce918SMarri Devender Rao {
11667e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
1167ed398213SEd Tanous         .privileges(redfish::privileges::getCertificate)
11687e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
116945ca1b86SEd Tanous             [&app](const crow::Request& req,
11707e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11717e860f15SJohn Edward Broadbent                    const std::string&) {
117245ca1b86SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
117345ca1b86SEd Tanous                 {
117445ca1b86SEd Tanous                     return;
117545ca1b86SEd Tanous                 }
117637cce918SMarri Devender Rao                 long id = getIDFromURL(req.url);
117737cce918SMarri Devender Rao                 if (id < 0)
117837cce918SMarri Devender Rao                 {
117937cce918SMarri Devender Rao                     BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
118037cce918SMarri Devender Rao                     messages::internalError(asyncResp->res);
118137cce918SMarri Devender Rao                     return;
118237cce918SMarri Devender Rao                 }
11837e860f15SJohn Edward Broadbent                 BMCWEB_LOG_DEBUG << "LDAP Certificate ID="
11847e860f15SJohn Edward Broadbent                                  << std::to_string(id);
11857e860f15SJohn Edward Broadbent                 std::string certURL =
11867e860f15SJohn Edward Broadbent                     "/redfish/v1/AccountService/LDAP/Certificates/" +
118737cce918SMarri Devender Rao                     std::to_string(id);
118837cce918SMarri Devender Rao                 std::string objectPath = certs::ldapObjectPath;
118937cce918SMarri Devender Rao                 objectPath += "/";
119037cce918SMarri Devender Rao                 objectPath += std::to_string(id);
11917e860f15SJohn Edward Broadbent                 getCertificateProperties(asyncResp, objectPath,
11927e860f15SJohn Edward Broadbent                                          certs::ldapServiceName, id, certURL,
11937e860f15SJohn Edward Broadbent                                          "LDAP Certificate");
11947e860f15SJohn Edward Broadbent             });
11957e860f15SJohn Edward Broadbent } // requestRoutesLDAPCertificate
1196cfcd5f6bSMarri Devender Rao /**
1197cfcd5f6bSMarri Devender Rao  * Collection of TrustStoreCertificate certificates
1198cfcd5f6bSMarri Devender Rao  */
11997e860f15SJohn Edward Broadbent inline void requestRoutesTrustStoreCertificateCollection(App& app)
1200cfcd5f6bSMarri Devender Rao {
12017e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
1202ed398213SEd Tanous         .privileges(redfish::privileges::getCertificate)
120345ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)([&app](const crow::Request& req,
120445ca1b86SEd Tanous                                                        const std::shared_ptr<
120545ca1b86SEd Tanous                                                            bmcweb::AsyncResp>&
120645ca1b86SEd Tanous                                                            asyncResp) {
120745ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
120845ca1b86SEd Tanous             {
120945ca1b86SEd Tanous                 return;
121045ca1b86SEd Tanous             }
1211*1476687dSEd Tanous 
1212*1476687dSEd Tanous             asyncResp->res.jsonValue["@odata.id"] =
1213*1476687dSEd Tanous                 "/redfish/v1/Managers/bmc/Truststore/Certificates/";
1214*1476687dSEd Tanous             asyncResp->res.jsonValue["@odata.type"] =
1215*1476687dSEd Tanous                 "#CertificateCollection.CertificateCollection";
1216*1476687dSEd Tanous             asyncResp->res.jsonValue["Name"] =
1217*1476687dSEd Tanous                 "TrustStore Certificates Collection";
1218*1476687dSEd Tanous             asyncResp->res.jsonValue["Description"] =
1219*1476687dSEd Tanous                 "A Collection of TrustStore certificate instances";
12208d1b46d7Szhanghch05 
1221cfcd5f6bSMarri Devender Rao             crow::connections::systemBus->async_method_call(
1222cfcd5f6bSMarri Devender Rao                 [asyncResp](const boost::system::error_code ec,
1223711ac7a9SEd Tanous                             const dbus::utility::ManagedObjectType& certs) {
1224cfcd5f6bSMarri Devender Rao                     if (ec)
1225cfcd5f6bSMarri Devender Rao                     {
1226cfcd5f6bSMarri Devender Rao                         BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
1227cfcd5f6bSMarri Devender Rao                         messages::internalError(asyncResp->res);
1228cfcd5f6bSMarri Devender Rao                         return;
1229cfcd5f6bSMarri Devender Rao                     }
12307e860f15SJohn Edward Broadbent                     nlohmann::json& members =
12317e860f15SJohn Edward Broadbent                         asyncResp->res.jsonValue["Members"];
1232cfcd5f6bSMarri Devender Rao                     members = nlohmann::json::array();
1233cfcd5f6bSMarri Devender Rao                     for (const auto& cert : certs)
1234cfcd5f6bSMarri Devender Rao                     {
1235cfcd5f6bSMarri Devender Rao                         long id = getIDFromURL(cert.first.str);
1236cfcd5f6bSMarri Devender Rao                         if (id >= 0)
1237cfcd5f6bSMarri Devender Rao                         {
1238*1476687dSEd Tanous                             nlohmann::json::object_t member;
1239*1476687dSEd Tanous                             member["@odata.id"] =
12400fda0f12SGeorge Liu                                 "/redfish/v1/Managers/bmc/Truststore/Certificates/" +
1241*1476687dSEd Tanous                                 std::to_string(id);
1242*1476687dSEd Tanous                             members.push_back(std::move(member));
1243cfcd5f6bSMarri Devender Rao                         }
1244cfcd5f6bSMarri Devender Rao                     }
1245cfcd5f6bSMarri Devender Rao                     asyncResp->res.jsonValue["Members@odata.count"] =
1246cfcd5f6bSMarri Devender Rao                         members.size();
1247cfcd5f6bSMarri Devender Rao                 },
1248cfcd5f6bSMarri Devender Rao                 certs::authorityServiceName, certs::authorityObjectPath,
1249cfcd5f6bSMarri Devender Rao                 certs::dbusObjManagerIntf, "GetManagedObjects");
12507e860f15SJohn Edward Broadbent         });
1251cfcd5f6bSMarri Devender Rao 
12527e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
1253ed398213SEd Tanous         .privileges(redfish::privileges::postCertificateCollection)
12540fda0f12SGeorge Liu         .methods(
12550fda0f12SGeorge Liu             boost::beast::http::verb::
125645ca1b86SEd Tanous                 post)([&app](
125745ca1b86SEd Tanous                           const crow::Request& req,
12587e860f15SJohn Edward Broadbent                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
125945ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
126045ca1b86SEd Tanous             {
126145ca1b86SEd Tanous                 return;
126245ca1b86SEd Tanous             }
12637e860f15SJohn Edward Broadbent             std::string certFileBody =
12647e860f15SJohn Edward Broadbent                 getCertificateFromReqBody(asyncResp, req);
1265a08752f5SZbigniew Kurzynski 
1266a08752f5SZbigniew Kurzynski             if (certFileBody.empty())
1267a08752f5SZbigniew Kurzynski             {
12680fda0f12SGeorge Liu                 BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
1269a08752f5SZbigniew Kurzynski                 messages::unrecognizedRequestBody(asyncResp->res);
1270a08752f5SZbigniew Kurzynski                 return;
1271a08752f5SZbigniew Kurzynski             }
1272a08752f5SZbigniew Kurzynski 
1273a08752f5SZbigniew Kurzynski             std::shared_ptr<CertificateFile> certFile =
1274a08752f5SZbigniew Kurzynski                 std::make_shared<CertificateFile>(certFileBody);
1275cfcd5f6bSMarri Devender Rao             crow::connections::systemBus->async_method_call(
1276656ec7e3SZbigniew Kurzynski                 [asyncResp, certFile](const boost::system::error_code ec,
1277656ec7e3SZbigniew Kurzynski                                       const std::string& objectPath) {
1278cfcd5f6bSMarri Devender Rao                     if (ec)
1279cfcd5f6bSMarri Devender Rao                     {
1280cfcd5f6bSMarri Devender Rao                         BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
1281cfcd5f6bSMarri Devender Rao                         messages::internalError(asyncResp->res);
1282cfcd5f6bSMarri Devender Rao                         return;
1283cfcd5f6bSMarri Devender Rao                     }
1284656ec7e3SZbigniew Kurzynski                     long certId = getIDFromURL(objectPath);
1285656ec7e3SZbigniew Kurzynski                     if (certId < 0)
1286656ec7e3SZbigniew Kurzynski                     {
1287656ec7e3SZbigniew Kurzynski                         BMCWEB_LOG_ERROR << "Invalid objectPath value"
1288656ec7e3SZbigniew Kurzynski                                          << objectPath;
1289656ec7e3SZbigniew Kurzynski                         messages::internalError(asyncResp->res);
1290656ec7e3SZbigniew Kurzynski                         return;
1291656ec7e3SZbigniew Kurzynski                     }
12920fda0f12SGeorge Liu                     std::string certURL =
12930fda0f12SGeorge Liu                         "/redfish/v1/Managers/bmc/Truststore/Certificates/" +
1294cfcd5f6bSMarri Devender Rao                         std::to_string(certId);
1295656ec7e3SZbigniew Kurzynski 
12967e860f15SJohn Edward Broadbent                     getCertificateProperties(
12977e860f15SJohn Edward Broadbent                         asyncResp, objectPath, certs::authorityServiceName,
12987e860f15SJohn Edward Broadbent                         certId, certURL, "TrustStore Certificate");
12990fda0f12SGeorge Liu                     BMCWEB_LOG_DEBUG << "TrustStore certificate install file="
1300cfcd5f6bSMarri Devender Rao                                      << certFile->getCertFilePath();
1301cfcd5f6bSMarri Devender Rao                 },
1302cfcd5f6bSMarri Devender Rao                 certs::authorityServiceName, certs::authorityObjectPath,
13030fda0f12SGeorge Liu                 certs::certInstallIntf, "Install", certFile->getCertFilePath());
13047e860f15SJohn Edward Broadbent         });
13057e860f15SJohn Edward Broadbent } // requestRoutesTrustStoreCertificateCollection
1306cfcd5f6bSMarri Devender Rao 
1307cfcd5f6bSMarri Devender Rao /**
1308cfcd5f6bSMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
1309cfcd5f6bSMarri Devender Rao  * of a component, account or service.
1310cfcd5f6bSMarri Devender Rao  */
13117e860f15SJohn Edward Broadbent inline void requestRoutesTrustStoreCertificate(App& app)
1312cfcd5f6bSMarri Devender Rao {
13137e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/")
1314ed398213SEd Tanous         .privileges(redfish::privileges::getCertificate)
13157e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
131645ca1b86SEd Tanous             [&app](const crow::Request& req,
13177e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
13187e860f15SJohn Edward Broadbent                    const std::string&) {
131945ca1b86SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
132045ca1b86SEd Tanous                 {
132145ca1b86SEd Tanous                     return;
132245ca1b86SEd Tanous                 }
1323cfcd5f6bSMarri Devender Rao                 long id = getIDFromURL(req.url);
1324cfcd5f6bSMarri Devender Rao                 if (id < 0)
1325cfcd5f6bSMarri Devender Rao                 {
1326cfcd5f6bSMarri Devender Rao                     BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
1327cfcd5f6bSMarri Devender Rao                     messages::internalError(asyncResp->res);
1328cfcd5f6bSMarri Devender Rao                     return;
1329cfcd5f6bSMarri Devender Rao                 }
1330cfcd5f6bSMarri Devender Rao                 BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doGet ID="
1331cfcd5f6bSMarri Devender Rao                                  << std::to_string(id);
1332cfcd5f6bSMarri Devender Rao                 std::string certURL =
1333cfcd5f6bSMarri Devender Rao                     "/redfish/v1/Managers/bmc/Truststore/Certificates/" +
1334cfcd5f6bSMarri Devender Rao                     std::to_string(id);
1335cfcd5f6bSMarri Devender Rao                 std::string objectPath = certs::authorityObjectPath;
1336cfcd5f6bSMarri Devender Rao                 objectPath += "/";
1337cfcd5f6bSMarri Devender Rao                 objectPath += std::to_string(id);
1338cfcd5f6bSMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath,
13397e860f15SJohn Edward Broadbent                                          certs::authorityServiceName, id,
13407e860f15SJohn Edward Broadbent                                          certURL, "TrustStore Certificate");
13417e860f15SJohn Edward Broadbent             });
134207a60299SZbigniew Kurzynski 
13437e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/")
1344ed398213SEd Tanous         .privileges(redfish::privileges::deleteCertificate)
13457e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::delete_)(
134645ca1b86SEd Tanous             [&app](const crow::Request& req,
13477e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
13487e860f15SJohn Edward Broadbent                    const std::string& param) {
134945ca1b86SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
135045ca1b86SEd Tanous                 {
135145ca1b86SEd Tanous                     return;
135245ca1b86SEd Tanous                 }
13537e860f15SJohn Edward Broadbent                 if (param.empty())
135407a60299SZbigniew Kurzynski                 {
135507a60299SZbigniew Kurzynski                     messages::internalError(asyncResp->res);
135607a60299SZbigniew Kurzynski                     return;
135707a60299SZbigniew Kurzynski                 }
135807a60299SZbigniew Kurzynski 
135907a60299SZbigniew Kurzynski                 long id = getIDFromURL(req.url);
136007a60299SZbigniew Kurzynski                 if (id < 0)
136107a60299SZbigniew Kurzynski                 {
136207a60299SZbigniew Kurzynski                     BMCWEB_LOG_ERROR << "Invalid url value: " << req.url;
13637e860f15SJohn Edward Broadbent                     messages::resourceNotFound(asyncResp->res,
13647e860f15SJohn Edward Broadbent                                                "TrustStore Certificate",
136507a60299SZbigniew Kurzynski                                                std::string(req.url));
136607a60299SZbigniew Kurzynski                     return;
136707a60299SZbigniew Kurzynski                 }
136807a60299SZbigniew Kurzynski                 BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doDelete ID="
136907a60299SZbigniew Kurzynski                                  << std::to_string(id);
137007a60299SZbigniew Kurzynski                 std::string certPath = certs::authorityObjectPath;
137107a60299SZbigniew Kurzynski                 certPath += "/";
137207a60299SZbigniew Kurzynski                 certPath += std::to_string(id);
137307a60299SZbigniew Kurzynski 
137407a60299SZbigniew Kurzynski                 crow::connections::systemBus->async_method_call(
137507a60299SZbigniew Kurzynski                     [asyncResp, id](const boost::system::error_code ec) {
137607a60299SZbigniew Kurzynski                         if (ec)
137707a60299SZbigniew Kurzynski                         {
137807a60299SZbigniew Kurzynski                             messages::resourceNotFound(asyncResp->res,
137907a60299SZbigniew Kurzynski                                                        "TrustStore Certificate",
138007a60299SZbigniew Kurzynski                                                        std::to_string(id));
138107a60299SZbigniew Kurzynski                             return;
138207a60299SZbigniew Kurzynski                         }
138307a60299SZbigniew Kurzynski                         BMCWEB_LOG_INFO << "Certificate deleted";
13847e860f15SJohn Edward Broadbent                         asyncResp->res.result(
13857e860f15SJohn Edward Broadbent                             boost::beast::http::status::no_content);
138607a60299SZbigniew Kurzynski                     },
138707a60299SZbigniew Kurzynski                     certs::authorityServiceName, certPath, certs::objDeleteIntf,
138807a60299SZbigniew Kurzynski                     "Delete");
13897e860f15SJohn Edward Broadbent             });
13907e860f15SJohn Edward Broadbent } // requestRoutesTrustStoreCertificate
13915968caeeSMarri Devender Rao } // namespace redfish
1392