xref: /openbmc/bmcweb/features/redfish/lib/certificate_service.hpp (revision 90d2d1e887e68c70f8e5923eb69c3c9356dae547)
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>
6*90d2d1e8SJiaqing 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             }
578d1b46d7Szhanghch05             asyncResp->res.jsonValue = {
587e860f15SJohn Edward Broadbent                 {"@odata.type",
597e860f15SJohn Edward Broadbent                  "#CertificateService.v1_0_0.CertificateService"},
605968caeeSMarri Devender Rao                 {"@odata.id", "/redfish/v1/CertificateService"},
615968caeeSMarri Devender Rao                 {"Id", "CertificateService"},
625968caeeSMarri Devender Rao                 {"Name", "Certificate Service"},
6372048780SAbhishek Patel                 {"Description", "Actions available to manage certificates"}};
6472048780SAbhishek Patel             // /redfish/v1/CertificateService/CertificateLocations is something
6572048780SAbhishek Patel             // only ConfigureManager can access then only display when the user
6672048780SAbhishek Patel             // has permissions ConfigureManager
6772048780SAbhishek Patel             Privileges effectiveUserPrivileges =
6872048780SAbhishek Patel                 redfish::getUserPrivileges(req.userRole);
6972048780SAbhishek Patel             if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
7072048780SAbhishek Patel                                                  effectiveUserPrivileges))
7172048780SAbhishek Patel             {
728d1b46d7Szhanghch05                 asyncResp->res.jsonValue["CertificateLocations"] = {
735968caeeSMarri Devender Rao                     {"@odata.id",
745968caeeSMarri Devender Rao                      "/redfish/v1/CertificateService/CertificateLocations"}};
7572048780SAbhishek Patel             }
760fda0f12SGeorge Liu             asyncResp->res
770fda0f12SGeorge Liu                 .jsonValue["Actions"]
780fda0f12SGeorge Liu                           ["#CertificateService.ReplaceCertificate"] = {
790fda0f12SGeorge Liu                 {"target",
800fda0f12SGeorge Liu                  "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate"},
815968caeeSMarri Devender Rao                 {"CertificateType@Redfish.AllowableValues", {"PEM"}}};
827e860f15SJohn Edward Broadbent             asyncResp->res
837e860f15SJohn Edward Broadbent                 .jsonValue["Actions"]["#CertificateService.GenerateCSR"] = {
840fda0f12SGeorge Liu                 {"target",
850fda0f12SGeorge Liu                  "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR"}};
867e860f15SJohn Edward Broadbent         });
877e860f15SJohn Edward Broadbent } // requestRoutesCertificateService
8837cce918SMarri Devender Rao 
895968caeeSMarri Devender Rao /**
905968caeeSMarri Devender Rao  * @brief Find the ID specified in the URL
915968caeeSMarri Devender Rao  * Finds the numbers specified after the last "/" in the URL and returns.
925968caeeSMarri Devender Rao  * @param[in] path URL
935968caeeSMarri Devender Rao  * @return -1 on failure and number on success
945968caeeSMarri Devender Rao  */
9523a21a1cSEd Tanous inline long getIDFromURL(const std::string_view url)
965968caeeSMarri Devender Rao {
97f23b7296SEd Tanous     std::size_t found = url.rfind('/');
985968caeeSMarri Devender Rao     if (found == std::string::npos)
995968caeeSMarri Devender Rao     {
1005968caeeSMarri Devender Rao         return -1;
1015968caeeSMarri Devender Rao     }
102e6604b11SIwona Klimaszewska 
1035968caeeSMarri Devender Rao     if ((found + 1) < url.length())
1045968caeeSMarri Devender Rao     {
1055968caeeSMarri Devender Rao         std::string_view str = url.substr(found + 1);
106e6604b11SIwona Klimaszewska 
107e6604b11SIwona Klimaszewska         return boost::convert<long>(str, boost::cnv::strtol()).value_or(-1);
1085968caeeSMarri Devender Rao     }
109e6604b11SIwona Klimaszewska 
1105968caeeSMarri Devender Rao     return -1;
1115968caeeSMarri Devender Rao }
1125968caeeSMarri Devender Rao 
1138d1b46d7Szhanghch05 inline std::string getCertificateFromReqBody(
1148d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11558eb238fSKowalski, Kamil     const crow::Request& req)
11658eb238fSKowalski, Kamil {
11758eb238fSKowalski, Kamil     nlohmann::json reqJson = nlohmann::json::parse(req.body, nullptr, false);
11858eb238fSKowalski, Kamil 
11958eb238fSKowalski, Kamil     if (reqJson.is_discarded())
12058eb238fSKowalski, Kamil     {
12158eb238fSKowalski, Kamil         // We did not receive JSON request, proceed as it is RAW data
12258eb238fSKowalski, Kamil         return req.body;
12358eb238fSKowalski, Kamil     }
12458eb238fSKowalski, Kamil 
12558eb238fSKowalski, Kamil     std::string certificate;
12658eb238fSKowalski, Kamil     std::optional<std::string> certificateType = "PEM";
12758eb238fSKowalski, Kamil 
12815ed6780SWilly Tu     if (!json_util::readJsonPatch(req, asyncResp->res, "CertificateString",
12915ed6780SWilly Tu                                   certificate, "CertificateType",
13015ed6780SWilly Tu                                   certificateType))
13158eb238fSKowalski, Kamil     {
13258eb238fSKowalski, Kamil         BMCWEB_LOG_ERROR << "Required parameters are missing";
13358eb238fSKowalski, Kamil         messages::internalError(asyncResp->res);
134abb93cddSEd Tanous         return {};
13558eb238fSKowalski, Kamil     }
13658eb238fSKowalski, Kamil 
13758eb238fSKowalski, Kamil     if (*certificateType != "PEM")
13858eb238fSKowalski, Kamil     {
13958eb238fSKowalski, Kamil         messages::propertyValueNotInList(asyncResp->res, *certificateType,
14058eb238fSKowalski, Kamil                                          "CertificateType");
141abb93cddSEd Tanous         return {};
14258eb238fSKowalski, Kamil     }
14358eb238fSKowalski, Kamil 
14458eb238fSKowalski, Kamil     return certificate;
14558eb238fSKowalski, Kamil }
14658eb238fSKowalski, Kamil 
1475968caeeSMarri Devender Rao /**
1485968caeeSMarri Devender Rao  * Class to create a temporary certificate file for uploading to system
1495968caeeSMarri Devender Rao  */
1505968caeeSMarri Devender Rao class CertificateFile
1515968caeeSMarri Devender Rao {
1525968caeeSMarri Devender Rao   public:
1535968caeeSMarri Devender Rao     CertificateFile() = delete;
1545968caeeSMarri Devender Rao     CertificateFile(const CertificateFile&) = delete;
1555968caeeSMarri Devender Rao     CertificateFile& operator=(const CertificateFile&) = delete;
1565968caeeSMarri Devender Rao     CertificateFile(CertificateFile&&) = delete;
1575968caeeSMarri Devender Rao     CertificateFile& operator=(CertificateFile&&) = delete;
1585968caeeSMarri Devender Rao     CertificateFile(const std::string& certString)
1595968caeeSMarri Devender Rao     {
16072d52d25SEd Tanous         std::array<char, 18> dirTemplate = {'/', 't', 'm', 'p', '/', 'C',
1615207438cSEd Tanous                                             'e', 'r', 't', 's', '.', 'X',
1625207438cSEd Tanous                                             'X', 'X', 'X', 'X', 'X', '\0'};
1635207438cSEd Tanous         char* tempDirectory = mkdtemp(dirTemplate.data());
164e662eae8SEd Tanous         if (tempDirectory != nullptr)
1655968caeeSMarri Devender Rao         {
1665968caeeSMarri Devender Rao             certDirectory = tempDirectory;
1675968caeeSMarri Devender Rao             certificateFile = certDirectory / "cert.pem";
1685968caeeSMarri Devender Rao             std::ofstream out(certificateFile, std::ofstream::out |
1695968caeeSMarri Devender Rao                                                    std::ofstream::binary |
1705968caeeSMarri Devender Rao                                                    std::ofstream::trunc);
1715968caeeSMarri Devender Rao             out << certString;
1725968caeeSMarri Devender Rao             out.close();
1738cc8edecSEd Tanous             BMCWEB_LOG_DEBUG << "Creating certificate file"
1748cc8edecSEd Tanous                              << certificateFile.string();
1755968caeeSMarri Devender Rao         }
1765968caeeSMarri Devender Rao     }
1775968caeeSMarri Devender Rao     ~CertificateFile()
1785968caeeSMarri Devender Rao     {
1795968caeeSMarri Devender Rao         if (std::filesystem::exists(certDirectory))
1805968caeeSMarri Devender Rao         {
1818cc8edecSEd Tanous             BMCWEB_LOG_DEBUG << "Removing certificate file"
1828cc8edecSEd Tanous                              << certificateFile.string();
18323a21a1cSEd Tanous             std::error_code ec;
18423a21a1cSEd Tanous             std::filesystem::remove_all(certDirectory, ec);
18523a21a1cSEd Tanous             if (ec)
1865968caeeSMarri Devender Rao             {
1875968caeeSMarri Devender Rao                 BMCWEB_LOG_ERROR << "Failed to remove temp directory"
1888cc8edecSEd Tanous                                  << certDirectory.string();
1895968caeeSMarri Devender Rao             }
1905968caeeSMarri Devender Rao         }
1915968caeeSMarri Devender Rao     }
1925968caeeSMarri Devender Rao     std::string getCertFilePath()
1935968caeeSMarri Devender Rao     {
1945968caeeSMarri Devender Rao         return certificateFile;
1955968caeeSMarri Devender Rao     }
1965968caeeSMarri Devender Rao 
1975968caeeSMarri Devender Rao   private:
1985968caeeSMarri Devender Rao     std::filesystem::path certificateFile;
1995968caeeSMarri Devender Rao     std::filesystem::path certDirectory;
2005968caeeSMarri Devender Rao };
2015968caeeSMarri Devender Rao 
20230215816SMarri Devender Rao static std::unique_ptr<sdbusplus::bus::match::match> csrMatcher;
20330215816SMarri Devender Rao /**
20430215816SMarri Devender Rao  * @brief Read data from CSR D-bus object and set to response
20530215816SMarri Devender Rao  *
20630215816SMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
20730215816SMarri Devender Rao  * @param[in] certURI Link to certifiate collection URI
20830215816SMarri Devender Rao  * @param[in] service D-Bus service name
20930215816SMarri Devender Rao  * @param[in] certObjPath certificate D-Bus object path
21030215816SMarri Devender Rao  * @param[in] csrObjPath CSR D-Bus object path
21130215816SMarri Devender Rao  * @return None
21230215816SMarri Devender Rao  */
2138d1b46d7Szhanghch05 static void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
21430215816SMarri Devender Rao                    const std::string& certURI, const std::string& service,
21530215816SMarri Devender Rao                    const std::string& certObjPath,
21630215816SMarri Devender Rao                    const std::string& csrObjPath)
21730215816SMarri Devender Rao {
21830215816SMarri Devender Rao     BMCWEB_LOG_DEBUG << "getCSR CertObjectPath" << certObjPath
21930215816SMarri Devender Rao                      << " CSRObjectPath=" << csrObjPath
22030215816SMarri Devender Rao                      << " service=" << service;
22130215816SMarri Devender Rao     crow::connections::systemBus->async_method_call(
22230215816SMarri Devender Rao         [asyncResp, certURI](const boost::system::error_code ec,
22330215816SMarri Devender Rao                              const std::string& csr) {
22430215816SMarri Devender Rao             if (ec)
22530215816SMarri Devender Rao             {
22630215816SMarri Devender Rao                 BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
22730215816SMarri Devender Rao                 messages::internalError(asyncResp->res);
22830215816SMarri Devender Rao                 return;
22930215816SMarri Devender Rao             }
23030215816SMarri Devender Rao             if (csr.empty())
23130215816SMarri Devender Rao             {
23230215816SMarri Devender Rao                 BMCWEB_LOG_ERROR << "CSR read is empty";
23330215816SMarri Devender Rao                 messages::internalError(asyncResp->res);
23430215816SMarri Devender Rao                 return;
23530215816SMarri Devender Rao             }
23630215816SMarri Devender Rao             asyncResp->res.jsonValue["CSRString"] = csr;
23730215816SMarri Devender Rao             asyncResp->res.jsonValue["CertificateCollection"] = {
23830215816SMarri Devender Rao                 {"@odata.id", certURI}};
23930215816SMarri Devender Rao         },
24030215816SMarri Devender Rao         service, csrObjPath, "xyz.openbmc_project.Certs.CSR", "CSR");
24130215816SMarri Devender Rao }
24230215816SMarri Devender Rao 
24330215816SMarri Devender Rao /**
24430215816SMarri Devender Rao  * Action to Generate CSR
24530215816SMarri Devender Rao  */
2467e860f15SJohn Edward Broadbent inline void requestRoutesCertificateActionGenerateCSR(App& app)
24730215816SMarri Devender Rao {
2480fda0f12SGeorge Liu     BMCWEB_ROUTE(
2490fda0f12SGeorge Liu         app,
2500fda0f12SGeorge Liu         "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR/")
251ed398213SEd Tanous         // Incorrect Privilege;  Should be ConfigureManager
252ed398213SEd Tanous         //.privileges(redfish::privileges::postCertificateService)
253432a890cSEd Tanous         .privileges({{"ConfigureComponents"}})
2540fda0f12SGeorge Liu         .methods(
2550fda0f12SGeorge Liu             boost::beast::http::verb::
25645ca1b86SEd Tanous                 post)([&app](
25745ca1b86SEd Tanous                           const crow::Request& req,
2587e860f15SJohn Edward Broadbent                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
25945ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
26045ca1b86SEd Tanous             {
26145ca1b86SEd Tanous                 return;
26245ca1b86SEd Tanous             }
2632c70f800SEd Tanous             static const int rsaKeyBitLength = 2048;
2648d1b46d7Szhanghch05 
26530215816SMarri Devender Rao             // Required parameters
26630215816SMarri Devender Rao             std::string city;
26730215816SMarri Devender Rao             std::string commonName;
26830215816SMarri Devender Rao             std::string country;
26930215816SMarri Devender Rao             std::string organization;
27030215816SMarri Devender Rao             std::string organizationalUnit;
27130215816SMarri Devender Rao             std::string state;
27230215816SMarri Devender Rao             nlohmann::json certificateCollection;
27330215816SMarri Devender Rao 
27430215816SMarri Devender Rao             // Optional parameters
27530215816SMarri Devender Rao             std::optional<std::vector<std::string>> optAlternativeNames =
27630215816SMarri Devender Rao                 std::vector<std::string>();
27730215816SMarri Devender Rao             std::optional<std::string> optContactPerson = "";
27830215816SMarri Devender Rao             std::optional<std::string> optChallengePassword = "";
27930215816SMarri Devender Rao             std::optional<std::string> optEmail = "";
28030215816SMarri Devender Rao             std::optional<std::string> optGivenName = "";
28130215816SMarri Devender Rao             std::optional<std::string> optInitials = "";
2822c70f800SEd Tanous             std::optional<int64_t> optKeyBitLength = rsaKeyBitLength;
283aaf3206fSVernon Mauery             std::optional<std::string> optKeyCurveId = "secp384r1";
28430215816SMarri Devender Rao             std::optional<std::string> optKeyPairAlgorithm = "EC";
28530215816SMarri Devender Rao             std::optional<std::vector<std::string>> optKeyUsage =
28630215816SMarri Devender Rao                 std::vector<std::string>();
28730215816SMarri Devender Rao             std::optional<std::string> optSurname = "";
28830215816SMarri Devender Rao             std::optional<std::string> optUnstructuredName = "";
28915ed6780SWilly Tu             if (!json_util::readJsonAction(
2900fda0f12SGeorge Liu                     req, asyncResp->res, "City", city, "CommonName", commonName,
2910fda0f12SGeorge Liu                     "ContactPerson", optContactPerson, "Country", country,
2920fda0f12SGeorge Liu                     "Organization", organization, "OrganizationalUnit",
2930fda0f12SGeorge Liu                     organizationalUnit, "State", state, "CertificateCollection",
2940fda0f12SGeorge Liu                     certificateCollection, "AlternativeNames",
2950fda0f12SGeorge Liu                     optAlternativeNames, "ChallengePassword",
2960fda0f12SGeorge Liu                     optChallengePassword, "Email", optEmail, "GivenName",
2970fda0f12SGeorge Liu                     optGivenName, "Initials", optInitials, "KeyBitLength",
2980fda0f12SGeorge Liu                     optKeyBitLength, "KeyCurveId", optKeyCurveId,
2990fda0f12SGeorge Liu                     "KeyPairAlgorithm", optKeyPairAlgorithm, "KeyUsage",
3000fda0f12SGeorge Liu                     optKeyUsage, "Surname", optSurname, "UnstructuredName",
3010fda0f12SGeorge Liu                     optUnstructuredName))
30230215816SMarri Devender Rao             {
30330215816SMarri Devender Rao                 return;
30430215816SMarri Devender Rao             }
30530215816SMarri Devender Rao 
30630215816SMarri Devender Rao             // bmcweb has no way to store or decode a private key challenge
3077e860f15SJohn Edward Broadbent             // password, which will likely cause bmcweb to crash on startup
3087e860f15SJohn Edward Broadbent             // if this is not set on a post so not allowing the user to set
3097e860f15SJohn Edward Broadbent             // value
31026f6976fSEd Tanous             if (!optChallengePassword->empty())
31130215816SMarri Devender Rao             {
3127e860f15SJohn Edward Broadbent                 messages::actionParameterNotSupported(
3137e860f15SJohn Edward Broadbent                     asyncResp->res, "GenerateCSR", "ChallengePassword");
31430215816SMarri Devender Rao                 return;
31530215816SMarri Devender Rao             }
31630215816SMarri Devender Rao 
31730215816SMarri Devender Rao             std::string certURI;
3187e860f15SJohn Edward Broadbent             if (!redfish::json_util::readJson(certificateCollection,
3197e860f15SJohn Edward Broadbent                                               asyncResp->res, "@odata.id",
3207e860f15SJohn Edward Broadbent                                               certURI))
32130215816SMarri Devender Rao             {
32230215816SMarri Devender Rao                 return;
32330215816SMarri Devender Rao             }
32430215816SMarri Devender Rao 
32530215816SMarri Devender Rao             std::string objectPath;
32630215816SMarri Devender Rao             std::string service;
3270fda0f12SGeorge Liu             if (boost::starts_with(
3280fda0f12SGeorge Liu                     certURI,
3290fda0f12SGeorge Liu                     "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
33030215816SMarri Devender Rao             {
33130215816SMarri Devender Rao                 objectPath = certs::httpsObjectPath;
33230215816SMarri Devender Rao                 service = certs::httpsServiceName;
33330215816SMarri Devender Rao             }
3343b7f0149SMarri Devender Rao             else if (boost::starts_with(
3357e860f15SJohn Edward Broadbent                          certURI,
3367e860f15SJohn Edward Broadbent                          "/redfish/v1/AccountService/LDAP/Certificates"))
3373b7f0149SMarri Devender Rao             {
3383b7f0149SMarri Devender Rao                 objectPath = certs::ldapObjectPath;
3393b7f0149SMarri Devender Rao                 service = certs::ldapServiceName;
3403b7f0149SMarri Devender Rao             }
34130215816SMarri Devender Rao             else
34230215816SMarri Devender Rao             {
34330215816SMarri Devender Rao                 messages::actionParameterNotSupported(
34430215816SMarri Devender Rao                     asyncResp->res, "CertificateCollection", "GenerateCSR");
34530215816SMarri Devender Rao                 return;
34630215816SMarri Devender Rao             }
34730215816SMarri Devender Rao 
34830215816SMarri Devender Rao             // supporting only EC and RSA algorithm
3490fda0f12SGeorge Liu             if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
35030215816SMarri Devender Rao             {
35130215816SMarri Devender Rao                 messages::actionParameterNotSupported(
35230215816SMarri Devender Rao                     asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
35330215816SMarri Devender Rao                 return;
35430215816SMarri Devender Rao             }
35530215816SMarri Devender Rao 
3567e860f15SJohn Edward Broadbent             // supporting only 2048 key bit length for RSA algorithm due to
3577e860f15SJohn Edward Broadbent             // time consumed in generating private key
35830215816SMarri Devender Rao             if (*optKeyPairAlgorithm == "RSA" &&
3592c70f800SEd Tanous                 *optKeyBitLength != rsaKeyBitLength)
36030215816SMarri Devender Rao             {
3617e860f15SJohn Edward Broadbent                 messages::propertyValueNotInList(
3627e860f15SJohn Edward Broadbent                     asyncResp->res, std::to_string(*optKeyBitLength),
36330215816SMarri Devender Rao                     "KeyBitLength");
36430215816SMarri Devender Rao                 return;
36530215816SMarri Devender Rao             }
36630215816SMarri Devender Rao 
36730215816SMarri Devender Rao             // validate KeyUsage supporting only 1 type based on URL
3680fda0f12SGeorge Liu             if (boost::starts_with(
3690fda0f12SGeorge Liu                     certURI,
3700fda0f12SGeorge Liu                     "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
37130215816SMarri Devender Rao             {
37226f6976fSEd Tanous                 if (optKeyUsage->empty())
37330215816SMarri Devender Rao                 {
37430215816SMarri Devender Rao                     optKeyUsage->push_back("ServerAuthentication");
37530215816SMarri Devender Rao                 }
37630215816SMarri Devender Rao                 else if (optKeyUsage->size() == 1)
37730215816SMarri Devender Rao                 {
37830215816SMarri Devender Rao                     if ((*optKeyUsage)[0] != "ServerAuthentication")
37930215816SMarri Devender Rao                     {
38030215816SMarri Devender Rao                         messages::propertyValueNotInList(
38130215816SMarri Devender Rao                             asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
38230215816SMarri Devender Rao                         return;
38330215816SMarri Devender Rao                     }
38430215816SMarri Devender Rao                 }
38530215816SMarri Devender Rao                 else
38630215816SMarri Devender Rao                 {
38730215816SMarri Devender Rao                     messages::actionParameterNotSupported(
38830215816SMarri Devender Rao                         asyncResp->res, "KeyUsage", "GenerateCSR");
38930215816SMarri Devender Rao                     return;
39030215816SMarri Devender Rao                 }
39130215816SMarri Devender Rao             }
3923b7f0149SMarri Devender Rao             else if (boost::starts_with(
3937e860f15SJohn Edward Broadbent                          certURI,
3947e860f15SJohn Edward Broadbent                          "/redfish/v1/AccountService/LDAP/Certificates"))
3953b7f0149SMarri Devender Rao             {
39626f6976fSEd Tanous                 if (optKeyUsage->empty())
3973b7f0149SMarri Devender Rao                 {
3983b7f0149SMarri Devender Rao                     optKeyUsage->push_back("ClientAuthentication");
3993b7f0149SMarri Devender Rao                 }
4003b7f0149SMarri Devender Rao                 else if (optKeyUsage->size() == 1)
4013b7f0149SMarri Devender Rao                 {
4023b7f0149SMarri Devender Rao                     if ((*optKeyUsage)[0] != "ClientAuthentication")
4033b7f0149SMarri Devender Rao                     {
4043b7f0149SMarri Devender Rao                         messages::propertyValueNotInList(
4053b7f0149SMarri Devender Rao                             asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
4063b7f0149SMarri Devender Rao                         return;
4073b7f0149SMarri Devender Rao                     }
4083b7f0149SMarri Devender Rao                 }
4093b7f0149SMarri Devender Rao                 else
4103b7f0149SMarri Devender Rao                 {
4113b7f0149SMarri Devender Rao                     messages::actionParameterNotSupported(
4123b7f0149SMarri Devender Rao                         asyncResp->res, "KeyUsage", "GenerateCSR");
4133b7f0149SMarri Devender Rao                     return;
4143b7f0149SMarri Devender Rao                 }
4153b7f0149SMarri Devender Rao             }
41630215816SMarri Devender Rao 
4177e860f15SJohn Edward Broadbent             // Only allow one CSR matcher at a time so setting retry
4187e860f15SJohn Edward Broadbent             // time-out and timer expiry to 10 seconds for now.
4192c70f800SEd Tanous             static const int timeOut = 10;
42030215816SMarri Devender Rao             if (csrMatcher)
42130215816SMarri Devender Rao             {
4227e860f15SJohn Edward Broadbent                 messages::serviceTemporarilyUnavailable(
4237e860f15SJohn Edward Broadbent                     asyncResp->res, std::to_string(timeOut));
42430215816SMarri Devender Rao                 return;
42530215816SMarri Devender Rao             }
42630215816SMarri Devender Rao 
42730215816SMarri Devender Rao             // Make this static so it survives outside this method
42830215816SMarri Devender Rao             static boost::asio::steady_timer timeout(*req.ioService);
4292c70f800SEd Tanous             timeout.expires_after(std::chrono::seconds(timeOut));
4300fda0f12SGeorge Liu             timeout.async_wait(
4310fda0f12SGeorge Liu                 [asyncResp](const boost::system::error_code& ec) {
43230215816SMarri Devender Rao                     csrMatcher = nullptr;
43330215816SMarri Devender Rao                     if (ec)
43430215816SMarri Devender Rao                     {
4357e860f15SJohn Edward Broadbent                         // operation_aborted is expected if timer is canceled
4367e860f15SJohn Edward Broadbent                         // before completion.
43730215816SMarri Devender Rao                         if (ec != boost::asio::error::operation_aborted)
43830215816SMarri Devender Rao                         {
43930215816SMarri Devender Rao                             BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
44030215816SMarri Devender Rao                         }
44130215816SMarri Devender Rao                         return;
44230215816SMarri Devender Rao                     }
44330215816SMarri Devender Rao                     BMCWEB_LOG_ERROR << "Timed out waiting for Generating CSR";
44430215816SMarri Devender Rao                     messages::internalError(asyncResp->res);
44530215816SMarri Devender Rao                 });
44630215816SMarri Devender Rao 
44730215816SMarri Devender Rao             // create a matcher to wait on CSR object
44830215816SMarri Devender Rao             BMCWEB_LOG_DEBUG << "create matcher with path " << objectPath;
4490fda0f12SGeorge Liu             std::string match("type='signal',"
45030215816SMarri Devender Rao                               "interface='org.freedesktop.DBus.ObjectManager',"
45130215816SMarri Devender Rao                               "path='" +
45230215816SMarri Devender Rao                               objectPath +
45330215816SMarri Devender Rao                               "',"
45430215816SMarri Devender Rao                               "member='InterfacesAdded'");
45530215816SMarri Devender Rao             csrMatcher = std::make_unique<sdbusplus::bus::match::match>(
45630215816SMarri Devender Rao                 *crow::connections::systemBus, match,
45730215816SMarri Devender Rao                 [asyncResp, service, objectPath,
45830215816SMarri Devender Rao                  certURI](sdbusplus::message::message& m) {
459271584abSEd Tanous                     timeout.cancel();
46030215816SMarri Devender Rao                     if (m.is_method_error())
46130215816SMarri Devender Rao                     {
46230215816SMarri Devender Rao                         BMCWEB_LOG_ERROR << "Dbus method error!!!";
46330215816SMarri Devender Rao                         messages::internalError(asyncResp->res);
46430215816SMarri Devender Rao                         return;
46530215816SMarri Devender Rao                     }
466b9d36b47SEd Tanous 
467b9d36b47SEd Tanous                     dbus::utility::DBusInteracesMap interfacesProperties;
468b9d36b47SEd Tanous 
46930215816SMarri Devender Rao                     sdbusplus::message::object_path csrObjectPath;
47030215816SMarri Devender Rao                     m.read(csrObjectPath, interfacesProperties);
4710fda0f12SGeorge Liu                     BMCWEB_LOG_DEBUG << "CSR object added" << csrObjectPath.str;
47230215816SMarri Devender Rao                     for (auto& interface : interfacesProperties)
47330215816SMarri Devender Rao                     {
4740fda0f12SGeorge Liu                         if (interface.first == "xyz.openbmc_project.Certs.CSR")
47530215816SMarri Devender Rao                         {
47630215816SMarri Devender Rao                             getCSR(asyncResp, certURI, service, objectPath,
47730215816SMarri Devender Rao                                    csrObjectPath.str);
47830215816SMarri Devender Rao                             break;
47930215816SMarri Devender Rao                         }
48030215816SMarri Devender Rao                     }
48130215816SMarri Devender Rao                 });
48230215816SMarri Devender Rao             crow::connections::systemBus->async_method_call(
483914e2d5dSEd Tanous                 [asyncResp](const boost::system::error_code ec,
484cb13a392SEd Tanous                             const std::string&) {
48530215816SMarri Devender Rao                     if (ec)
48630215816SMarri Devender Rao                     {
4877e860f15SJohn Edward Broadbent                         BMCWEB_LOG_ERROR << "DBUS response error: "
4887e860f15SJohn Edward Broadbent                                          << ec.message();
48930215816SMarri Devender Rao                         messages::internalError(asyncResp->res);
49030215816SMarri Devender Rao                         return;
49130215816SMarri Devender Rao                     }
49230215816SMarri Devender Rao                 },
49330215816SMarri Devender Rao                 service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
4947e860f15SJohn Edward Broadbent                 "GenerateCSR", *optAlternativeNames, *optChallengePassword,
4957e860f15SJohn Edward Broadbent                 city, commonName, *optContactPerson, country, *optEmail,
4960fda0f12SGeorge Liu                 *optGivenName, *optInitials, *optKeyBitLength, *optKeyCurveId,
4970fda0f12SGeorge Liu                 *optKeyPairAlgorithm, *optKeyUsage, organization,
4980fda0f12SGeorge Liu                 organizationalUnit, state, *optSurname, *optUnstructuredName);
4997e860f15SJohn Edward Broadbent         });
5007e860f15SJohn Edward Broadbent } // requestRoutesCertificateActionGenerateCSR
50130215816SMarri Devender Rao 
5025968caeeSMarri Devender Rao /**
5034e0453b1SGunnar Mills  * @brief Parse and update Certificate Issue/Subject property
5045968caeeSMarri Devender Rao  *
5055968caeeSMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
5065968caeeSMarri Devender Rao  * @param[in] str  Issuer/Subject value in key=value pairs
5075968caeeSMarri Devender Rao  * @param[in] type Issuer/Subject
5085968caeeSMarri Devender Rao  * @return None
5095968caeeSMarri Devender Rao  */
5105968caeeSMarri Devender Rao static void updateCertIssuerOrSubject(nlohmann::json& out,
5115968caeeSMarri Devender Rao                                       const std::string_view value)
5125968caeeSMarri Devender Rao {
5135968caeeSMarri Devender Rao     // example: O=openbmc-project.xyz,CN=localhost
5145968caeeSMarri Devender Rao     std::string_view::iterator i = value.begin();
5155968caeeSMarri Devender Rao     while (i != value.end())
5165968caeeSMarri Devender Rao     {
5175968caeeSMarri Devender Rao         std::string_view::iterator tokenBegin = i;
5185968caeeSMarri Devender Rao         while (i != value.end() && *i != '=')
5195968caeeSMarri Devender Rao         {
52017a897dfSManojkiran Eda             ++i;
5215968caeeSMarri Devender Rao         }
5225968caeeSMarri Devender Rao         if (i == value.end())
5235968caeeSMarri Devender Rao         {
5245968caeeSMarri Devender Rao             break;
5255968caeeSMarri Devender Rao         }
526271584abSEd Tanous         const std::string_view key(tokenBegin,
527271584abSEd Tanous                                    static_cast<size_t>(i - tokenBegin));
52817a897dfSManojkiran Eda         ++i;
5295968caeeSMarri Devender Rao         tokenBegin = i;
5305968caeeSMarri Devender Rao         while (i != value.end() && *i != ',')
5315968caeeSMarri Devender Rao         {
53217a897dfSManojkiran Eda             ++i;
5335968caeeSMarri Devender Rao         }
534271584abSEd Tanous         const std::string_view val(tokenBegin,
535271584abSEd Tanous                                    static_cast<size_t>(i - tokenBegin));
5365968caeeSMarri Devender Rao         if (key == "L")
5375968caeeSMarri Devender Rao         {
5385968caeeSMarri Devender Rao             out["City"] = val;
5395968caeeSMarri Devender Rao         }
5405968caeeSMarri Devender Rao         else if (key == "CN")
5415968caeeSMarri Devender Rao         {
5425968caeeSMarri Devender Rao             out["CommonName"] = val;
5435968caeeSMarri Devender Rao         }
5445968caeeSMarri Devender Rao         else if (key == "C")
5455968caeeSMarri Devender Rao         {
5465968caeeSMarri Devender Rao             out["Country"] = val;
5475968caeeSMarri Devender Rao         }
5485968caeeSMarri Devender Rao         else if (key == "O")
5495968caeeSMarri Devender Rao         {
5505968caeeSMarri Devender Rao             out["Organization"] = val;
5515968caeeSMarri Devender Rao         }
5525968caeeSMarri Devender Rao         else if (key == "OU")
5535968caeeSMarri Devender Rao         {
5545968caeeSMarri Devender Rao             out["OrganizationalUnit"] = val;
5555968caeeSMarri Devender Rao         }
5565968caeeSMarri Devender Rao         else if (key == "ST")
5575968caeeSMarri Devender Rao         {
5585968caeeSMarri Devender Rao             out["State"] = val;
5595968caeeSMarri Devender Rao         }
5605968caeeSMarri Devender Rao         // skip comma character
5615968caeeSMarri Devender Rao         if (i != value.end())
5625968caeeSMarri Devender Rao         {
56317a897dfSManojkiran Eda             ++i;
5645968caeeSMarri Devender Rao         }
5655968caeeSMarri Devender Rao     }
5665968caeeSMarri Devender Rao }
5675968caeeSMarri Devender Rao 
5685968caeeSMarri Devender Rao /**
5695968caeeSMarri Devender Rao  * @brief Retrieve the certificates properties and append to the response
5705968caeeSMarri Devender Rao  * message
5715968caeeSMarri Devender Rao  *
5725968caeeSMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
5735968caeeSMarri Devender Rao  * @param[in] objectPath  Path of the D-Bus service object
5745968caeeSMarri Devender Rao  * @param[in] certId  Id of the certificate
5755968caeeSMarri Devender Rao  * @param[in] certURL  URL of the certificate object
5765968caeeSMarri Devender Rao  * @param[in] name  name of the certificate
5775968caeeSMarri Devender Rao  * @return None
5785968caeeSMarri Devender Rao  */
5795968caeeSMarri Devender Rao static void getCertificateProperties(
5808d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
5818d1b46d7Szhanghch05     const std::string& objectPath, const std::string& service, long certId,
5828d1b46d7Szhanghch05     const std::string& certURL, const std::string& name)
5835968caeeSMarri Devender Rao {
5845968caeeSMarri Devender Rao     BMCWEB_LOG_DEBUG << "getCertificateProperties Path=" << objectPath
5855968caeeSMarri Devender Rao                      << " certId=" << certId << " certURl=" << certURL;
5865968caeeSMarri Devender Rao     crow::connections::systemBus->async_method_call(
587b9d36b47SEd Tanous         [asyncResp, certURL, certId,
588b9d36b47SEd Tanous          name](const boost::system::error_code ec,
589b9d36b47SEd Tanous                const dbus::utility::DBusPropertiesMap& properties) {
5905968caeeSMarri Devender Rao             if (ec)
5915968caeeSMarri Devender Rao             {
5925968caeeSMarri Devender Rao                 BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
5938aae75adSMarri Devender Rao                 messages::resourceNotFound(asyncResp->res, name,
5948aae75adSMarri Devender Rao                                            std::to_string(certId));
5955968caeeSMarri Devender Rao                 return;
5965968caeeSMarri Devender Rao             }
5975968caeeSMarri Devender Rao             asyncResp->res.jsonValue = {
5985968caeeSMarri Devender Rao                 {"@odata.id", certURL},
5995968caeeSMarri Devender Rao                 {"@odata.type", "#Certificate.v1_0_0.Certificate"},
6005968caeeSMarri Devender Rao                 {"Id", std::to_string(certId)},
6015968caeeSMarri Devender Rao                 {"Name", name},
6025968caeeSMarri Devender Rao                 {"Description", name}};
6035968caeeSMarri Devender Rao             for (const auto& property : properties)
6045968caeeSMarri Devender Rao             {
6055968caeeSMarri Devender Rao                 if (property.first == "CertificateString")
6065968caeeSMarri Devender Rao                 {
6075968caeeSMarri Devender Rao                     asyncResp->res.jsonValue["CertificateString"] = "";
6085968caeeSMarri Devender Rao                     const std::string* value =
6095968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
610e662eae8SEd Tanous                     if (value != nullptr)
6115968caeeSMarri Devender Rao                     {
61237cce918SMarri Devender Rao                         asyncResp->res.jsonValue["CertificateString"] = *value;
6135968caeeSMarri Devender Rao                     }
6145968caeeSMarri Devender Rao                 }
6155968caeeSMarri Devender Rao                 else if (property.first == "KeyUsage")
6165968caeeSMarri Devender Rao                 {
6175968caeeSMarri Devender Rao                     nlohmann::json& keyUsage =
6185968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["KeyUsage"];
6195968caeeSMarri Devender Rao                     keyUsage = nlohmann::json::array();
6205968caeeSMarri Devender Rao                     const std::vector<std::string>* value =
62137cce918SMarri Devender Rao                         std::get_if<std::vector<std::string>>(&property.second);
622e662eae8SEd Tanous                     if (value != nullptr)
6235968caeeSMarri Devender Rao                     {
6245968caeeSMarri Devender Rao                         for (const std::string& usage : *value)
6255968caeeSMarri Devender Rao                         {
6265968caeeSMarri Devender Rao                             keyUsage.push_back(usage);
6275968caeeSMarri Devender Rao                         }
6285968caeeSMarri Devender Rao                     }
6295968caeeSMarri Devender Rao                 }
6305968caeeSMarri Devender Rao                 else if (property.first == "Issuer")
6315968caeeSMarri Devender Rao                 {
6325968caeeSMarri Devender Rao                     const std::string* value =
6335968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
634e662eae8SEd Tanous                     if (value != nullptr)
6355968caeeSMarri Devender Rao                     {
6365968caeeSMarri Devender Rao                         updateCertIssuerOrSubject(
6375968caeeSMarri Devender Rao                             asyncResp->res.jsonValue["Issuer"], *value);
6385968caeeSMarri Devender Rao                     }
6395968caeeSMarri Devender Rao                 }
6405968caeeSMarri Devender Rao                 else if (property.first == "Subject")
6415968caeeSMarri Devender Rao                 {
6425968caeeSMarri Devender Rao                     const std::string* value =
6435968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
644e662eae8SEd Tanous                     if (value != nullptr)
6455968caeeSMarri Devender Rao                     {
6465968caeeSMarri Devender Rao                         updateCertIssuerOrSubject(
64737cce918SMarri Devender Rao                             asyncResp->res.jsonValue["Subject"], *value);
6485968caeeSMarri Devender Rao                     }
6495968caeeSMarri Devender Rao                 }
6505968caeeSMarri Devender Rao                 else if (property.first == "ValidNotAfter")
6515968caeeSMarri Devender Rao                 {
6525968caeeSMarri Devender Rao                     const uint64_t* value =
6535968caeeSMarri Devender Rao                         std::get_if<uint64_t>(&property.second);
654e662eae8SEd Tanous                     if (value != nullptr)
6555968caeeSMarri Devender Rao                     {
6565968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["ValidNotAfter"] =
6571d8782e7SNan Zhou                             crow::utility::getDateTimeUint(*value);
6585968caeeSMarri Devender Rao                     }
6595968caeeSMarri Devender Rao                 }
6605968caeeSMarri Devender Rao                 else if (property.first == "ValidNotBefore")
6615968caeeSMarri Devender Rao                 {
6625968caeeSMarri Devender Rao                     const uint64_t* value =
6635968caeeSMarri Devender Rao                         std::get_if<uint64_t>(&property.second);
664e662eae8SEd Tanous                     if (value != nullptr)
6655968caeeSMarri Devender Rao                     {
6665968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["ValidNotBefore"] =
6671d8782e7SNan Zhou                             crow::utility::getDateTimeUint(*value);
6685968caeeSMarri Devender Rao                     }
6695968caeeSMarri Devender Rao                 }
6705968caeeSMarri Devender Rao             }
6715968caeeSMarri Devender Rao             asyncResp->res.addHeader("Location", certURL);
6725968caeeSMarri Devender Rao         },
6735968caeeSMarri Devender Rao         service, objectPath, certs::dbusPropIntf, "GetAll",
6745968caeeSMarri Devender Rao         certs::certPropIntf);
6755968caeeSMarri Devender Rao }
6765968caeeSMarri Devender Rao 
6775968caeeSMarri Devender Rao /**
6785968caeeSMarri Devender Rao  * Action to replace an existing certificate
6795968caeeSMarri Devender Rao  */
6807e860f15SJohn Edward Broadbent inline void requestRoutesCertificateActionsReplaceCertificate(App& app)
6815968caeeSMarri Devender Rao {
6820fda0f12SGeorge Liu     BMCWEB_ROUTE(
6830fda0f12SGeorge Liu         app,
6840fda0f12SGeorge Liu         "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate/")
685ed398213SEd Tanous         .privileges(redfish::privileges::postCertificateService)
6867e860f15SJohn Edward Broadbent         .methods(
6877e860f15SJohn Edward Broadbent             boost::beast::http::verb::
68845ca1b86SEd Tanous                 post)([&app](
68945ca1b86SEd Tanous                           const crow::Request& req,
6907e860f15SJohn Edward Broadbent                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
69145ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
69245ca1b86SEd Tanous             {
69345ca1b86SEd Tanous                 return;
69445ca1b86SEd Tanous             }
6955968caeeSMarri Devender Rao             std::string certificate;
6965968caeeSMarri Devender Rao             nlohmann::json certificateUri;
6975968caeeSMarri Devender Rao             std::optional<std::string> certificateType = "PEM";
6988d1b46d7Szhanghch05 
69915ed6780SWilly Tu             if (!json_util::readJsonAction(req, asyncResp->res,
70015ed6780SWilly Tu                                            "CertificateString", certificate,
70115ed6780SWilly Tu                                            "CertificateUri", certificateUri,
70215ed6780SWilly Tu                                            "CertificateType", certificateType))
7035968caeeSMarri Devender Rao             {
7045968caeeSMarri Devender Rao                 BMCWEB_LOG_ERROR << "Required parameters are missing";
7055968caeeSMarri Devender Rao                 messages::internalError(asyncResp->res);
7065968caeeSMarri Devender Rao                 return;
7075968caeeSMarri Devender Rao             }
7085968caeeSMarri Devender Rao 
7095968caeeSMarri Devender Rao             if (!certificateType)
7105968caeeSMarri Devender Rao             {
7115968caeeSMarri Devender Rao                 // should never happen, but it never hurts to be paranoid.
7125968caeeSMarri Devender Rao                 return;
7135968caeeSMarri Devender Rao             }
7145968caeeSMarri Devender Rao             if (certificateType != "PEM")
7155968caeeSMarri Devender Rao             {
7165968caeeSMarri Devender Rao                 messages::actionParameterNotSupported(
7175968caeeSMarri Devender Rao                     asyncResp->res, "CertificateType", "ReplaceCertificate");
7185968caeeSMarri Devender Rao                 return;
7195968caeeSMarri Devender Rao             }
7205968caeeSMarri Devender Rao 
7215968caeeSMarri Devender Rao             std::string certURI;
7225968caeeSMarri Devender Rao             if (!redfish::json_util::readJson(certificateUri, asyncResp->res,
7235968caeeSMarri Devender Rao                                               "@odata.id", certURI))
7245968caeeSMarri Devender Rao             {
7255968caeeSMarri Devender Rao                 messages::actionParameterMissing(
7265968caeeSMarri Devender Rao                     asyncResp->res, "ReplaceCertificate", "CertificateUri");
7275968caeeSMarri Devender Rao                 return;
7285968caeeSMarri Devender Rao             }
7295968caeeSMarri Devender Rao 
7305968caeeSMarri Devender Rao             BMCWEB_LOG_INFO << "Certificate URI to replace" << certURI;
7315968caeeSMarri Devender Rao             long id = getIDFromURL(certURI);
7325968caeeSMarri Devender Rao             if (id < 0)
7335968caeeSMarri Devender Rao             {
7347e860f15SJohn Edward Broadbent                 messages::actionParameterValueFormatError(
7357e860f15SJohn Edward Broadbent                     asyncResp->res, certURI, "CertificateUri",
7365968caeeSMarri Devender Rao                     "ReplaceCertificate");
7375968caeeSMarri Devender Rao                 return;
7385968caeeSMarri Devender Rao             }
7395968caeeSMarri Devender Rao             std::string objectPath;
7405968caeeSMarri Devender Rao             std::string name;
74137cce918SMarri Devender Rao             std::string service;
7420fda0f12SGeorge Liu             if (boost::starts_with(
7430fda0f12SGeorge Liu                     certURI,
7440fda0f12SGeorge Liu                     "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/"))
7455968caeeSMarri Devender Rao             {
7467e860f15SJohn Edward Broadbent                 objectPath = std::string(certs::httpsObjectPath) + "/" +
7477e860f15SJohn Edward Broadbent                              std::to_string(id);
7485968caeeSMarri Devender Rao                 name = "HTTPS certificate";
74937cce918SMarri Devender Rao                 service = certs::httpsServiceName;
75037cce918SMarri Devender Rao             }
75137cce918SMarri Devender Rao             else if (boost::starts_with(
7527e860f15SJohn Edward Broadbent                          certURI,
7537e860f15SJohn Edward Broadbent                          "/redfish/v1/AccountService/LDAP/Certificates/"))
75437cce918SMarri Devender Rao             {
7557e860f15SJohn Edward Broadbent                 objectPath = std::string(certs::ldapObjectPath) + "/" +
7567e860f15SJohn Edward Broadbent                              std::to_string(id);
75737cce918SMarri Devender Rao                 name = "LDAP certificate";
75837cce918SMarri Devender Rao                 service = certs::ldapServiceName;
7595968caeeSMarri Devender Rao             }
760cfcd5f6bSMarri Devender Rao             else if (boost::starts_with(
761cfcd5f6bSMarri Devender Rao                          certURI,
762cfcd5f6bSMarri Devender Rao                          "/redfish/v1/Managers/bmc/Truststore/Certificates/"))
763cfcd5f6bSMarri Devender Rao             {
764cfcd5f6bSMarri Devender Rao                 objectPath = std::string(certs::authorityObjectPath) + "/" +
765cfcd5f6bSMarri Devender Rao                              std::to_string(id);
766cfcd5f6bSMarri Devender Rao                 name = "TrustStore certificate";
767cfcd5f6bSMarri Devender Rao                 service = certs::authorityServiceName;
768cfcd5f6bSMarri Devender Rao             }
7695968caeeSMarri Devender Rao             else
7705968caeeSMarri Devender Rao             {
7715968caeeSMarri Devender Rao                 messages::actionParameterNotSupported(
7725968caeeSMarri Devender Rao                     asyncResp->res, "CertificateUri", "ReplaceCertificate");
7735968caeeSMarri Devender Rao                 return;
7745968caeeSMarri Devender Rao             }
7755968caeeSMarri Devender Rao 
7765968caeeSMarri Devender Rao             std::shared_ptr<CertificateFile> certFile =
7775968caeeSMarri Devender Rao                 std::make_shared<CertificateFile>(certificate);
7785968caeeSMarri Devender Rao             crow::connections::systemBus->async_method_call(
77937cce918SMarri Devender Rao                 [asyncResp, certFile, objectPath, service, certURI, id,
7805968caeeSMarri Devender Rao                  name](const boost::system::error_code ec) {
7815968caeeSMarri Devender Rao                     if (ec)
7825968caeeSMarri Devender Rao                     {
7835968caeeSMarri Devender Rao                         BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
784*90d2d1e8SJiaqing Zhao                         if (ec.value() ==
785*90d2d1e8SJiaqing Zhao                             boost::system::linux_error::bad_request_descriptor)
786*90d2d1e8SJiaqing Zhao                         {
7878aae75adSMarri Devender Rao                             messages::resourceNotFound(asyncResp->res, name,
7888aae75adSMarri Devender Rao                                                        std::to_string(id));
7895968caeeSMarri Devender Rao                             return;
7905968caeeSMarri Devender Rao                         }
791*90d2d1e8SJiaqing Zhao                         messages::internalError(asyncResp->res);
792*90d2d1e8SJiaqing Zhao                         return;
793*90d2d1e8SJiaqing Zhao                     }
79437cce918SMarri Devender Rao                     getCertificateProperties(asyncResp, objectPath, service, id,
7955968caeeSMarri Devender Rao                                              certURI, name);
7965968caeeSMarri Devender Rao                     BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
7975968caeeSMarri Devender Rao                                      << certFile->getCertFilePath();
7985968caeeSMarri Devender Rao                 },
7995968caeeSMarri Devender Rao                 service, objectPath, certs::certReplaceIntf, "Replace",
8005968caeeSMarri Devender Rao                 certFile->getCertFilePath());
8017e860f15SJohn Edward Broadbent         });
8027e860f15SJohn Edward Broadbent } // requestRoutesCertificateActionsReplaceCertificate
8035968caeeSMarri Devender Rao 
8045968caeeSMarri Devender Rao /**
8055968caeeSMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
8065968caeeSMarri Devender Rao  * of a component, account or service.
8075968caeeSMarri Devender Rao  */
8085968caeeSMarri Devender Rao 
8097e860f15SJohn Edward Broadbent inline void requestRoutesHTTPSCertificate(App& app)
8105968caeeSMarri Devender Rao {
8117e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
8127e860f15SJohn Edward Broadbent         app,
8137e860f15SJohn Edward Broadbent         "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/<str>/")
814ed398213SEd Tanous         .privileges(redfish::privileges::getCertificate)
8157e860f15SJohn Edward Broadbent         .methods(
8167e860f15SJohn Edward Broadbent             boost::beast::http::verb::
81745ca1b86SEd Tanous                 get)([&app](const crow::Request& req,
8187e860f15SJohn Edward Broadbent                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8197e860f15SJohn Edward Broadbent                             const std::string& param) -> void {
82045ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
82145ca1b86SEd Tanous             {
82245ca1b86SEd Tanous                 return;
82345ca1b86SEd Tanous             }
8247e860f15SJohn Edward Broadbent             if (param.empty())
8255968caeeSMarri Devender Rao             {
8265968caeeSMarri Devender Rao                 messages::internalError(asyncResp->res);
8275968caeeSMarri Devender Rao                 return;
8285968caeeSMarri Devender Rao             }
8295968caeeSMarri Devender Rao             long id = getIDFromURL(req.url);
8305968caeeSMarri Devender Rao 
8317e860f15SJohn Edward Broadbent             BMCWEB_LOG_DEBUG << "HTTPSCertificate::doGet ID="
8327e860f15SJohn Edward Broadbent                              << std::to_string(id);
8335968caeeSMarri Devender Rao             std::string certURL =
8345968caeeSMarri Devender Rao                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" +
8355968caeeSMarri Devender Rao                 std::to_string(id);
8365968caeeSMarri Devender Rao             std::string objectPath = certs::httpsObjectPath;
8375968caeeSMarri Devender Rao             objectPath += "/";
8385968caeeSMarri Devender Rao             objectPath += std::to_string(id);
8397e860f15SJohn Edward Broadbent             getCertificateProperties(asyncResp, objectPath,
8407e860f15SJohn Edward Broadbent                                      certs::httpsServiceName, id, certURL,
8417e860f15SJohn Edward Broadbent                                      "HTTPS Certificate");
8427e860f15SJohn Edward Broadbent         });
8435968caeeSMarri Devender Rao }
8445968caeeSMarri Devender Rao 
8455968caeeSMarri Devender Rao /**
8465968caeeSMarri Devender Rao  * Collection of HTTPS certificates
8475968caeeSMarri Devender Rao  */
8487e860f15SJohn Edward Broadbent inline void requestRoutesHTTPSCertificateCollection(App& app)
8495968caeeSMarri Devender Rao {
8507e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
8515968caeeSMarri Devender Rao                  "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
852ed398213SEd Tanous         .privileges(redfish::privileges::getCertificateCollection)
85345ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)([&app](const crow::Request& req,
85445ca1b86SEd Tanous                                                        const std::shared_ptr<
85545ca1b86SEd Tanous                                                            bmcweb::AsyncResp>&
85645ca1b86SEd Tanous                                                            asyncResp) {
85745ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
85845ca1b86SEd Tanous             {
85945ca1b86SEd Tanous                 return;
86045ca1b86SEd Tanous             }
8618d1b46d7Szhanghch05             asyncResp->res.jsonValue = {
8625968caeeSMarri Devender Rao                 {"@odata.id",
8635968caeeSMarri Devender Rao                  "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"},
8645968caeeSMarri Devender Rao                 {"@odata.type", "#CertificateCollection.CertificateCollection"},
8655968caeeSMarri Devender Rao                 {"Name", "HTTPS Certificates Collection"},
8665968caeeSMarri Devender Rao                 {"Description", "A Collection of HTTPS certificate instances"}};
8678d1b46d7Szhanghch05 
8685968caeeSMarri Devender Rao             crow::connections::systemBus->async_method_call(
8695968caeeSMarri Devender Rao                 [asyncResp](const boost::system::error_code ec,
870711ac7a9SEd Tanous                             const dbus::utility::ManagedObjectType& certs) {
8715968caeeSMarri Devender Rao                     if (ec)
8725968caeeSMarri Devender Rao                     {
8735968caeeSMarri Devender Rao                         BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
8745968caeeSMarri Devender Rao                         messages::internalError(asyncResp->res);
8755968caeeSMarri Devender Rao                         return;
8765968caeeSMarri Devender Rao                     }
8777e860f15SJohn Edward Broadbent                     nlohmann::json& members =
8787e860f15SJohn Edward Broadbent                         asyncResp->res.jsonValue["Members"];
8795968caeeSMarri Devender Rao                     members = nlohmann::json::array();
8805968caeeSMarri Devender Rao                     for (const auto& cert : certs)
8815968caeeSMarri Devender Rao                     {
8825968caeeSMarri Devender Rao                         long id = getIDFromURL(cert.first.str);
88337cce918SMarri Devender Rao                         if (id >= 0)
8845968caeeSMarri Devender Rao                         {
8855968caeeSMarri Devender Rao                             members.push_back(
8865968caeeSMarri Devender Rao                                 {{"@odata.id",
8870fda0f12SGeorge Liu                                   "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" +
8885968caeeSMarri Devender Rao                                       std::to_string(id)}});
8895968caeeSMarri Devender Rao                         }
8905968caeeSMarri Devender Rao                     }
8915968caeeSMarri Devender Rao                     asyncResp->res.jsonValue["Members@odata.count"] =
8925968caeeSMarri Devender Rao                         members.size();
8935968caeeSMarri Devender Rao                 },
89437cce918SMarri Devender Rao                 certs::httpsServiceName, certs::httpsObjectPath,
89537cce918SMarri Devender Rao                 certs::dbusObjManagerIntf, "GetManagedObjects");
8967e860f15SJohn Edward Broadbent         });
8975968caeeSMarri Devender Rao 
8987e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
8997e860f15SJohn Edward Broadbent                  "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
900ed398213SEd Tanous         .privileges(redfish::privileges::postCertificateCollection)
9010fda0f12SGeorge Liu         .methods(
9020fda0f12SGeorge Liu             boost::beast::http::verb::
90345ca1b86SEd Tanous                 post)([&app](
90445ca1b86SEd Tanous                           const crow::Request& req,
9057e860f15SJohn Edward Broadbent                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
90645ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
90745ca1b86SEd Tanous             {
90845ca1b86SEd Tanous                 return;
90945ca1b86SEd Tanous             }
9105968caeeSMarri Devender Rao             BMCWEB_LOG_DEBUG << "HTTPSCertificateCollection::doPost";
9118d1b46d7Szhanghch05 
9120fda0f12SGeorge Liu             asyncResp->res.jsonValue = {{"Name", "HTTPS Certificate"},
9135968caeeSMarri Devender Rao                                         {"Description", "HTTPS Certificate"}};
9145968caeeSMarri Devender Rao 
9157e860f15SJohn Edward Broadbent             std::string certFileBody =
9167e860f15SJohn Edward Broadbent                 getCertificateFromReqBody(asyncResp, req);
91758eb238fSKowalski, Kamil 
91858eb238fSKowalski, Kamil             if (certFileBody.empty())
91958eb238fSKowalski, Kamil             {
9200fda0f12SGeorge Liu                 BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
921a08752f5SZbigniew Kurzynski                 messages::unrecognizedRequestBody(asyncResp->res);
92258eb238fSKowalski, Kamil                 return;
92358eb238fSKowalski, Kamil             }
92458eb238fSKowalski, Kamil 
9255968caeeSMarri Devender Rao             std::shared_ptr<CertificateFile> certFile =
92658eb238fSKowalski, Kamil                 std::make_shared<CertificateFile>(certFileBody);
9275968caeeSMarri Devender Rao 
9285968caeeSMarri Devender Rao             crow::connections::systemBus->async_method_call(
929656ec7e3SZbigniew Kurzynski                 [asyncResp, certFile](const boost::system::error_code ec,
930656ec7e3SZbigniew Kurzynski                                       const std::string& objectPath) {
9315968caeeSMarri Devender Rao                     if (ec)
9325968caeeSMarri Devender Rao                     {
9335968caeeSMarri Devender Rao                         BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
9345968caeeSMarri Devender Rao                         messages::internalError(asyncResp->res);
9355968caeeSMarri Devender Rao                         return;
9365968caeeSMarri Devender Rao                     }
937656ec7e3SZbigniew Kurzynski                     long certId = getIDFromURL(objectPath);
938656ec7e3SZbigniew Kurzynski                     if (certId < 0)
939656ec7e3SZbigniew Kurzynski                     {
940656ec7e3SZbigniew Kurzynski                         BMCWEB_LOG_ERROR << "Invalid objectPath value"
941656ec7e3SZbigniew Kurzynski                                          << objectPath;
942656ec7e3SZbigniew Kurzynski                         messages::internalError(asyncResp->res);
943656ec7e3SZbigniew Kurzynski                         return;
944656ec7e3SZbigniew Kurzynski                     }
9455968caeeSMarri Devender Rao                     std::string certURL =
9460fda0f12SGeorge Liu                         "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" +
9475968caeeSMarri Devender Rao                         std::to_string(certId);
9480fda0f12SGeorge Liu                     getCertificateProperties(asyncResp, objectPath,
9490fda0f12SGeorge Liu                                              certs::httpsServiceName, certId,
9500fda0f12SGeorge Liu                                              certURL, "HTTPS Certificate");
9515968caeeSMarri Devender Rao                     BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
9525968caeeSMarri Devender Rao                                      << certFile->getCertFilePath();
9535968caeeSMarri Devender Rao                 },
95437cce918SMarri Devender Rao                 certs::httpsServiceName, certs::httpsObjectPath,
9550fda0f12SGeorge Liu                 certs::certInstallIntf, "Install", certFile->getCertFilePath());
9567e860f15SJohn Edward Broadbent         });
9577e860f15SJohn Edward Broadbent } // requestRoutesHTTPSCertificateCollection
9585968caeeSMarri Devender Rao 
9595968caeeSMarri Devender Rao /**
96037cce918SMarri Devender Rao  * @brief Retrieve the certificates installed list and append to the
96137cce918SMarri Devender Rao  * response
96237cce918SMarri Devender Rao  *
96337cce918SMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
96437cce918SMarri Devender Rao  * @param[in] certURL  Path of the certificate object
96537cce918SMarri Devender Rao  * @param[in] path  Path of the D-Bus service object
96637cce918SMarri Devender Rao  * @return None
96737cce918SMarri Devender Rao  */
9684f48d5f6SEd Tanous inline void
9694f48d5f6SEd Tanous     getCertificateLocations(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9708d1b46d7Szhanghch05                             const std::string& certURL, const std::string& path,
97137cce918SMarri Devender Rao                             const std::string& service)
97237cce918SMarri Devender Rao {
97337cce918SMarri Devender Rao     BMCWEB_LOG_DEBUG << "getCertificateLocations URI=" << certURL
97437cce918SMarri Devender Rao                      << " Path=" << path << " service= " << service;
97537cce918SMarri Devender Rao     crow::connections::systemBus->async_method_call(
97637cce918SMarri Devender Rao         [asyncResp, certURL](const boost::system::error_code ec,
977711ac7a9SEd Tanous                              const dbus::utility::ManagedObjectType& certs) {
97837cce918SMarri Devender Rao             if (ec)
97937cce918SMarri Devender Rao             {
9809c8e039eSJonathan Doman                 BMCWEB_LOG_WARNING
9819c8e039eSJonathan Doman                     << "Certificate collection query failed: " << ec
9829c8e039eSJonathan Doman                     << ", skipping " << certURL;
98337cce918SMarri Devender Rao                 return;
98437cce918SMarri Devender Rao             }
98537cce918SMarri Devender Rao             nlohmann::json& links =
98637cce918SMarri Devender Rao                 asyncResp->res.jsonValue["Links"]["Certificates"];
9879eb808c1SEd Tanous             for (const auto& cert : certs)
98837cce918SMarri Devender Rao             {
98937cce918SMarri Devender Rao                 long id = getIDFromURL(cert.first.str);
99037cce918SMarri Devender Rao                 if (id >= 0)
99137cce918SMarri Devender Rao                 {
99237cce918SMarri Devender Rao                     links.push_back(
99337cce918SMarri Devender Rao                         {{"@odata.id", certURL + std::to_string(id)}});
99437cce918SMarri Devender Rao                 }
99537cce918SMarri Devender Rao             }
99637cce918SMarri Devender Rao             asyncResp->res.jsonValue["Links"]["Certificates@odata.count"] =
99737cce918SMarri Devender Rao                 links.size();
99837cce918SMarri Devender Rao         },
99937cce918SMarri Devender Rao         service, path, certs::dbusObjManagerIntf, "GetManagedObjects");
10005968caeeSMarri Devender Rao }
10017e860f15SJohn Edward Broadbent 
10027e860f15SJohn Edward Broadbent /**
10037e860f15SJohn Edward Broadbent  * The certificate location schema defines a resource that an administrator
10047e860f15SJohn Edward Broadbent  * can use in order to locate all certificates installed on a given service.
10057e860f15SJohn Edward Broadbent  */
10067e860f15SJohn Edward Broadbent inline void requestRoutesCertificateLocations(App& app)
10077e860f15SJohn Edward Broadbent {
10087e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/CertificateLocations/")
1009ed398213SEd Tanous         .privileges(redfish::privileges::getCertificateLocations)
101045ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)([&app](const crow::Request& req,
101145ca1b86SEd Tanous                                                        const std::shared_ptr<
101245ca1b86SEd Tanous                                                            bmcweb::AsyncResp>&
101345ca1b86SEd Tanous                                                            asyncResp) {
101445ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
101545ca1b86SEd Tanous             {
101645ca1b86SEd Tanous                 return;
101745ca1b86SEd Tanous             }
10187e860f15SJohn Edward Broadbent             asyncResp->res.jsonValue = {
10197e860f15SJohn Edward Broadbent                 {"@odata.id",
10207e860f15SJohn Edward Broadbent                  "/redfish/v1/CertificateService/CertificateLocations"},
10217e860f15SJohn Edward Broadbent                 {"@odata.type",
10227e860f15SJohn Edward Broadbent                  "#CertificateLocations.v1_0_0.CertificateLocations"},
10237e860f15SJohn Edward Broadbent                 {"Name", "Certificate Locations"},
10247e860f15SJohn Edward Broadbent                 {"Id", "CertificateLocations"},
10257e860f15SJohn Edward Broadbent                 {"Description",
10267e860f15SJohn Edward Broadbent                  "Defines a resource that an administrator can use in order to "
10277e860f15SJohn Edward Broadbent                  "locate all certificates installed on a given service"}};
10287e860f15SJohn Edward Broadbent 
10297e860f15SJohn Edward Broadbent             nlohmann::json& links =
10307e860f15SJohn Edward Broadbent                 asyncResp->res.jsonValue["Links"]["Certificates"];
10317e860f15SJohn Edward Broadbent             links = nlohmann::json::array();
10327e860f15SJohn Edward Broadbent             getCertificateLocations(
10337e860f15SJohn Edward Broadbent                 asyncResp,
10347e860f15SJohn Edward Broadbent                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/",
10357e860f15SJohn Edward Broadbent                 certs::httpsObjectPath, certs::httpsServiceName);
10367e860f15SJohn Edward Broadbent             getCertificateLocations(
10377e860f15SJohn Edward Broadbent                 asyncResp, "/redfish/v1/AccountService/LDAP/Certificates/",
10387e860f15SJohn Edward Broadbent                 certs::ldapObjectPath, certs::ldapServiceName);
10397e860f15SJohn Edward Broadbent             getCertificateLocations(
10407e860f15SJohn Edward Broadbent                 asyncResp, "/redfish/v1/Managers/bmc/Truststore/Certificates/",
10417e860f15SJohn Edward Broadbent                 certs::authorityObjectPath, certs::authorityServiceName);
10427e860f15SJohn Edward Broadbent         });
10437e860f15SJohn Edward Broadbent }
10447e860f15SJohn Edward Broadbent // requestRoutesCertificateLocations
104537cce918SMarri Devender Rao 
104637cce918SMarri Devender Rao /**
104737cce918SMarri Devender Rao  * Collection of LDAP certificates
104837cce918SMarri Devender Rao  */
10497e860f15SJohn Edward Broadbent inline void requestRoutesLDAPCertificateCollection(App& app)
105037cce918SMarri Devender Rao {
10517e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
1052ed398213SEd Tanous         .privileges(redfish::privileges::getCertificateCollection)
105345ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)([&app](const crow::Request& req,
105445ca1b86SEd Tanous                                                        const std::shared_ptr<
105545ca1b86SEd Tanous                                                            bmcweb::AsyncResp>&
105645ca1b86SEd Tanous                                                            asyncResp) {
105745ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
105845ca1b86SEd Tanous             {
105945ca1b86SEd Tanous                 return;
106045ca1b86SEd Tanous             }
10618d1b46d7Szhanghch05             asyncResp->res.jsonValue = {
10620fda0f12SGeorge Liu                 {"@odata.id", "/redfish/v1/AccountService/LDAP/Certificates"},
10630fda0f12SGeorge Liu                 {"@odata.type", "#CertificateCollection.CertificateCollection"},
106437cce918SMarri Devender Rao                 {"Name", "LDAP Certificates Collection"},
10650fda0f12SGeorge Liu                 {"Description", "A Collection of LDAP certificate instances"}};
10668d1b46d7Szhanghch05 
106737cce918SMarri Devender Rao             crow::connections::systemBus->async_method_call(
106837cce918SMarri Devender Rao                 [asyncResp](const boost::system::error_code ec,
1069711ac7a9SEd Tanous                             const dbus::utility::ManagedObjectType& certs) {
10707e860f15SJohn Edward Broadbent                     nlohmann::json& members =
10717e860f15SJohn Edward Broadbent                         asyncResp->res.jsonValue["Members"];
10729c8e039eSJonathan Doman                     nlohmann::json& count =
10739c8e039eSJonathan Doman                         asyncResp->res.jsonValue["Members@odata.count"];
10749c8e039eSJonathan Doman                     members = nlohmann::json::array();
10759c8e039eSJonathan Doman                     count = 0;
107637cce918SMarri Devender Rao                     if (ec)
107737cce918SMarri Devender Rao                     {
10780fda0f12SGeorge Liu                         BMCWEB_LOG_WARNING << "LDAP certificate query failed: "
10790fda0f12SGeorge Liu                                            << ec;
108037cce918SMarri Devender Rao                         return;
108137cce918SMarri Devender Rao                     }
108237cce918SMarri Devender Rao                     for (const auto& cert : certs)
108337cce918SMarri Devender Rao                     {
108437cce918SMarri Devender Rao                         long id = getIDFromURL(cert.first.str);
108537cce918SMarri Devender Rao                         if (id >= 0)
108637cce918SMarri Devender Rao                         {
108737cce918SMarri Devender Rao                             members.push_back(
10880fda0f12SGeorge Liu                                 {{"@odata.id",
10890fda0f12SGeorge Liu                                   "/redfish/v1/AccountService/LDAP/Certificates/" +
109037cce918SMarri Devender Rao                                       std::to_string(id)}});
109137cce918SMarri Devender Rao                         }
109237cce918SMarri Devender Rao                     }
10939c8e039eSJonathan Doman                     count = members.size();
109437cce918SMarri Devender Rao                 },
109537cce918SMarri Devender Rao                 certs::ldapServiceName, certs::ldapObjectPath,
109637cce918SMarri Devender Rao                 certs::dbusObjManagerIntf, "GetManagedObjects");
10977e860f15SJohn Edward Broadbent         });
109837cce918SMarri Devender Rao 
10997e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
1100ed398213SEd Tanous         .privileges(redfish::privileges::postCertificateCollection)
11017e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::post)(
110245ca1b86SEd Tanous             [&app](const crow::Request& req,
11037e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
110445ca1b86SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
110545ca1b86SEd Tanous                 {
110645ca1b86SEd Tanous                     return;
110745ca1b86SEd Tanous                 }
11087e860f15SJohn Edward Broadbent                 std::string certFileBody =
11097e860f15SJohn Edward Broadbent                     getCertificateFromReqBody(asyncResp, req);
111058eb238fSKowalski, Kamil 
111158eb238fSKowalski, Kamil                 if (certFileBody.empty())
111258eb238fSKowalski, Kamil                 {
11137e860f15SJohn Edward Broadbent                     BMCWEB_LOG_ERROR
11147e860f15SJohn Edward Broadbent                         << "Cannot get certificate from request body.";
1115a08752f5SZbigniew Kurzynski                     messages::unrecognizedRequestBody(asyncResp->res);
111658eb238fSKowalski, Kamil                     return;
111758eb238fSKowalski, Kamil                 }
111858eb238fSKowalski, Kamil 
111958eb238fSKowalski, Kamil                 std::shared_ptr<CertificateFile> certFile =
112058eb238fSKowalski, Kamil                     std::make_shared<CertificateFile>(certFileBody);
112158eb238fSKowalski, Kamil 
112237cce918SMarri Devender Rao                 crow::connections::systemBus->async_method_call(
1123656ec7e3SZbigniew Kurzynski                     [asyncResp, certFile](const boost::system::error_code ec,
1124656ec7e3SZbigniew Kurzynski                                           const std::string& objectPath) {
112537cce918SMarri Devender Rao                         if (ec)
112637cce918SMarri Devender Rao                         {
112737cce918SMarri Devender Rao                             BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
112837cce918SMarri Devender Rao                             messages::internalError(asyncResp->res);
112937cce918SMarri Devender Rao                             return;
113037cce918SMarri Devender Rao                         }
1131656ec7e3SZbigniew Kurzynski                         long certId = getIDFromURL(objectPath);
1132656ec7e3SZbigniew Kurzynski                         if (certId < 0)
1133656ec7e3SZbigniew Kurzynski                         {
1134656ec7e3SZbigniew Kurzynski                             BMCWEB_LOG_ERROR << "Invalid objectPath value"
1135656ec7e3SZbigniew Kurzynski                                              << objectPath;
1136656ec7e3SZbigniew Kurzynski                             messages::internalError(asyncResp->res);
1137656ec7e3SZbigniew Kurzynski                             return;
1138656ec7e3SZbigniew Kurzynski                         }
113937cce918SMarri Devender Rao                         std::string certURL =
114037cce918SMarri Devender Rao                             "/redfish/v1/AccountService/LDAP/Certificates/" +
114137cce918SMarri Devender Rao                             std::to_string(certId);
114237cce918SMarri Devender Rao                         getCertificateProperties(asyncResp, objectPath,
114337cce918SMarri Devender Rao                                                  certs::ldapServiceName, certId,
114437cce918SMarri Devender Rao                                                  certURL, "LDAP Certificate");
114537cce918SMarri Devender Rao                         BMCWEB_LOG_DEBUG << "LDAP certificate install file="
114637cce918SMarri Devender Rao                                          << certFile->getCertFilePath();
114737cce918SMarri Devender Rao                     },
114837cce918SMarri Devender Rao                     certs::ldapServiceName, certs::ldapObjectPath,
11497e860f15SJohn Edward Broadbent                     certs::certInstallIntf, "Install",
11507e860f15SJohn Edward Broadbent                     certFile->getCertFilePath());
11517e860f15SJohn Edward Broadbent             });
11527e860f15SJohn Edward Broadbent } // requestRoutesLDAPCertificateCollection
115337cce918SMarri Devender Rao 
115437cce918SMarri Devender Rao /**
115537cce918SMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
115637cce918SMarri Devender Rao  * of a component, account or service.
115737cce918SMarri Devender Rao  */
11587e860f15SJohn Edward Broadbent inline void requestRoutesLDAPCertificate(App& app)
115937cce918SMarri Devender Rao {
11607e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
1161ed398213SEd Tanous         .privileges(redfish::privileges::getCertificate)
11627e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
116345ca1b86SEd Tanous             [&app](const crow::Request& req,
11647e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11657e860f15SJohn Edward Broadbent                    const std::string&) {
116645ca1b86SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
116745ca1b86SEd Tanous                 {
116845ca1b86SEd Tanous                     return;
116945ca1b86SEd Tanous                 }
117037cce918SMarri Devender Rao                 long id = getIDFromURL(req.url);
117137cce918SMarri Devender Rao                 if (id < 0)
117237cce918SMarri Devender Rao                 {
117337cce918SMarri Devender Rao                     BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
117437cce918SMarri Devender Rao                     messages::internalError(asyncResp->res);
117537cce918SMarri Devender Rao                     return;
117637cce918SMarri Devender Rao                 }
11777e860f15SJohn Edward Broadbent                 BMCWEB_LOG_DEBUG << "LDAP Certificate ID="
11787e860f15SJohn Edward Broadbent                                  << std::to_string(id);
11797e860f15SJohn Edward Broadbent                 std::string certURL =
11807e860f15SJohn Edward Broadbent                     "/redfish/v1/AccountService/LDAP/Certificates/" +
118137cce918SMarri Devender Rao                     std::to_string(id);
118237cce918SMarri Devender Rao                 std::string objectPath = certs::ldapObjectPath;
118337cce918SMarri Devender Rao                 objectPath += "/";
118437cce918SMarri Devender Rao                 objectPath += std::to_string(id);
11857e860f15SJohn Edward Broadbent                 getCertificateProperties(asyncResp, objectPath,
11867e860f15SJohn Edward Broadbent                                          certs::ldapServiceName, id, certURL,
11877e860f15SJohn Edward Broadbent                                          "LDAP Certificate");
11887e860f15SJohn Edward Broadbent             });
11897e860f15SJohn Edward Broadbent } // requestRoutesLDAPCertificate
1190cfcd5f6bSMarri Devender Rao /**
1191cfcd5f6bSMarri Devender Rao  * Collection of TrustStoreCertificate certificates
1192cfcd5f6bSMarri Devender Rao  */
11937e860f15SJohn Edward Broadbent inline void requestRoutesTrustStoreCertificateCollection(App& app)
1194cfcd5f6bSMarri Devender Rao {
11957e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
1196ed398213SEd Tanous         .privileges(redfish::privileges::getCertificate)
119745ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)([&app](const crow::Request& req,
119845ca1b86SEd Tanous                                                        const std::shared_ptr<
119945ca1b86SEd Tanous                                                            bmcweb::AsyncResp>&
120045ca1b86SEd Tanous                                                            asyncResp) {
120145ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
120245ca1b86SEd Tanous             {
120345ca1b86SEd Tanous                 return;
120445ca1b86SEd Tanous             }
12058d1b46d7Szhanghch05             asyncResp->res.jsonValue = {
12067e860f15SJohn Edward Broadbent                 {"@odata.id",
12077e860f15SJohn Edward Broadbent                  "/redfish/v1/Managers/bmc/Truststore/Certificates/"},
12080fda0f12SGeorge Liu                 {"@odata.type", "#CertificateCollection.CertificateCollection"},
1209cfcd5f6bSMarri Devender Rao                 {"Name", "TrustStore Certificates Collection"},
1210cfcd5f6bSMarri Devender Rao                 {"Description",
1211cfcd5f6bSMarri Devender Rao                  "A Collection of TrustStore certificate instances"}};
12128d1b46d7Szhanghch05 
1213cfcd5f6bSMarri Devender Rao             crow::connections::systemBus->async_method_call(
1214cfcd5f6bSMarri Devender Rao                 [asyncResp](const boost::system::error_code ec,
1215711ac7a9SEd Tanous                             const dbus::utility::ManagedObjectType& certs) {
1216cfcd5f6bSMarri Devender Rao                     if (ec)
1217cfcd5f6bSMarri Devender Rao                     {
1218cfcd5f6bSMarri Devender Rao                         BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
1219cfcd5f6bSMarri Devender Rao                         messages::internalError(asyncResp->res);
1220cfcd5f6bSMarri Devender Rao                         return;
1221cfcd5f6bSMarri Devender Rao                     }
12227e860f15SJohn Edward Broadbent                     nlohmann::json& members =
12237e860f15SJohn Edward Broadbent                         asyncResp->res.jsonValue["Members"];
1224cfcd5f6bSMarri Devender Rao                     members = nlohmann::json::array();
1225cfcd5f6bSMarri Devender Rao                     for (const auto& cert : certs)
1226cfcd5f6bSMarri Devender Rao                     {
1227cfcd5f6bSMarri Devender Rao                         long id = getIDFromURL(cert.first.str);
1228cfcd5f6bSMarri Devender Rao                         if (id >= 0)
1229cfcd5f6bSMarri Devender Rao                         {
1230cfcd5f6bSMarri Devender Rao                             members.push_back(
12310fda0f12SGeorge Liu                                 {{"@odata.id",
12320fda0f12SGeorge Liu                                   "/redfish/v1/Managers/bmc/Truststore/Certificates/" +
1233cfcd5f6bSMarri Devender Rao                                       std::to_string(id)}});
1234cfcd5f6bSMarri Devender Rao                         }
1235cfcd5f6bSMarri Devender Rao                     }
1236cfcd5f6bSMarri Devender Rao                     asyncResp->res.jsonValue["Members@odata.count"] =
1237cfcd5f6bSMarri Devender Rao                         members.size();
1238cfcd5f6bSMarri Devender Rao                 },
1239cfcd5f6bSMarri Devender Rao                 certs::authorityServiceName, certs::authorityObjectPath,
1240cfcd5f6bSMarri Devender Rao                 certs::dbusObjManagerIntf, "GetManagedObjects");
12417e860f15SJohn Edward Broadbent         });
1242cfcd5f6bSMarri Devender Rao 
12437e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
1244ed398213SEd Tanous         .privileges(redfish::privileges::postCertificateCollection)
12450fda0f12SGeorge Liu         .methods(
12460fda0f12SGeorge Liu             boost::beast::http::verb::
124745ca1b86SEd Tanous                 post)([&app](
124845ca1b86SEd Tanous                           const crow::Request& req,
12497e860f15SJohn Edward Broadbent                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
125045ca1b86SEd Tanous             if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
125145ca1b86SEd Tanous             {
125245ca1b86SEd Tanous                 return;
125345ca1b86SEd Tanous             }
12547e860f15SJohn Edward Broadbent             std::string certFileBody =
12557e860f15SJohn Edward Broadbent                 getCertificateFromReqBody(asyncResp, req);
1256a08752f5SZbigniew Kurzynski 
1257a08752f5SZbigniew Kurzynski             if (certFileBody.empty())
1258a08752f5SZbigniew Kurzynski             {
12590fda0f12SGeorge Liu                 BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
1260a08752f5SZbigniew Kurzynski                 messages::unrecognizedRequestBody(asyncResp->res);
1261a08752f5SZbigniew Kurzynski                 return;
1262a08752f5SZbigniew Kurzynski             }
1263a08752f5SZbigniew Kurzynski 
1264a08752f5SZbigniew Kurzynski             std::shared_ptr<CertificateFile> certFile =
1265a08752f5SZbigniew Kurzynski                 std::make_shared<CertificateFile>(certFileBody);
1266cfcd5f6bSMarri Devender Rao             crow::connections::systemBus->async_method_call(
1267656ec7e3SZbigniew Kurzynski                 [asyncResp, certFile](const boost::system::error_code ec,
1268656ec7e3SZbigniew Kurzynski                                       const std::string& objectPath) {
1269cfcd5f6bSMarri Devender Rao                     if (ec)
1270cfcd5f6bSMarri Devender Rao                     {
1271cfcd5f6bSMarri Devender Rao                         BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
1272cfcd5f6bSMarri Devender Rao                         messages::internalError(asyncResp->res);
1273cfcd5f6bSMarri Devender Rao                         return;
1274cfcd5f6bSMarri Devender Rao                     }
1275656ec7e3SZbigniew Kurzynski                     long certId = getIDFromURL(objectPath);
1276656ec7e3SZbigniew Kurzynski                     if (certId < 0)
1277656ec7e3SZbigniew Kurzynski                     {
1278656ec7e3SZbigniew Kurzynski                         BMCWEB_LOG_ERROR << "Invalid objectPath value"
1279656ec7e3SZbigniew Kurzynski                                          << objectPath;
1280656ec7e3SZbigniew Kurzynski                         messages::internalError(asyncResp->res);
1281656ec7e3SZbigniew Kurzynski                         return;
1282656ec7e3SZbigniew Kurzynski                     }
12830fda0f12SGeorge Liu                     std::string certURL =
12840fda0f12SGeorge Liu                         "/redfish/v1/Managers/bmc/Truststore/Certificates/" +
1285cfcd5f6bSMarri Devender Rao                         std::to_string(certId);
1286656ec7e3SZbigniew Kurzynski 
12877e860f15SJohn Edward Broadbent                     getCertificateProperties(
12887e860f15SJohn Edward Broadbent                         asyncResp, objectPath, certs::authorityServiceName,
12897e860f15SJohn Edward Broadbent                         certId, certURL, "TrustStore Certificate");
12900fda0f12SGeorge Liu                     BMCWEB_LOG_DEBUG << "TrustStore certificate install file="
1291cfcd5f6bSMarri Devender Rao                                      << certFile->getCertFilePath();
1292cfcd5f6bSMarri Devender Rao                 },
1293cfcd5f6bSMarri Devender Rao                 certs::authorityServiceName, certs::authorityObjectPath,
12940fda0f12SGeorge Liu                 certs::certInstallIntf, "Install", certFile->getCertFilePath());
12957e860f15SJohn Edward Broadbent         });
12967e860f15SJohn Edward Broadbent } // requestRoutesTrustStoreCertificateCollection
1297cfcd5f6bSMarri Devender Rao 
1298cfcd5f6bSMarri Devender Rao /**
1299cfcd5f6bSMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
1300cfcd5f6bSMarri Devender Rao  * of a component, account or service.
1301cfcd5f6bSMarri Devender Rao  */
13027e860f15SJohn Edward Broadbent inline void requestRoutesTrustStoreCertificate(App& app)
1303cfcd5f6bSMarri Devender Rao {
13047e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/")
1305ed398213SEd Tanous         .privileges(redfish::privileges::getCertificate)
13067e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
130745ca1b86SEd Tanous             [&app](const crow::Request& req,
13087e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
13097e860f15SJohn Edward Broadbent                    const std::string&) {
131045ca1b86SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
131145ca1b86SEd Tanous                 {
131245ca1b86SEd Tanous                     return;
131345ca1b86SEd Tanous                 }
1314cfcd5f6bSMarri Devender Rao                 long id = getIDFromURL(req.url);
1315cfcd5f6bSMarri Devender Rao                 if (id < 0)
1316cfcd5f6bSMarri Devender Rao                 {
1317cfcd5f6bSMarri Devender Rao                     BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
1318cfcd5f6bSMarri Devender Rao                     messages::internalError(asyncResp->res);
1319cfcd5f6bSMarri Devender Rao                     return;
1320cfcd5f6bSMarri Devender Rao                 }
1321cfcd5f6bSMarri Devender Rao                 BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doGet ID="
1322cfcd5f6bSMarri Devender Rao                                  << std::to_string(id);
1323cfcd5f6bSMarri Devender Rao                 std::string certURL =
1324cfcd5f6bSMarri Devender Rao                     "/redfish/v1/Managers/bmc/Truststore/Certificates/" +
1325cfcd5f6bSMarri Devender Rao                     std::to_string(id);
1326cfcd5f6bSMarri Devender Rao                 std::string objectPath = certs::authorityObjectPath;
1327cfcd5f6bSMarri Devender Rao                 objectPath += "/";
1328cfcd5f6bSMarri Devender Rao                 objectPath += std::to_string(id);
1329cfcd5f6bSMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath,
13307e860f15SJohn Edward Broadbent                                          certs::authorityServiceName, id,
13317e860f15SJohn Edward Broadbent                                          certURL, "TrustStore Certificate");
13327e860f15SJohn Edward Broadbent             });
133307a60299SZbigniew Kurzynski 
13347e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/")
1335ed398213SEd Tanous         .privileges(redfish::privileges::deleteCertificate)
13367e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::delete_)(
133745ca1b86SEd Tanous             [&app](const crow::Request& req,
13387e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
13397e860f15SJohn Edward Broadbent                    const std::string& param) {
134045ca1b86SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
134145ca1b86SEd Tanous                 {
134245ca1b86SEd Tanous                     return;
134345ca1b86SEd Tanous                 }
13447e860f15SJohn Edward Broadbent                 if (param.empty())
134507a60299SZbigniew Kurzynski                 {
134607a60299SZbigniew Kurzynski                     messages::internalError(asyncResp->res);
134707a60299SZbigniew Kurzynski                     return;
134807a60299SZbigniew Kurzynski                 }
134907a60299SZbigniew Kurzynski 
135007a60299SZbigniew Kurzynski                 long id = getIDFromURL(req.url);
135107a60299SZbigniew Kurzynski                 if (id < 0)
135207a60299SZbigniew Kurzynski                 {
135307a60299SZbigniew Kurzynski                     BMCWEB_LOG_ERROR << "Invalid url value: " << req.url;
13547e860f15SJohn Edward Broadbent                     messages::resourceNotFound(asyncResp->res,
13557e860f15SJohn Edward Broadbent                                                "TrustStore Certificate",
135607a60299SZbigniew Kurzynski                                                std::string(req.url));
135707a60299SZbigniew Kurzynski                     return;
135807a60299SZbigniew Kurzynski                 }
135907a60299SZbigniew Kurzynski                 BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doDelete ID="
136007a60299SZbigniew Kurzynski                                  << std::to_string(id);
136107a60299SZbigniew Kurzynski                 std::string certPath = certs::authorityObjectPath;
136207a60299SZbigniew Kurzynski                 certPath += "/";
136307a60299SZbigniew Kurzynski                 certPath += std::to_string(id);
136407a60299SZbigniew Kurzynski 
136507a60299SZbigniew Kurzynski                 crow::connections::systemBus->async_method_call(
136607a60299SZbigniew Kurzynski                     [asyncResp, id](const boost::system::error_code ec) {
136707a60299SZbigniew Kurzynski                         if (ec)
136807a60299SZbigniew Kurzynski                         {
136907a60299SZbigniew Kurzynski                             messages::resourceNotFound(asyncResp->res,
137007a60299SZbigniew Kurzynski                                                        "TrustStore Certificate",
137107a60299SZbigniew Kurzynski                                                        std::to_string(id));
137207a60299SZbigniew Kurzynski                             return;
137307a60299SZbigniew Kurzynski                         }
137407a60299SZbigniew Kurzynski                         BMCWEB_LOG_INFO << "Certificate deleted";
13757e860f15SJohn Edward Broadbent                         asyncResp->res.result(
13767e860f15SJohn Edward Broadbent                             boost::beast::http::status::no_content);
137707a60299SZbigniew Kurzynski                     },
137807a60299SZbigniew Kurzynski                     certs::authorityServiceName, certPath, certs::objDeleteIntf,
137907a60299SZbigniew Kurzynski                     "Delete");
13807e860f15SJohn Edward Broadbent             });
13817e860f15SJohn Edward Broadbent } // requestRoutesTrustStoreCertificate
13825968caeeSMarri Devender Rao } // namespace redfish
1383