xref: /openbmc/bmcweb/features/redfish/lib/certificate_service.hpp (revision cb13a39253848ece442971301ade9c09d98bf08e)
15968caeeSMarri Devender Rao /*
25968caeeSMarri Devender Rao // Copyright (c) 2018 IBM Corporation
35968caeeSMarri Devender Rao //
45968caeeSMarri Devender Rao // Licensed under the Apache License, Version 2.0 (the "License");
55968caeeSMarri Devender Rao // you may not use this file except in compliance with the License.
65968caeeSMarri Devender Rao // You may obtain a copy of the License at
75968caeeSMarri Devender Rao //
85968caeeSMarri Devender Rao //      http://www.apache.org/licenses/LICENSE-2.0
95968caeeSMarri Devender Rao //
105968caeeSMarri Devender Rao // Unless required by applicable law or agreed to in writing, software
115968caeeSMarri Devender Rao // distributed under the License is distributed on an "AS IS" BASIS,
125968caeeSMarri Devender Rao // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135968caeeSMarri Devender Rao // See the License for the specific language governing permissions and
145968caeeSMarri Devender Rao // limitations under the License.
155968caeeSMarri Devender Rao */
165968caeeSMarri Devender Rao #pragma once
175968caeeSMarri Devender Rao 
185968caeeSMarri Devender Rao #include "node.hpp"
195968caeeSMarri Devender Rao 
20e6604b11SIwona Klimaszewska #include <boost/convert.hpp>
21e6604b11SIwona Klimaszewska #include <boost/convert/strtol.hpp>
221214b7e7SGunnar Mills 
235968caeeSMarri Devender Rao #include <variant>
245968caeeSMarri Devender Rao namespace redfish
255968caeeSMarri Devender Rao {
265968caeeSMarri Devender Rao namespace certs
275968caeeSMarri Devender Rao {
285968caeeSMarri Devender Rao constexpr char const* httpsObjectPath =
295968caeeSMarri Devender Rao     "/xyz/openbmc_project/certs/server/https";
305968caeeSMarri Devender Rao constexpr char const* certInstallIntf = "xyz.openbmc_project.Certs.Install";
315968caeeSMarri Devender Rao constexpr char const* certReplaceIntf = "xyz.openbmc_project.Certs.Replace";
3207a60299SZbigniew Kurzynski constexpr char const* objDeleteIntf = "xyz.openbmc_project.Object.Delete";
335968caeeSMarri Devender Rao constexpr char const* certPropIntf = "xyz.openbmc_project.Certs.Certificate";
345968caeeSMarri Devender Rao constexpr char const* dbusPropIntf = "org.freedesktop.DBus.Properties";
355968caeeSMarri Devender Rao constexpr char const* dbusObjManagerIntf = "org.freedesktop.DBus.ObjectManager";
3637cce918SMarri Devender Rao constexpr char const* ldapObjectPath = "/xyz/openbmc_project/certs/client/ldap";
3737cce918SMarri Devender Rao constexpr char const* httpsServiceName =
3837cce918SMarri Devender Rao     "xyz.openbmc_project.Certs.Manager.Server.Https";
3937cce918SMarri Devender Rao constexpr char const* ldapServiceName =
4037cce918SMarri Devender Rao     "xyz.openbmc_project.Certs.Manager.Client.Ldap";
41cfcd5f6bSMarri Devender Rao constexpr char const* authorityServiceName =
42cfcd5f6bSMarri Devender Rao     "xyz.openbmc_project.Certs.Manager.Authority.Ldap";
43cfcd5f6bSMarri Devender Rao constexpr char const* authorityObjectPath =
44cfcd5f6bSMarri Devender Rao     "/xyz/openbmc_project/certs/authority/ldap";
455968caeeSMarri Devender Rao } // namespace certs
465968caeeSMarri Devender Rao 
475968caeeSMarri Devender Rao /**
485968caeeSMarri Devender Rao  * The Certificate schema defines a Certificate Service which represents the
495968caeeSMarri Devender Rao  * actions available to manage certificates and links to where certificates
505968caeeSMarri Devender Rao  * are installed.
515968caeeSMarri Devender Rao  */
525968caeeSMarri Devender Rao class CertificateService : public Node
535968caeeSMarri Devender Rao {
545968caeeSMarri Devender Rao   public:
5552cc112dSEd Tanous     CertificateService(App& app) : Node(app, "/redfish/v1/CertificateService/")
565968caeeSMarri Devender Rao     {
575968caeeSMarri Devender Rao         // TODO: Issue#61 No entries are available for Certificate
584e0453b1SGunnar Mills         // service at https://www.dmtf.org/standards/redfish
595968caeeSMarri Devender Rao         // "redfish standard registries". Need to modify after DMTF
605968caeeSMarri Devender Rao         // publish Privilege details for certificate service
615968caeeSMarri Devender Rao         entityPrivileges = {
625968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
635968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
645968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
655968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
665968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
675968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
685968caeeSMarri Devender Rao     }
695968caeeSMarri Devender Rao 
705968caeeSMarri Devender Rao   private:
71*cb13a392SEd Tanous     void doGet(crow::Response& res, const crow::Request&,
72*cb13a392SEd Tanous                const std::vector<std::string>&) override
735968caeeSMarri Devender Rao     {
745968caeeSMarri Devender Rao         res.jsonValue = {
755968caeeSMarri Devender Rao             {"@odata.type", "#CertificateService.v1_0_0.CertificateService"},
765968caeeSMarri Devender Rao             {"@odata.id", "/redfish/v1/CertificateService"},
775968caeeSMarri Devender Rao             {"Id", "CertificateService"},
785968caeeSMarri Devender Rao             {"Name", "Certificate Service"},
795968caeeSMarri Devender Rao             {"Description", "Actions available to manage certificates"}};
805968caeeSMarri Devender Rao         res.jsonValue["CertificateLocations"] = {
815968caeeSMarri Devender Rao             {"@odata.id",
825968caeeSMarri Devender Rao              "/redfish/v1/CertificateService/CertificateLocations"}};
835968caeeSMarri Devender Rao         res.jsonValue["Actions"]["#CertificateService.ReplaceCertificate"] = {
845968caeeSMarri Devender Rao             {"target", "/redfish/v1/CertificateService/Actions/"
855968caeeSMarri Devender Rao                        "CertificateService.ReplaceCertificate"},
865968caeeSMarri Devender Rao             {"CertificateType@Redfish.AllowableValues", {"PEM"}}};
8730215816SMarri Devender Rao         res.jsonValue["Actions"]["#CertificateService.GenerateCSR"] = {
8830215816SMarri Devender Rao             {"target", "/redfish/v1/CertificateService/Actions/"
8930215816SMarri Devender Rao                        "CertificateService.GenerateCSR"}};
905968caeeSMarri Devender Rao         res.end();
915968caeeSMarri Devender Rao     }
925968caeeSMarri Devender Rao }; // CertificateService
9337cce918SMarri Devender Rao 
945968caeeSMarri Devender Rao /**
955968caeeSMarri Devender Rao  * @brief Find the ID specified in the URL
965968caeeSMarri Devender Rao  * Finds the numbers specified after the last "/" in the URL and returns.
975968caeeSMarri Devender Rao  * @param[in] path URL
985968caeeSMarri Devender Rao  * @return -1 on failure and number on success
995968caeeSMarri Devender Rao  */
10023a21a1cSEd Tanous inline long getIDFromURL(const std::string_view url)
1015968caeeSMarri Devender Rao {
1025968caeeSMarri Devender Rao     std::size_t found = url.rfind("/");
1035968caeeSMarri Devender Rao     if (found == std::string::npos)
1045968caeeSMarri Devender Rao     {
1055968caeeSMarri Devender Rao         return -1;
1065968caeeSMarri Devender Rao     }
107e6604b11SIwona Klimaszewska 
1085968caeeSMarri Devender Rao     if ((found + 1) < url.length())
1095968caeeSMarri Devender Rao     {
1105968caeeSMarri Devender Rao         std::string_view str = url.substr(found + 1);
111e6604b11SIwona Klimaszewska 
112e6604b11SIwona Klimaszewska         return boost::convert<long>(str, boost::cnv::strtol()).value_or(-1);
1135968caeeSMarri Devender Rao     }
114e6604b11SIwona Klimaszewska 
1155968caeeSMarri Devender Rao     return -1;
1165968caeeSMarri Devender Rao }
1175968caeeSMarri Devender Rao 
11823a21a1cSEd Tanous inline std::string
11958eb238fSKowalski, Kamil     getCertificateFromReqBody(const std::shared_ptr<AsyncResp>& asyncResp,
12058eb238fSKowalski, Kamil                               const crow::Request& req)
12158eb238fSKowalski, Kamil {
12258eb238fSKowalski, Kamil     nlohmann::json reqJson = nlohmann::json::parse(req.body, nullptr, false);
12358eb238fSKowalski, Kamil 
12458eb238fSKowalski, Kamil     if (reqJson.is_discarded())
12558eb238fSKowalski, Kamil     {
12658eb238fSKowalski, Kamil         // We did not receive JSON request, proceed as it is RAW data
12758eb238fSKowalski, Kamil         return req.body;
12858eb238fSKowalski, Kamil     }
12958eb238fSKowalski, Kamil 
13058eb238fSKowalski, Kamil     std::string certificate;
13158eb238fSKowalski, Kamil     std::optional<std::string> certificateType = "PEM";
13258eb238fSKowalski, Kamil 
13358eb238fSKowalski, Kamil     if (!json_util::readJson(reqJson, asyncResp->res, "CertificateString",
13458eb238fSKowalski, Kamil                              certificate, "CertificateType", certificateType))
13558eb238fSKowalski, Kamil     {
13658eb238fSKowalski, Kamil         BMCWEB_LOG_ERROR << "Required parameters are missing";
13758eb238fSKowalski, Kamil         messages::internalError(asyncResp->res);
13858eb238fSKowalski, Kamil         return std::string();
13958eb238fSKowalski, Kamil     }
14058eb238fSKowalski, Kamil 
14158eb238fSKowalski, Kamil     if (*certificateType != "PEM")
14258eb238fSKowalski, Kamil     {
14358eb238fSKowalski, Kamil         messages::propertyValueNotInList(asyncResp->res, *certificateType,
14458eb238fSKowalski, Kamil                                          "CertificateType");
14558eb238fSKowalski, Kamil         return std::string();
14658eb238fSKowalski, Kamil     }
14758eb238fSKowalski, Kamil 
14858eb238fSKowalski, Kamil     return certificate;
14958eb238fSKowalski, Kamil }
15058eb238fSKowalski, Kamil 
1515968caeeSMarri Devender Rao /**
1525968caeeSMarri Devender Rao  * Class to create a temporary certificate file for uploading to system
1535968caeeSMarri Devender Rao  */
1545968caeeSMarri Devender Rao class CertificateFile
1555968caeeSMarri Devender Rao {
1565968caeeSMarri Devender Rao   public:
1575968caeeSMarri Devender Rao     CertificateFile() = delete;
1585968caeeSMarri Devender Rao     CertificateFile(const CertificateFile&) = delete;
1595968caeeSMarri Devender Rao     CertificateFile& operator=(const CertificateFile&) = delete;
1605968caeeSMarri Devender Rao     CertificateFile(CertificateFile&&) = delete;
1615968caeeSMarri Devender Rao     CertificateFile& operator=(CertificateFile&&) = delete;
1625968caeeSMarri Devender Rao     CertificateFile(const std::string& certString)
1635968caeeSMarri Devender Rao     {
1645968caeeSMarri Devender Rao         char dirTemplate[] = "/tmp/Certs.XXXXXX";
1655968caeeSMarri Devender Rao         char* tempDirectory = mkdtemp(dirTemplate);
1665968caeeSMarri Devender Rao         if (tempDirectory)
1675968caeeSMarri Devender Rao         {
1685968caeeSMarri Devender Rao             certDirectory = tempDirectory;
1695968caeeSMarri Devender Rao             certificateFile = certDirectory / "cert.pem";
1705968caeeSMarri Devender Rao             std::ofstream out(certificateFile, std::ofstream::out |
1715968caeeSMarri Devender Rao                                                    std::ofstream::binary |
1725968caeeSMarri Devender Rao                                                    std::ofstream::trunc);
1735968caeeSMarri Devender Rao             out << certString;
1745968caeeSMarri Devender Rao             out.close();
1755968caeeSMarri Devender Rao             BMCWEB_LOG_DEBUG << "Creating certificate file" << certificateFile;
1765968caeeSMarri Devender Rao         }
1775968caeeSMarri Devender Rao     }
1785968caeeSMarri Devender Rao     ~CertificateFile()
1795968caeeSMarri Devender Rao     {
1805968caeeSMarri Devender Rao         if (std::filesystem::exists(certDirectory))
1815968caeeSMarri Devender Rao         {
1825968caeeSMarri Devender Rao             BMCWEB_LOG_DEBUG << "Removing certificate file" << certificateFile;
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"
1885968caeeSMarri Devender Rao                                  << certDirectory;
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  */
21330215816SMarri Devender Rao static void getCSR(const std::shared_ptr<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  */
24630215816SMarri Devender Rao class CertificateActionGenerateCSR : public Node
24730215816SMarri Devender Rao {
24830215816SMarri Devender Rao   public:
24952cc112dSEd Tanous     CertificateActionGenerateCSR(App& app) :
25030215816SMarri Devender Rao         Node(app, "/redfish/v1/CertificateService/Actions/"
25130215816SMarri Devender Rao                   "CertificateService.GenerateCSR/")
25230215816SMarri Devender Rao     {
25330215816SMarri Devender Rao         entityPrivileges = {
25430215816SMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
25530215816SMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
25630215816SMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
25730215816SMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
25830215816SMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
25930215816SMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
26030215816SMarri Devender Rao     }
26130215816SMarri Devender Rao 
26230215816SMarri Devender Rao   private:
26330215816SMarri Devender Rao     void doPost(crow::Response& res, const crow::Request& req,
264*cb13a392SEd Tanous                 const std::vector<std::string>&) override
26530215816SMarri Devender Rao     {
26630215816SMarri Devender Rao         static const int RSA_KEY_BIT_LENGTH = 2048;
26730215816SMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
26830215816SMarri Devender Rao         // Required parameters
26930215816SMarri Devender Rao         std::string city;
27030215816SMarri Devender Rao         std::string commonName;
27130215816SMarri Devender Rao         std::string country;
27230215816SMarri Devender Rao         std::string organization;
27330215816SMarri Devender Rao         std::string organizationalUnit;
27430215816SMarri Devender Rao         std::string state;
27530215816SMarri Devender Rao         nlohmann::json certificateCollection;
27630215816SMarri Devender Rao 
27730215816SMarri Devender Rao         // Optional parameters
27830215816SMarri Devender Rao         std::optional<std::vector<std::string>> optAlternativeNames =
27930215816SMarri Devender Rao             std::vector<std::string>();
28030215816SMarri Devender Rao         std::optional<std::string> optContactPerson = "";
28130215816SMarri Devender Rao         std::optional<std::string> optChallengePassword = "";
28230215816SMarri Devender Rao         std::optional<std::string> optEmail = "";
28330215816SMarri Devender Rao         std::optional<std::string> optGivenName = "";
28430215816SMarri Devender Rao         std::optional<std::string> optInitials = "";
28530215816SMarri Devender Rao         std::optional<int64_t> optKeyBitLength = RSA_KEY_BIT_LENGTH;
286aaf3206fSVernon Mauery         std::optional<std::string> optKeyCurveId = "secp384r1";
28730215816SMarri Devender Rao         std::optional<std::string> optKeyPairAlgorithm = "EC";
28830215816SMarri Devender Rao         std::optional<std::vector<std::string>> optKeyUsage =
28930215816SMarri Devender Rao             std::vector<std::string>();
29030215816SMarri Devender Rao         std::optional<std::string> optSurname = "";
29130215816SMarri Devender Rao         std::optional<std::string> optUnstructuredName = "";
29230215816SMarri Devender Rao         if (!json_util::readJson(
29330215816SMarri Devender Rao                 req, asyncResp->res, "City", city, "CommonName", commonName,
29430215816SMarri Devender Rao                 "ContactPerson", optContactPerson, "Country", country,
29530215816SMarri Devender Rao                 "Organization", organization, "OrganizationalUnit",
29630215816SMarri Devender Rao                 organizationalUnit, "State", state, "CertificateCollection",
29730215816SMarri Devender Rao                 certificateCollection, "AlternativeNames", optAlternativeNames,
29830215816SMarri Devender Rao                 "ChallengePassword", optChallengePassword, "Email", optEmail,
29930215816SMarri Devender Rao                 "GivenName", optGivenName, "Initials", optInitials,
30030215816SMarri Devender Rao                 "KeyBitLength", optKeyBitLength, "KeyCurveId", optKeyCurveId,
30130215816SMarri Devender Rao                 "KeyPairAlgorithm", optKeyPairAlgorithm, "KeyUsage",
30230215816SMarri Devender Rao                 optKeyUsage, "Surname", optSurname, "UnstructuredName",
30330215816SMarri Devender Rao                 optUnstructuredName))
30430215816SMarri Devender Rao         {
30530215816SMarri Devender Rao             return;
30630215816SMarri Devender Rao         }
30730215816SMarri Devender Rao 
30830215816SMarri Devender Rao         // bmcweb has no way to store or decode a private key challenge
30930215816SMarri Devender Rao         // password, which will likely cause bmcweb to crash on startup if this
31030215816SMarri Devender Rao         // is not set on a post so not allowing the user to set value
31130215816SMarri Devender Rao         if (*optChallengePassword != "")
31230215816SMarri Devender Rao         {
31330215816SMarri Devender Rao             messages::actionParameterNotSupported(asyncResp->res, "GenerateCSR",
31430215816SMarri Devender Rao                                                   "ChallengePassword");
31530215816SMarri Devender Rao             return;
31630215816SMarri Devender Rao         }
31730215816SMarri Devender Rao 
31830215816SMarri Devender Rao         std::string certURI;
31930215816SMarri Devender Rao         if (!redfish::json_util::readJson(certificateCollection, asyncResp->res,
32030215816SMarri Devender Rao                                           "@odata.id", 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;
32730215816SMarri Devender Rao         if (boost::starts_with(
32830215816SMarri Devender Rao                 certURI,
32930215816SMarri Devender Rao                 "/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(
3353b7f0149SMarri Devender Rao                      certURI, "/redfish/v1/AccountService/LDAP/Certificates"))
3363b7f0149SMarri Devender Rao         {
3373b7f0149SMarri Devender Rao             objectPath = certs::ldapObjectPath;
3383b7f0149SMarri Devender Rao             service = certs::ldapServiceName;
3393b7f0149SMarri Devender Rao         }
34030215816SMarri Devender Rao         else
34130215816SMarri Devender Rao         {
34230215816SMarri Devender Rao             messages::actionParameterNotSupported(
34330215816SMarri Devender Rao                 asyncResp->res, "CertificateCollection", "GenerateCSR");
34430215816SMarri Devender Rao             return;
34530215816SMarri Devender Rao         }
34630215816SMarri Devender Rao 
34730215816SMarri Devender Rao         // supporting only EC and RSA algorithm
34830215816SMarri Devender Rao         if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
34930215816SMarri Devender Rao         {
35030215816SMarri Devender Rao             messages::actionParameterNotSupported(
35130215816SMarri Devender Rao                 asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
35230215816SMarri Devender Rao             return;
35330215816SMarri Devender Rao         }
35430215816SMarri Devender Rao 
35530215816SMarri Devender Rao         // supporting only 2048 key bit length for RSA algorithm due to time
35630215816SMarri Devender Rao         // consumed in generating private key
35730215816SMarri Devender Rao         if (*optKeyPairAlgorithm == "RSA" &&
35830215816SMarri Devender Rao             *optKeyBitLength != RSA_KEY_BIT_LENGTH)
35930215816SMarri Devender Rao         {
36030215816SMarri Devender Rao             messages::propertyValueNotInList(asyncResp->res,
36130215816SMarri Devender Rao                                              std::to_string(*optKeyBitLength),
36230215816SMarri Devender Rao                                              "KeyBitLength");
36330215816SMarri Devender Rao             return;
36430215816SMarri Devender Rao         }
36530215816SMarri Devender Rao 
36630215816SMarri Devender Rao         // validate KeyUsage supporting only 1 type based on URL
36730215816SMarri Devender Rao         if (boost::starts_with(
36830215816SMarri Devender Rao                 certURI,
36930215816SMarri Devender Rao                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
37030215816SMarri Devender Rao         {
37130215816SMarri Devender Rao             if (optKeyUsage->size() == 0)
37230215816SMarri Devender Rao             {
37330215816SMarri Devender Rao                 optKeyUsage->push_back("ServerAuthentication");
37430215816SMarri Devender Rao             }
37530215816SMarri Devender Rao             else if (optKeyUsage->size() == 1)
37630215816SMarri Devender Rao             {
37730215816SMarri Devender Rao                 if ((*optKeyUsage)[0] != "ServerAuthentication")
37830215816SMarri Devender Rao                 {
37930215816SMarri Devender Rao                     messages::propertyValueNotInList(
38030215816SMarri Devender Rao                         asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
38130215816SMarri Devender Rao                     return;
38230215816SMarri Devender Rao                 }
38330215816SMarri Devender Rao             }
38430215816SMarri Devender Rao             else
38530215816SMarri Devender Rao             {
38630215816SMarri Devender Rao                 messages::actionParameterNotSupported(
38730215816SMarri Devender Rao                     asyncResp->res, "KeyUsage", "GenerateCSR");
38830215816SMarri Devender Rao                 return;
38930215816SMarri Devender Rao             }
39030215816SMarri Devender Rao         }
3913b7f0149SMarri Devender Rao         else if (boost::starts_with(
3923b7f0149SMarri Devender Rao                      certURI, "/redfish/v1/AccountService/LDAP/Certificates"))
3933b7f0149SMarri Devender Rao         {
3943b7f0149SMarri Devender Rao             if (optKeyUsage->size() == 0)
3953b7f0149SMarri Devender Rao             {
3963b7f0149SMarri Devender Rao                 optKeyUsage->push_back("ClientAuthentication");
3973b7f0149SMarri Devender Rao             }
3983b7f0149SMarri Devender Rao             else if (optKeyUsage->size() == 1)
3993b7f0149SMarri Devender Rao             {
4003b7f0149SMarri Devender Rao                 if ((*optKeyUsage)[0] != "ClientAuthentication")
4013b7f0149SMarri Devender Rao                 {
4023b7f0149SMarri Devender Rao                     messages::propertyValueNotInList(
4033b7f0149SMarri Devender Rao                         asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
4043b7f0149SMarri Devender Rao                     return;
4053b7f0149SMarri Devender Rao                 }
4063b7f0149SMarri Devender Rao             }
4073b7f0149SMarri Devender Rao             else
4083b7f0149SMarri Devender Rao             {
4093b7f0149SMarri Devender Rao                 messages::actionParameterNotSupported(
4103b7f0149SMarri Devender Rao                     asyncResp->res, "KeyUsage", "GenerateCSR");
4113b7f0149SMarri Devender Rao                 return;
4123b7f0149SMarri Devender Rao             }
4133b7f0149SMarri Devender Rao         }
41430215816SMarri Devender Rao 
41530215816SMarri Devender Rao         // Only allow one CSR matcher at a time so setting retry time-out and
41630215816SMarri Devender Rao         // timer expiry to 10 seconds for now.
41730215816SMarri Devender Rao         static const int TIME_OUT = 10;
41830215816SMarri Devender Rao         if (csrMatcher)
41930215816SMarri Devender Rao         {
42030215816SMarri Devender Rao             messages::serviceTemporarilyUnavailable(asyncResp->res,
42130215816SMarri Devender Rao                                                     std::to_string(TIME_OUT));
42230215816SMarri Devender Rao             return;
42330215816SMarri Devender Rao         }
42430215816SMarri Devender Rao 
42530215816SMarri Devender Rao         // Make this static so it survives outside this method
42630215816SMarri Devender Rao         static boost::asio::steady_timer timeout(*req.ioService);
42730215816SMarri Devender Rao         timeout.expires_after(std::chrono::seconds(TIME_OUT));
42830215816SMarri Devender Rao         timeout.async_wait([asyncResp](const boost::system::error_code& ec) {
42930215816SMarri Devender Rao             csrMatcher = nullptr;
43030215816SMarri Devender Rao             if (ec)
43130215816SMarri Devender Rao             {
43230215816SMarri Devender Rao                 // operation_aborted is expected if timer is canceled before
43330215816SMarri Devender Rao                 // completion.
43430215816SMarri Devender Rao                 if (ec != boost::asio::error::operation_aborted)
43530215816SMarri Devender Rao                 {
43630215816SMarri Devender Rao                     BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
43730215816SMarri Devender Rao                 }
43830215816SMarri Devender Rao                 return;
43930215816SMarri Devender Rao             }
44030215816SMarri Devender Rao             BMCWEB_LOG_ERROR << "Timed out waiting for Generating CSR";
44130215816SMarri Devender Rao             messages::internalError(asyncResp->res);
44230215816SMarri Devender Rao         });
44330215816SMarri Devender Rao 
44430215816SMarri Devender Rao         // create a matcher to wait on CSR object
44530215816SMarri Devender Rao         BMCWEB_LOG_DEBUG << "create matcher with path " << objectPath;
44630215816SMarri Devender Rao         std::string match("type='signal',"
44730215816SMarri Devender Rao                           "interface='org.freedesktop.DBus.ObjectManager',"
44830215816SMarri Devender Rao                           "path='" +
44930215816SMarri Devender Rao                           objectPath +
45030215816SMarri Devender Rao                           "',"
45130215816SMarri Devender Rao                           "member='InterfacesAdded'");
45230215816SMarri Devender Rao         csrMatcher = std::make_unique<sdbusplus::bus::match::match>(
45330215816SMarri Devender Rao             *crow::connections::systemBus, match,
45430215816SMarri Devender Rao             [asyncResp, service, objectPath,
45530215816SMarri Devender Rao              certURI](sdbusplus::message::message& m) {
456271584abSEd Tanous                 timeout.cancel();
45730215816SMarri Devender Rao                 if (m.is_method_error())
45830215816SMarri Devender Rao                 {
45930215816SMarri Devender Rao                     BMCWEB_LOG_ERROR << "Dbus method error!!!";
46030215816SMarri Devender Rao                     messages::internalError(asyncResp->res);
46130215816SMarri Devender Rao                     return;
46230215816SMarri Devender Rao                 }
46330215816SMarri Devender Rao                 std::vector<std::pair<
46430215816SMarri Devender Rao                     std::string, std::vector<std::pair<
46530215816SMarri Devender Rao                                      std::string, std::variant<std::string>>>>>
46630215816SMarri Devender Rao                     interfacesProperties;
46730215816SMarri Devender Rao                 sdbusplus::message::object_path csrObjectPath;
46830215816SMarri Devender Rao                 m.read(csrObjectPath, interfacesProperties);
46930215816SMarri Devender Rao                 BMCWEB_LOG_DEBUG << "CSR object added" << csrObjectPath.str;
47030215816SMarri Devender Rao                 for (auto& interface : interfacesProperties)
47130215816SMarri Devender Rao                 {
47230215816SMarri Devender Rao                     if (interface.first == "xyz.openbmc_project.Certs.CSR")
47330215816SMarri Devender Rao                     {
47430215816SMarri Devender Rao                         getCSR(asyncResp, certURI, service, objectPath,
47530215816SMarri Devender Rao                                csrObjectPath.str);
47630215816SMarri Devender Rao                         break;
47730215816SMarri Devender Rao                     }
47830215816SMarri Devender Rao                 }
47930215816SMarri Devender Rao             });
48030215816SMarri Devender Rao         crow::connections::systemBus->async_method_call(
481271584abSEd Tanous             [asyncResp](const boost::system::error_code& ec,
482*cb13a392SEd Tanous                         const std::string&) {
48330215816SMarri Devender Rao                 if (ec)
48430215816SMarri Devender Rao                 {
48530215816SMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec.message();
48630215816SMarri Devender Rao                     messages::internalError(asyncResp->res);
48730215816SMarri Devender Rao                     return;
48830215816SMarri Devender Rao                 }
48930215816SMarri Devender Rao             },
49030215816SMarri Devender Rao             service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
49130215816SMarri Devender Rao             "GenerateCSR", *optAlternativeNames, *optChallengePassword, city,
49230215816SMarri Devender Rao             commonName, *optContactPerson, country, *optEmail, *optGivenName,
49330215816SMarri Devender Rao             *optInitials, *optKeyBitLength, *optKeyCurveId,
49430215816SMarri Devender Rao             *optKeyPairAlgorithm, *optKeyUsage, organization,
49530215816SMarri Devender Rao             organizationalUnit, state, *optSurname, *optUnstructuredName);
49630215816SMarri Devender Rao     }
49730215816SMarri Devender Rao }; // CertificateActionGenerateCSR
49830215816SMarri Devender Rao 
4995968caeeSMarri Devender Rao /**
5004e0453b1SGunnar Mills  * @brief Parse and update Certificate Issue/Subject property
5015968caeeSMarri Devender Rao  *
5025968caeeSMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
5035968caeeSMarri Devender Rao  * @param[in] str  Issuer/Subject value in key=value pairs
5045968caeeSMarri Devender Rao  * @param[in] type Issuer/Subject
5055968caeeSMarri Devender Rao  * @return None
5065968caeeSMarri Devender Rao  */
5075968caeeSMarri Devender Rao static void updateCertIssuerOrSubject(nlohmann::json& out,
5085968caeeSMarri Devender Rao                                       const std::string_view value)
5095968caeeSMarri Devender Rao {
5105968caeeSMarri Devender Rao     // example: O=openbmc-project.xyz,CN=localhost
5115968caeeSMarri Devender Rao     std::string_view::iterator i = value.begin();
5125968caeeSMarri Devender Rao     while (i != value.end())
5135968caeeSMarri Devender Rao     {
5145968caeeSMarri Devender Rao         std::string_view::iterator tokenBegin = i;
5155968caeeSMarri Devender Rao         while (i != value.end() && *i != '=')
5165968caeeSMarri Devender Rao         {
5175968caeeSMarri Devender Rao             i++;
5185968caeeSMarri Devender Rao         }
5195968caeeSMarri Devender Rao         if (i == value.end())
5205968caeeSMarri Devender Rao         {
5215968caeeSMarri Devender Rao             break;
5225968caeeSMarri Devender Rao         }
523271584abSEd Tanous         const std::string_view key(tokenBegin,
524271584abSEd Tanous                                    static_cast<size_t>(i - tokenBegin));
5255968caeeSMarri Devender Rao         i++;
5265968caeeSMarri Devender Rao         tokenBegin = i;
5275968caeeSMarri Devender Rao         while (i != value.end() && *i != ',')
5285968caeeSMarri Devender Rao         {
5295968caeeSMarri Devender Rao             i++;
5305968caeeSMarri Devender Rao         }
531271584abSEd Tanous         const std::string_view val(tokenBegin,
532271584abSEd Tanous                                    static_cast<size_t>(i - tokenBegin));
5335968caeeSMarri Devender Rao         if (key == "L")
5345968caeeSMarri Devender Rao         {
5355968caeeSMarri Devender Rao             out["City"] = val;
5365968caeeSMarri Devender Rao         }
5375968caeeSMarri Devender Rao         else if (key == "CN")
5385968caeeSMarri Devender Rao         {
5395968caeeSMarri Devender Rao             out["CommonName"] = val;
5405968caeeSMarri Devender Rao         }
5415968caeeSMarri Devender Rao         else if (key == "C")
5425968caeeSMarri Devender Rao         {
5435968caeeSMarri Devender Rao             out["Country"] = val;
5445968caeeSMarri Devender Rao         }
5455968caeeSMarri Devender Rao         else if (key == "O")
5465968caeeSMarri Devender Rao         {
5475968caeeSMarri Devender Rao             out["Organization"] = val;
5485968caeeSMarri Devender Rao         }
5495968caeeSMarri Devender Rao         else if (key == "OU")
5505968caeeSMarri Devender Rao         {
5515968caeeSMarri Devender Rao             out["OrganizationalUnit"] = val;
5525968caeeSMarri Devender Rao         }
5535968caeeSMarri Devender Rao         else if (key == "ST")
5545968caeeSMarri Devender Rao         {
5555968caeeSMarri Devender Rao             out["State"] = val;
5565968caeeSMarri Devender Rao         }
5575968caeeSMarri Devender Rao         // skip comma character
5585968caeeSMarri Devender Rao         if (i != value.end())
5595968caeeSMarri Devender Rao         {
5605968caeeSMarri Devender Rao             i++;
5615968caeeSMarri Devender Rao         }
5625968caeeSMarri Devender Rao     }
5635968caeeSMarri Devender Rao }
5645968caeeSMarri Devender Rao 
5655968caeeSMarri Devender Rao /**
5665968caeeSMarri Devender Rao  * @brief Retrieve the certificates properties and append to the response
5675968caeeSMarri Devender Rao  * message
5685968caeeSMarri Devender Rao  *
5695968caeeSMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
5705968caeeSMarri Devender Rao  * @param[in] objectPath  Path of the D-Bus service object
5715968caeeSMarri Devender Rao  * @param[in] certId  Id of the certificate
5725968caeeSMarri Devender Rao  * @param[in] certURL  URL of the certificate object
5735968caeeSMarri Devender Rao  * @param[in] name  name of the certificate
5745968caeeSMarri Devender Rao  * @return None
5755968caeeSMarri Devender Rao  */
5765968caeeSMarri Devender Rao static void getCertificateProperties(
5775968caeeSMarri Devender Rao     const std::shared_ptr<AsyncResp>& asyncResp, const std::string& objectPath,
57837cce918SMarri Devender Rao     const std::string& service, long certId, const std::string& certURL,
57937cce918SMarri Devender Rao     const std::string& name)
5805968caeeSMarri Devender Rao {
5815968caeeSMarri Devender Rao     using PropertyType =
5825968caeeSMarri Devender Rao         std::variant<std::string, uint64_t, std::vector<std::string>>;
5835968caeeSMarri Devender Rao     using PropertiesMap = boost::container::flat_map<std::string, PropertyType>;
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(
58737cce918SMarri Devender Rao         [asyncResp, certURL, certId, name](const boost::system::error_code ec,
5885968caeeSMarri Devender Rao                                            const PropertiesMap& properties) {
5895968caeeSMarri Devender Rao             if (ec)
5905968caeeSMarri Devender Rao             {
5915968caeeSMarri Devender Rao                 BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
5928aae75adSMarri Devender Rao                 messages::resourceNotFound(asyncResp->res, name,
5938aae75adSMarri Devender Rao                                            std::to_string(certId));
5945968caeeSMarri Devender Rao                 return;
5955968caeeSMarri Devender Rao             }
5965968caeeSMarri Devender Rao             asyncResp->res.jsonValue = {
5975968caeeSMarri Devender Rao                 {"@odata.id", certURL},
5985968caeeSMarri Devender Rao                 {"@odata.type", "#Certificate.v1_0_0.Certificate"},
5995968caeeSMarri Devender Rao                 {"Id", std::to_string(certId)},
6005968caeeSMarri Devender Rao                 {"Name", name},
6015968caeeSMarri Devender Rao                 {"Description", name}};
6025968caeeSMarri Devender Rao             for (const auto& property : properties)
6035968caeeSMarri Devender Rao             {
6045968caeeSMarri Devender Rao                 if (property.first == "CertificateString")
6055968caeeSMarri Devender Rao                 {
6065968caeeSMarri Devender Rao                     asyncResp->res.jsonValue["CertificateString"] = "";
6075968caeeSMarri Devender Rao                     const std::string* value =
6085968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
6095968caeeSMarri Devender Rao                     if (value)
6105968caeeSMarri Devender Rao                     {
61137cce918SMarri Devender Rao                         asyncResp->res.jsonValue["CertificateString"] = *value;
6125968caeeSMarri Devender Rao                     }
6135968caeeSMarri Devender Rao                 }
6145968caeeSMarri Devender Rao                 else if (property.first == "KeyUsage")
6155968caeeSMarri Devender Rao                 {
6165968caeeSMarri Devender Rao                     nlohmann::json& keyUsage =
6175968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["KeyUsage"];
6185968caeeSMarri Devender Rao                     keyUsage = nlohmann::json::array();
6195968caeeSMarri Devender Rao                     const std::vector<std::string>* value =
62037cce918SMarri Devender Rao                         std::get_if<std::vector<std::string>>(&property.second);
6215968caeeSMarri Devender Rao                     if (value)
6225968caeeSMarri Devender Rao                     {
6235968caeeSMarri Devender Rao                         for (const std::string& usage : *value)
6245968caeeSMarri Devender Rao                         {
6255968caeeSMarri Devender Rao                             keyUsage.push_back(usage);
6265968caeeSMarri Devender Rao                         }
6275968caeeSMarri Devender Rao                     }
6285968caeeSMarri Devender Rao                 }
6295968caeeSMarri Devender Rao                 else if (property.first == "Issuer")
6305968caeeSMarri Devender Rao                 {
6315968caeeSMarri Devender Rao                     const std::string* value =
6325968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
6335968caeeSMarri Devender Rao                     if (value)
6345968caeeSMarri Devender Rao                     {
6355968caeeSMarri Devender Rao                         updateCertIssuerOrSubject(
6365968caeeSMarri Devender Rao                             asyncResp->res.jsonValue["Issuer"], *value);
6375968caeeSMarri Devender Rao                     }
6385968caeeSMarri Devender Rao                 }
6395968caeeSMarri Devender Rao                 else if (property.first == "Subject")
6405968caeeSMarri Devender Rao                 {
6415968caeeSMarri Devender Rao                     const std::string* value =
6425968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
6435968caeeSMarri Devender Rao                     if (value)
6445968caeeSMarri Devender Rao                     {
6455968caeeSMarri Devender Rao                         updateCertIssuerOrSubject(
64637cce918SMarri Devender Rao                             asyncResp->res.jsonValue["Subject"], *value);
6475968caeeSMarri Devender Rao                     }
6485968caeeSMarri Devender Rao                 }
6495968caeeSMarri Devender Rao                 else if (property.first == "ValidNotAfter")
6505968caeeSMarri Devender Rao                 {
6515968caeeSMarri Devender Rao                     const uint64_t* value =
6525968caeeSMarri Devender Rao                         std::get_if<uint64_t>(&property.second);
6535968caeeSMarri Devender Rao                     if (value)
6545968caeeSMarri Devender Rao                     {
65537cce918SMarri Devender Rao                         std::time_t time = static_cast<std::time_t>(*value);
6565968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["ValidNotAfter"] =
6575968caeeSMarri Devender Rao                             crow::utility::getDateTime(time);
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);
6645968caeeSMarri Devender Rao                     if (value)
6655968caeeSMarri Devender Rao                     {
66637cce918SMarri Devender Rao                         std::time_t time = static_cast<std::time_t>(*value);
6675968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["ValidNotBefore"] =
6685968caeeSMarri Devender Rao                             crow::utility::getDateTime(time);
6695968caeeSMarri Devender Rao                     }
6705968caeeSMarri Devender Rao                 }
6715968caeeSMarri Devender Rao             }
6725968caeeSMarri Devender Rao             asyncResp->res.addHeader("Location", certURL);
6735968caeeSMarri Devender Rao         },
6745968caeeSMarri Devender Rao         service, objectPath, certs::dbusPropIntf, "GetAll",
6755968caeeSMarri Devender Rao         certs::certPropIntf);
6765968caeeSMarri Devender Rao }
6775968caeeSMarri Devender Rao 
6785968caeeSMarri Devender Rao using GetObjectType =
6795968caeeSMarri Devender Rao     std::vector<std::pair<std::string, std::vector<std::string>>>;
6805968caeeSMarri Devender Rao 
6815968caeeSMarri Devender Rao /**
6825968caeeSMarri Devender Rao  * Action to replace an existing certificate
6835968caeeSMarri Devender Rao  */
6845968caeeSMarri Devender Rao class CertificateActionsReplaceCertificate : public Node
6855968caeeSMarri Devender Rao {
6865968caeeSMarri Devender Rao   public:
68752cc112dSEd Tanous     CertificateActionsReplaceCertificate(App& app) :
6885968caeeSMarri Devender Rao         Node(app, "/redfish/v1/CertificateService/Actions/"
6895968caeeSMarri Devender Rao                   "CertificateService.ReplaceCertificate/")
6905968caeeSMarri Devender Rao     {
6915968caeeSMarri Devender Rao         entityPrivileges = {
6925968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
6935968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
6945968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
6955968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
6965968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
6975968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
6985968caeeSMarri Devender Rao     }
6995968caeeSMarri Devender Rao 
7005968caeeSMarri Devender Rao   private:
7015968caeeSMarri Devender Rao     void doPost(crow::Response& res, const crow::Request& req,
702*cb13a392SEd Tanous                 const std::vector<std::string>&) override
7035968caeeSMarri Devender Rao     {
7045968caeeSMarri Devender Rao         std::string certificate;
7055968caeeSMarri Devender Rao         nlohmann::json certificateUri;
7065968caeeSMarri Devender Rao         std::optional<std::string> certificateType = "PEM";
7075968caeeSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
7085968caeeSMarri Devender Rao         if (!json_util::readJson(req, asyncResp->res, "CertificateString",
7095968caeeSMarri Devender Rao                                  certificate, "CertificateUri", certificateUri,
7105968caeeSMarri Devender Rao                                  "CertificateType", certificateType))
7115968caeeSMarri Devender Rao         {
7125968caeeSMarri Devender Rao             BMCWEB_LOG_ERROR << "Required parameters are missing";
7135968caeeSMarri Devender Rao             messages::internalError(asyncResp->res);
7145968caeeSMarri Devender Rao             return;
7155968caeeSMarri Devender Rao         }
7165968caeeSMarri Devender Rao 
7175968caeeSMarri Devender Rao         if (!certificateType)
7185968caeeSMarri Devender Rao         {
7195968caeeSMarri Devender Rao             // should never happen, but it never hurts to be paranoid.
7205968caeeSMarri Devender Rao             return;
7215968caeeSMarri Devender Rao         }
7225968caeeSMarri Devender Rao         if (certificateType != "PEM")
7235968caeeSMarri Devender Rao         {
7245968caeeSMarri Devender Rao             messages::actionParameterNotSupported(
7255968caeeSMarri Devender Rao                 asyncResp->res, "CertificateType", "ReplaceCertificate");
7265968caeeSMarri Devender Rao             return;
7275968caeeSMarri Devender Rao         }
7285968caeeSMarri Devender Rao 
7295968caeeSMarri Devender Rao         std::string certURI;
7305968caeeSMarri Devender Rao         if (!redfish::json_util::readJson(certificateUri, asyncResp->res,
7315968caeeSMarri Devender Rao                                           "@odata.id", certURI))
7325968caeeSMarri Devender Rao         {
7335968caeeSMarri Devender Rao             messages::actionParameterMissing(
7345968caeeSMarri Devender Rao                 asyncResp->res, "ReplaceCertificate", "CertificateUri");
7355968caeeSMarri Devender Rao             return;
7365968caeeSMarri Devender Rao         }
7375968caeeSMarri Devender Rao 
7385968caeeSMarri Devender Rao         BMCWEB_LOG_INFO << "Certificate URI to replace" << certURI;
7395968caeeSMarri Devender Rao         long id = getIDFromURL(certURI);
7405968caeeSMarri Devender Rao         if (id < 0)
7415968caeeSMarri Devender Rao         {
7425968caeeSMarri Devender Rao             messages::actionParameterValueFormatError(asyncResp->res, certURI,
7435968caeeSMarri Devender Rao                                                       "CertificateUri",
7445968caeeSMarri Devender Rao                                                       "ReplaceCertificate");
7455968caeeSMarri Devender Rao             return;
7465968caeeSMarri Devender Rao         }
7475968caeeSMarri Devender Rao         std::string objectPath;
7485968caeeSMarri Devender Rao         std::string name;
74937cce918SMarri Devender Rao         std::string service;
7505968caeeSMarri Devender Rao         if (boost::starts_with(
7515968caeeSMarri Devender Rao                 certURI,
7525968caeeSMarri Devender Rao                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/"))
7535968caeeSMarri Devender Rao         {
7545968caeeSMarri Devender Rao             objectPath =
7555968caeeSMarri Devender Rao                 std::string(certs::httpsObjectPath) + "/" + std::to_string(id);
7565968caeeSMarri Devender Rao             name = "HTTPS certificate";
75737cce918SMarri Devender Rao             service = certs::httpsServiceName;
75837cce918SMarri Devender Rao         }
75937cce918SMarri Devender Rao         else if (boost::starts_with(
76037cce918SMarri Devender Rao                      certURI, "/redfish/v1/AccountService/LDAP/Certificates/"))
76137cce918SMarri Devender Rao         {
76237cce918SMarri Devender Rao             objectPath =
76337cce918SMarri Devender Rao                 std::string(certs::ldapObjectPath) + "/" + std::to_string(id);
76437cce918SMarri Devender Rao             name = "LDAP certificate";
76537cce918SMarri Devender Rao             service = certs::ldapServiceName;
7665968caeeSMarri Devender Rao         }
767cfcd5f6bSMarri Devender Rao         else if (boost::starts_with(
768cfcd5f6bSMarri Devender Rao                      certURI,
769cfcd5f6bSMarri Devender Rao                      "/redfish/v1/Managers/bmc/Truststore/Certificates/"))
770cfcd5f6bSMarri Devender Rao         {
771cfcd5f6bSMarri Devender Rao             objectPath = std::string(certs::authorityObjectPath) + "/" +
772cfcd5f6bSMarri Devender Rao                          std::to_string(id);
773cfcd5f6bSMarri Devender Rao             name = "TrustStore certificate";
774cfcd5f6bSMarri Devender Rao             service = certs::authorityServiceName;
775cfcd5f6bSMarri Devender Rao         }
7765968caeeSMarri Devender Rao         else
7775968caeeSMarri Devender Rao         {
7785968caeeSMarri Devender Rao             messages::actionParameterNotSupported(
7795968caeeSMarri Devender Rao                 asyncResp->res, "CertificateUri", "ReplaceCertificate");
7805968caeeSMarri Devender Rao             return;
7815968caeeSMarri Devender Rao         }
7825968caeeSMarri Devender Rao 
7835968caeeSMarri Devender Rao         std::shared_ptr<CertificateFile> certFile =
7845968caeeSMarri Devender Rao             std::make_shared<CertificateFile>(certificate);
7855968caeeSMarri Devender Rao         crow::connections::systemBus->async_method_call(
78637cce918SMarri Devender Rao             [asyncResp, certFile, objectPath, service, certURI, id,
7875968caeeSMarri Devender Rao              name](const boost::system::error_code ec) {
7885968caeeSMarri Devender Rao                 if (ec)
7895968caeeSMarri Devender Rao                 {
7905968caeeSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
7918aae75adSMarri Devender Rao                     messages::resourceNotFound(asyncResp->res, name,
7928aae75adSMarri Devender Rao                                                std::to_string(id));
7935968caeeSMarri Devender Rao                     return;
7945968caeeSMarri Devender Rao                 }
79537cce918SMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath, service, id,
7965968caeeSMarri Devender Rao                                          certURI, name);
7975968caeeSMarri Devender Rao                 BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
7985968caeeSMarri Devender Rao                                  << certFile->getCertFilePath();
7995968caeeSMarri Devender Rao             },
8005968caeeSMarri Devender Rao             service, objectPath, certs::certReplaceIntf, "Replace",
8015968caeeSMarri Devender Rao             certFile->getCertFilePath());
8025968caeeSMarri Devender Rao     }
8035968caeeSMarri Devender Rao }; // CertificateActionsReplaceCertificate
8045968caeeSMarri Devender Rao 
8055968caeeSMarri Devender Rao /**
8065968caeeSMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
8075968caeeSMarri Devender Rao  * of a component, account or service.
8085968caeeSMarri Devender Rao  */
8095968caeeSMarri Devender Rao class HTTPSCertificate : public Node
8105968caeeSMarri Devender Rao {
8115968caeeSMarri Devender Rao   public:
81252cc112dSEd Tanous     HTTPSCertificate(App& app) :
8135968caeeSMarri Devender Rao         Node(app,
8145968caeeSMarri Devender Rao              "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/"
8155968caeeSMarri Devender Rao              "<str>/",
8165968caeeSMarri Devender Rao              std::string())
8175968caeeSMarri Devender Rao     {
8185968caeeSMarri Devender Rao         entityPrivileges = {
8195968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
8205968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
8215968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
8225968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
8235968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
8245968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
8255968caeeSMarri Devender Rao     }
8265968caeeSMarri Devender Rao 
8275968caeeSMarri Devender Rao     void doGet(crow::Response& res, const crow::Request& req,
8285968caeeSMarri Devender Rao                const std::vector<std::string>& params) override
8295968caeeSMarri Devender Rao     {
8305968caeeSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
8315968caeeSMarri Devender Rao         if (params.size() != 1)
8325968caeeSMarri Devender Rao         {
8335968caeeSMarri Devender Rao             messages::internalError(asyncResp->res);
8345968caeeSMarri Devender Rao             return;
8355968caeeSMarri Devender Rao         }
8365968caeeSMarri Devender Rao         long id = getIDFromURL(req.url);
8375968caeeSMarri Devender Rao 
8385968caeeSMarri Devender Rao         BMCWEB_LOG_DEBUG << "HTTPSCertificate::doGet ID=" << std::to_string(id);
8395968caeeSMarri Devender Rao         std::string certURL =
8405968caeeSMarri Devender Rao             "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" +
8415968caeeSMarri Devender Rao             std::to_string(id);
8425968caeeSMarri Devender Rao         std::string objectPath = certs::httpsObjectPath;
8435968caeeSMarri Devender Rao         objectPath += "/";
8445968caeeSMarri Devender Rao         objectPath += std::to_string(id);
84537cce918SMarri Devender Rao         getCertificateProperties(asyncResp, objectPath, certs::httpsServiceName,
84637cce918SMarri Devender Rao                                  id, certURL, "HTTPS Certificate");
8475968caeeSMarri Devender Rao     }
8485968caeeSMarri Devender Rao 
8495968caeeSMarri Devender Rao }; // namespace redfish
8505968caeeSMarri Devender Rao 
8515968caeeSMarri Devender Rao /**
8525968caeeSMarri Devender Rao  * Collection of HTTPS certificates
8535968caeeSMarri Devender Rao  */
8545968caeeSMarri Devender Rao class HTTPSCertificateCollection : public Node
8555968caeeSMarri Devender Rao {
8565968caeeSMarri Devender Rao   public:
85752cc112dSEd Tanous     HTTPSCertificateCollection(App& app) :
8585968caeeSMarri Devender Rao         Node(app,
8595968caeeSMarri Devender Rao              "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
8605968caeeSMarri Devender Rao     {
8615968caeeSMarri Devender Rao         entityPrivileges = {
8625968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
8635968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
8645968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
8655968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
8665968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
8675968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
8685968caeeSMarri Devender Rao     }
869*cb13a392SEd Tanous     void doGet(crow::Response& res, const crow::Request&,
870*cb13a392SEd Tanous                const std::vector<std::string>&) override
8715968caeeSMarri Devender Rao     {
8725968caeeSMarri Devender Rao         res.jsonValue = {
8735968caeeSMarri Devender Rao             {"@odata.id",
8745968caeeSMarri Devender Rao              "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"},
8755968caeeSMarri Devender Rao             {"@odata.type", "#CertificateCollection.CertificateCollection"},
8765968caeeSMarri Devender Rao             {"Name", "HTTPS Certificates Collection"},
8775968caeeSMarri Devender Rao             {"Description", "A Collection of HTTPS certificate instances"}};
8785968caeeSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
8795968caeeSMarri Devender Rao         crow::connections::systemBus->async_method_call(
8805968caeeSMarri Devender Rao             [asyncResp](const boost::system::error_code ec,
8815968caeeSMarri Devender Rao                         const ManagedObjectType& certs) {
8825968caeeSMarri Devender Rao                 if (ec)
8835968caeeSMarri Devender Rao                 {
8845968caeeSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
8855968caeeSMarri Devender Rao                     messages::internalError(asyncResp->res);
8865968caeeSMarri Devender Rao                     return;
8875968caeeSMarri Devender Rao                 }
88837cce918SMarri Devender Rao                 nlohmann::json& members = asyncResp->res.jsonValue["Members"];
8895968caeeSMarri Devender Rao                 members = nlohmann::json::array();
8905968caeeSMarri Devender Rao                 for (const auto& cert : certs)
8915968caeeSMarri Devender Rao                 {
8925968caeeSMarri Devender Rao                     long id = getIDFromURL(cert.first.str);
89337cce918SMarri Devender Rao                     if (id >= 0)
8945968caeeSMarri Devender Rao                     {
8955968caeeSMarri Devender Rao                         members.push_back(
8965968caeeSMarri Devender Rao                             {{"@odata.id",
8975968caeeSMarri Devender Rao                               "/redfish/v1/Managers/bmc/"
8985968caeeSMarri Devender Rao                               "NetworkProtocol/HTTPS/Certificates/" +
8995968caeeSMarri Devender Rao                                   std::to_string(id)}});
9005968caeeSMarri Devender Rao                     }
9015968caeeSMarri Devender Rao                 }
9025968caeeSMarri Devender Rao                 asyncResp->res.jsonValue["Members@odata.count"] =
9035968caeeSMarri Devender Rao                     members.size();
9045968caeeSMarri Devender Rao             },
90537cce918SMarri Devender Rao             certs::httpsServiceName, certs::httpsObjectPath,
90637cce918SMarri Devender Rao             certs::dbusObjManagerIntf, "GetManagedObjects");
9075968caeeSMarri Devender Rao     }
9085968caeeSMarri Devender Rao 
9095968caeeSMarri Devender Rao     void doPost(crow::Response& res, const crow::Request& req,
910*cb13a392SEd Tanous                 const std::vector<std::string>&) override
9115968caeeSMarri Devender Rao     {
9125968caeeSMarri Devender Rao         BMCWEB_LOG_DEBUG << "HTTPSCertificateCollection::doPost";
9135968caeeSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
9145968caeeSMarri Devender Rao         asyncResp->res.jsonValue = {{"Name", "HTTPS Certificate"},
9155968caeeSMarri Devender Rao                                     {"Description", "HTTPS Certificate"}};
9165968caeeSMarri Devender Rao 
91758eb238fSKowalski, Kamil         std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
91858eb238fSKowalski, Kamil 
91958eb238fSKowalski, Kamil         if (certFileBody.empty())
92058eb238fSKowalski, Kamil         {
921a08752f5SZbigniew Kurzynski             BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
922a08752f5SZbigniew Kurzynski             messages::unrecognizedRequestBody(asyncResp->res);
92358eb238fSKowalski, Kamil             return;
92458eb238fSKowalski, Kamil         }
92558eb238fSKowalski, Kamil 
9265968caeeSMarri Devender Rao         std::shared_ptr<CertificateFile> certFile =
92758eb238fSKowalski, Kamil             std::make_shared<CertificateFile>(certFileBody);
9285968caeeSMarri Devender Rao 
9295968caeeSMarri Devender Rao         crow::connections::systemBus->async_method_call(
930656ec7e3SZbigniew Kurzynski             [asyncResp, certFile](const boost::system::error_code ec,
931656ec7e3SZbigniew Kurzynski                                   const std::string& objectPath) {
9325968caeeSMarri Devender Rao                 if (ec)
9335968caeeSMarri Devender Rao                 {
9345968caeeSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
9355968caeeSMarri Devender Rao                     messages::internalError(asyncResp->res);
9365968caeeSMarri Devender Rao                     return;
9375968caeeSMarri Devender Rao                 }
938656ec7e3SZbigniew Kurzynski                 long certId = getIDFromURL(objectPath);
939656ec7e3SZbigniew Kurzynski                 if (certId < 0)
940656ec7e3SZbigniew Kurzynski                 {
941656ec7e3SZbigniew Kurzynski                     BMCWEB_LOG_ERROR << "Invalid objectPath value"
942656ec7e3SZbigniew Kurzynski                                      << objectPath;
943656ec7e3SZbigniew Kurzynski                     messages::internalError(asyncResp->res);
944656ec7e3SZbigniew Kurzynski                     return;
945656ec7e3SZbigniew Kurzynski                 }
9465968caeeSMarri Devender Rao                 std::string certURL =
9475968caeeSMarri Devender Rao                     "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/"
9485968caeeSMarri Devender Rao                     "Certificates/" +
9495968caeeSMarri Devender Rao                     std::to_string(certId);
95037cce918SMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath,
95137cce918SMarri Devender Rao                                          certs::httpsServiceName, certId,
9525968caeeSMarri Devender Rao                                          certURL, "HTTPS Certificate");
9535968caeeSMarri Devender Rao                 BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
9545968caeeSMarri Devender Rao                                  << certFile->getCertFilePath();
9555968caeeSMarri Devender Rao             },
95637cce918SMarri Devender Rao             certs::httpsServiceName, certs::httpsObjectPath,
95737cce918SMarri Devender Rao             certs::certInstallIntf, "Install", certFile->getCertFilePath());
9585968caeeSMarri Devender Rao     }
9595968caeeSMarri Devender Rao }; // HTTPSCertificateCollection
9605968caeeSMarri Devender Rao 
9615968caeeSMarri Devender Rao /**
9625968caeeSMarri Devender Rao  * The certificate location schema defines a resource that an administrator
9635968caeeSMarri Devender Rao  * can use in order to locate all certificates installed on a given service.
9645968caeeSMarri Devender Rao  */
9655968caeeSMarri Devender Rao class CertificateLocations : public Node
9665968caeeSMarri Devender Rao {
9675968caeeSMarri Devender Rao   public:
96852cc112dSEd Tanous     CertificateLocations(App& app) :
9695968caeeSMarri Devender Rao         Node(app, "/redfish/v1/CertificateService/CertificateLocations/")
9705968caeeSMarri Devender Rao     {
9715968caeeSMarri Devender Rao         entityPrivileges = {
9725968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
9735968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
9745968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
9755968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
9765968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
9775968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
9785968caeeSMarri Devender Rao     }
9795968caeeSMarri Devender Rao 
9805968caeeSMarri Devender Rao   private:
981*cb13a392SEd Tanous     void doGet(crow::Response& res, const crow::Request&,
982*cb13a392SEd Tanous                const std::vector<std::string>&) override
9835968caeeSMarri Devender Rao     {
9845968caeeSMarri Devender Rao         res.jsonValue = {
9855968caeeSMarri Devender Rao             {"@odata.id",
9865968caeeSMarri Devender Rao              "/redfish/v1/CertificateService/CertificateLocations"},
9875968caeeSMarri Devender Rao             {"@odata.type",
9885968caeeSMarri Devender Rao              "#CertificateLocations.v1_0_0.CertificateLocations"},
9895968caeeSMarri Devender Rao             {"Name", "Certificate Locations"},
9905968caeeSMarri Devender Rao             {"Id", "CertificateLocations"},
9915968caeeSMarri Devender Rao             {"Description",
9925968caeeSMarri Devender Rao              "Defines a resource that an administrator can use in order to "
9935968caeeSMarri Devender Rao              "locate all certificates installed on a given service"}};
9945968caeeSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
9955968caeeSMarri Devender Rao         nlohmann::json& links =
9965968caeeSMarri Devender Rao             asyncResp->res.jsonValue["Links"]["Certificates"];
9975968caeeSMarri Devender Rao         links = nlohmann::json::array();
9985968caeeSMarri Devender Rao         getCertificateLocations(
9995968caeeSMarri Devender Rao             asyncResp,
10005968caeeSMarri Devender Rao             "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/",
100137cce918SMarri Devender Rao             certs::httpsObjectPath, certs::httpsServiceName);
100237cce918SMarri Devender Rao         getCertificateLocations(asyncResp,
100337cce918SMarri Devender Rao                                 "/redfish/v1/AccountService/LDAP/Certificates/",
100437cce918SMarri Devender Rao                                 certs::ldapObjectPath, certs::ldapServiceName);
1005cfcd5f6bSMarri Devender Rao         getCertificateLocations(
1006cfcd5f6bSMarri Devender Rao             asyncResp, "/redfish/v1/Managers/bmc/Truststore/Certificates/",
1007cfcd5f6bSMarri Devender Rao             certs::authorityObjectPath, certs::authorityServiceName);
100837cce918SMarri Devender Rao     }
100937cce918SMarri Devender Rao     /**
101037cce918SMarri Devender Rao      * @brief Retrieve the certificates installed list and append to the
101137cce918SMarri Devender Rao      * response
101237cce918SMarri Devender Rao      *
101337cce918SMarri Devender Rao      * @param[in] asyncResp Shared pointer to the response message
101437cce918SMarri Devender Rao      * @param[in] certURL  Path of the certificate object
101537cce918SMarri Devender Rao      * @param[in] path  Path of the D-Bus service object
101637cce918SMarri Devender Rao      * @return None
101737cce918SMarri Devender Rao      */
101837cce918SMarri Devender Rao     void getCertificateLocations(std::shared_ptr<AsyncResp>& asyncResp,
101937cce918SMarri Devender Rao                                  const std::string& certURL,
102037cce918SMarri Devender Rao                                  const std::string& path,
102137cce918SMarri Devender Rao                                  const std::string& service)
102237cce918SMarri Devender Rao     {
102337cce918SMarri Devender Rao         BMCWEB_LOG_DEBUG << "getCertificateLocations URI=" << certURL
102437cce918SMarri Devender Rao                          << " Path=" << path << " service= " << service;
102537cce918SMarri Devender Rao         crow::connections::systemBus->async_method_call(
102637cce918SMarri Devender Rao             [asyncResp, certURL](const boost::system::error_code ec,
102737cce918SMarri Devender Rao                                  const ManagedObjectType& certs) {
102837cce918SMarri Devender Rao                 if (ec)
102937cce918SMarri Devender Rao                 {
103037cce918SMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
103137cce918SMarri Devender Rao                     messages::internalError(asyncResp->res);
103237cce918SMarri Devender Rao                     return;
103337cce918SMarri Devender Rao                 }
103437cce918SMarri Devender Rao                 nlohmann::json& links =
103537cce918SMarri Devender Rao                     asyncResp->res.jsonValue["Links"]["Certificates"];
103637cce918SMarri Devender Rao                 for (auto& cert : certs)
103737cce918SMarri Devender Rao                 {
103837cce918SMarri Devender Rao                     long id = getIDFromURL(cert.first.str);
103937cce918SMarri Devender Rao                     if (id >= 0)
104037cce918SMarri Devender Rao                     {
104137cce918SMarri Devender Rao                         links.push_back(
104237cce918SMarri Devender Rao                             {{"@odata.id", certURL + std::to_string(id)}});
104337cce918SMarri Devender Rao                     }
104437cce918SMarri Devender Rao                 }
104537cce918SMarri Devender Rao                 asyncResp->res.jsonValue["Links"]["Certificates@odata.count"] =
104637cce918SMarri Devender Rao                     links.size();
104737cce918SMarri Devender Rao             },
104837cce918SMarri Devender Rao             service, path, certs::dbusObjManagerIntf, "GetManagedObjects");
10495968caeeSMarri Devender Rao     }
10505968caeeSMarri Devender Rao }; // CertificateLocations
105137cce918SMarri Devender Rao 
105237cce918SMarri Devender Rao /**
105337cce918SMarri Devender Rao  * Collection of LDAP certificates
105437cce918SMarri Devender Rao  */
105537cce918SMarri Devender Rao class LDAPCertificateCollection : public Node
105637cce918SMarri Devender Rao {
105737cce918SMarri Devender Rao   public:
105852cc112dSEd Tanous     LDAPCertificateCollection(App& app) :
105937cce918SMarri Devender Rao         Node(app, "/redfish/v1/AccountService/LDAP/Certificates/")
106037cce918SMarri Devender Rao     {
106137cce918SMarri Devender Rao         entityPrivileges = {
106237cce918SMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
106337cce918SMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
106437cce918SMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
106537cce918SMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
106637cce918SMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
106737cce918SMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
106837cce918SMarri Devender Rao     }
1069*cb13a392SEd Tanous     void doGet(crow::Response& res, const crow::Request&,
1070*cb13a392SEd Tanous                const std::vector<std::string>&) override
107137cce918SMarri Devender Rao     {
107237cce918SMarri Devender Rao         res.jsonValue = {
107337cce918SMarri Devender Rao             {"@odata.id", "/redfish/v1/AccountService/LDAP/Certificates"},
107437cce918SMarri Devender Rao             {"@odata.type", "#CertificateCollection.CertificateCollection"},
107537cce918SMarri Devender Rao             {"Name", "LDAP Certificates Collection"},
107637cce918SMarri Devender Rao             {"Description", "A Collection of LDAP certificate instances"}};
107737cce918SMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
107837cce918SMarri Devender Rao         crow::connections::systemBus->async_method_call(
107937cce918SMarri Devender Rao             [asyncResp](const boost::system::error_code ec,
108037cce918SMarri Devender Rao                         const ManagedObjectType& certs) {
108137cce918SMarri Devender Rao                 if (ec)
108237cce918SMarri Devender Rao                 {
108337cce918SMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
108437cce918SMarri Devender Rao                     messages::internalError(asyncResp->res);
108537cce918SMarri Devender Rao                     return;
108637cce918SMarri Devender Rao                 }
108737cce918SMarri Devender Rao                 nlohmann::json& members = asyncResp->res.jsonValue["Members"];
108837cce918SMarri Devender Rao                 members = nlohmann::json::array();
108937cce918SMarri Devender Rao                 for (const auto& cert : certs)
109037cce918SMarri Devender Rao                 {
109137cce918SMarri Devender Rao                     long id = getIDFromURL(cert.first.str);
109237cce918SMarri Devender Rao                     if (id >= 0)
109337cce918SMarri Devender Rao                     {
109437cce918SMarri Devender Rao                         members.push_back(
109537cce918SMarri Devender Rao                             {{"@odata.id", "/redfish/v1/AccountService/"
109637cce918SMarri Devender Rao                                            "LDAP/Certificates/" +
109737cce918SMarri Devender Rao                                                std::to_string(id)}});
109837cce918SMarri Devender Rao                     }
109937cce918SMarri Devender Rao                 }
110037cce918SMarri Devender Rao                 asyncResp->res.jsonValue["Members@odata.count"] =
110137cce918SMarri Devender Rao                     members.size();
110237cce918SMarri Devender Rao             },
110337cce918SMarri Devender Rao             certs::ldapServiceName, certs::ldapObjectPath,
110437cce918SMarri Devender Rao             certs::dbusObjManagerIntf, "GetManagedObjects");
110537cce918SMarri Devender Rao     }
110637cce918SMarri Devender Rao 
110737cce918SMarri Devender Rao     void doPost(crow::Response& res, const crow::Request& req,
1108*cb13a392SEd Tanous                 const std::vector<std::string>&) override
110937cce918SMarri Devender Rao     {
111037cce918SMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
111158eb238fSKowalski, Kamil         std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
111258eb238fSKowalski, Kamil 
111358eb238fSKowalski, Kamil         if (certFileBody.empty())
111458eb238fSKowalski, Kamil         {
1115a08752f5SZbigniew Kurzynski             BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
1116a08752f5SZbigniew Kurzynski             messages::unrecognizedRequestBody(asyncResp->res);
111758eb238fSKowalski, Kamil             return;
111858eb238fSKowalski, Kamil         }
111958eb238fSKowalski, Kamil 
112058eb238fSKowalski, Kamil         std::shared_ptr<CertificateFile> certFile =
112158eb238fSKowalski, Kamil             std::make_shared<CertificateFile>(certFileBody);
112258eb238fSKowalski, Kamil 
112337cce918SMarri Devender Rao         crow::connections::systemBus->async_method_call(
1124656ec7e3SZbigniew Kurzynski             [asyncResp, certFile](const boost::system::error_code ec,
1125656ec7e3SZbigniew Kurzynski                                   const std::string& objectPath) {
112637cce918SMarri Devender Rao                 if (ec)
112737cce918SMarri Devender Rao                 {
112837cce918SMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
112937cce918SMarri Devender Rao                     messages::internalError(asyncResp->res);
113037cce918SMarri Devender Rao                     return;
113137cce918SMarri Devender Rao                 }
1132656ec7e3SZbigniew Kurzynski                 long certId = getIDFromURL(objectPath);
1133656ec7e3SZbigniew Kurzynski                 if (certId < 0)
1134656ec7e3SZbigniew Kurzynski                 {
1135656ec7e3SZbigniew Kurzynski                     BMCWEB_LOG_ERROR << "Invalid objectPath value"
1136656ec7e3SZbigniew Kurzynski                                      << objectPath;
1137656ec7e3SZbigniew Kurzynski                     messages::internalError(asyncResp->res);
1138656ec7e3SZbigniew Kurzynski                     return;
1139656ec7e3SZbigniew Kurzynski                 }
114037cce918SMarri Devender Rao                 std::string certURL =
114137cce918SMarri Devender Rao                     "/redfish/v1/AccountService/LDAP/Certificates/" +
114237cce918SMarri Devender Rao                     std::to_string(certId);
114337cce918SMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath,
114437cce918SMarri Devender Rao                                          certs::ldapServiceName, certId,
114537cce918SMarri Devender Rao                                          certURL, "LDAP Certificate");
114637cce918SMarri Devender Rao                 BMCWEB_LOG_DEBUG << "LDAP certificate install file="
114737cce918SMarri Devender Rao                                  << certFile->getCertFilePath();
114837cce918SMarri Devender Rao             },
114937cce918SMarri Devender Rao             certs::ldapServiceName, certs::ldapObjectPath,
115037cce918SMarri Devender Rao             certs::certInstallIntf, "Install", certFile->getCertFilePath());
115137cce918SMarri Devender Rao     }
115237cce918SMarri Devender Rao }; // LDAPCertificateCollection
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  */
115837cce918SMarri Devender Rao class LDAPCertificate : public Node
115937cce918SMarri Devender Rao {
116037cce918SMarri Devender Rao   public:
116152cc112dSEd Tanous     LDAPCertificate(App& app) :
116237cce918SMarri Devender Rao         Node(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/",
116337cce918SMarri Devender Rao              std::string())
116437cce918SMarri Devender Rao     {
116537cce918SMarri Devender Rao         entityPrivileges = {
116637cce918SMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
116737cce918SMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
116837cce918SMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
116937cce918SMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
117037cce918SMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
117137cce918SMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
117237cce918SMarri Devender Rao     }
117337cce918SMarri Devender Rao 
117437cce918SMarri Devender Rao     void doGet(crow::Response& res, const crow::Request& req,
1175*cb13a392SEd Tanous                const std::vector<std::string>&) override
117637cce918SMarri Devender Rao     {
117737cce918SMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
117837cce918SMarri Devender Rao         long id = getIDFromURL(req.url);
117937cce918SMarri Devender Rao         if (id < 0)
118037cce918SMarri Devender Rao         {
118137cce918SMarri Devender Rao             BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
118237cce918SMarri Devender Rao             messages::internalError(asyncResp->res);
118337cce918SMarri Devender Rao             return;
118437cce918SMarri Devender Rao         }
118537cce918SMarri Devender Rao         BMCWEB_LOG_DEBUG << "LDAP Certificate ID=" << std::to_string(id);
118637cce918SMarri Devender Rao         std::string certURL = "/redfish/v1/AccountService/LDAP/Certificates/" +
118737cce918SMarri Devender Rao                               std::to_string(id);
118837cce918SMarri Devender Rao         std::string objectPath = certs::ldapObjectPath;
118937cce918SMarri Devender Rao         objectPath += "/";
119037cce918SMarri Devender Rao         objectPath += std::to_string(id);
119137cce918SMarri Devender Rao         getCertificateProperties(asyncResp, objectPath, certs::ldapServiceName,
119237cce918SMarri Devender Rao                                  id, certURL, "LDAP Certificate");
119337cce918SMarri Devender Rao     }
119437cce918SMarri Devender Rao }; // LDAPCertificate
1195cfcd5f6bSMarri Devender Rao /**
1196cfcd5f6bSMarri Devender Rao  * Collection of TrustStoreCertificate certificates
1197cfcd5f6bSMarri Devender Rao  */
1198cfcd5f6bSMarri Devender Rao class TrustStoreCertificateCollection : public Node
1199cfcd5f6bSMarri Devender Rao {
1200cfcd5f6bSMarri Devender Rao   public:
120152cc112dSEd Tanous     TrustStoreCertificateCollection(App& app) :
1202cfcd5f6bSMarri Devender Rao         Node(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
1203cfcd5f6bSMarri Devender Rao     {
1204cfcd5f6bSMarri Devender Rao         entityPrivileges = {
1205cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
1206cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
1207cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1208cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1209cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1210cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1211cfcd5f6bSMarri Devender Rao     }
1212*cb13a392SEd Tanous     void doGet(crow::Response& res, const crow::Request&,
1213*cb13a392SEd Tanous                const std::vector<std::string>&) override
1214cfcd5f6bSMarri Devender Rao     {
1215cfcd5f6bSMarri Devender Rao         res.jsonValue = {
1216cfcd5f6bSMarri Devender Rao             {"@odata.id", "/redfish/v1/Managers/bmc/Truststore/Certificates/"},
1217cfcd5f6bSMarri Devender Rao             {"@odata.type", "#CertificateCollection.CertificateCollection"},
1218cfcd5f6bSMarri Devender Rao             {"Name", "TrustStore Certificates Collection"},
1219cfcd5f6bSMarri Devender Rao             {"Description",
1220cfcd5f6bSMarri Devender Rao              "A Collection of TrustStore certificate instances"}};
1221cfcd5f6bSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
1222cfcd5f6bSMarri Devender Rao         crow::connections::systemBus->async_method_call(
1223cfcd5f6bSMarri Devender Rao             [asyncResp](const boost::system::error_code ec,
1224cfcd5f6bSMarri Devender Rao                         const ManagedObjectType& certs) {
1225cfcd5f6bSMarri Devender Rao                 if (ec)
1226cfcd5f6bSMarri Devender Rao                 {
1227cfcd5f6bSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
1228cfcd5f6bSMarri Devender Rao                     messages::internalError(asyncResp->res);
1229cfcd5f6bSMarri Devender Rao                     return;
1230cfcd5f6bSMarri Devender Rao                 }
1231cfcd5f6bSMarri Devender Rao                 nlohmann::json& members = asyncResp->res.jsonValue["Members"];
1232cfcd5f6bSMarri Devender Rao                 members = nlohmann::json::array();
1233cfcd5f6bSMarri Devender Rao                 for (const auto& cert : certs)
1234cfcd5f6bSMarri Devender Rao                 {
1235cfcd5f6bSMarri Devender Rao                     long id = getIDFromURL(cert.first.str);
1236cfcd5f6bSMarri Devender Rao                     if (id >= 0)
1237cfcd5f6bSMarri Devender Rao                     {
1238cfcd5f6bSMarri Devender Rao                         members.push_back(
1239cfcd5f6bSMarri Devender Rao                             {{"@odata.id", "/redfish/v1/Managers/bmc/"
1240cfcd5f6bSMarri Devender Rao                                            "Truststore/Certificates/" +
1241cfcd5f6bSMarri Devender Rao                                                std::to_string(id)}});
1242cfcd5f6bSMarri Devender Rao                     }
1243cfcd5f6bSMarri Devender Rao                 }
1244cfcd5f6bSMarri Devender Rao                 asyncResp->res.jsonValue["Members@odata.count"] =
1245cfcd5f6bSMarri Devender Rao                     members.size();
1246cfcd5f6bSMarri Devender Rao             },
1247cfcd5f6bSMarri Devender Rao             certs::authorityServiceName, certs::authorityObjectPath,
1248cfcd5f6bSMarri Devender Rao             certs::dbusObjManagerIntf, "GetManagedObjects");
1249cfcd5f6bSMarri Devender Rao     }
1250cfcd5f6bSMarri Devender Rao 
1251cfcd5f6bSMarri Devender Rao     void doPost(crow::Response& res, const crow::Request& req,
1252*cb13a392SEd Tanous                 const std::vector<std::string>&) override
1253cfcd5f6bSMarri Devender Rao     {
1254cfcd5f6bSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
1255a08752f5SZbigniew Kurzynski         std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
1256a08752f5SZbigniew Kurzynski 
1257a08752f5SZbigniew Kurzynski         if (certFileBody.empty())
1258a08752f5SZbigniew Kurzynski         {
1259a08752f5SZbigniew Kurzynski             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                 }
1283cfcd5f6bSMarri Devender Rao                 std::string certURL = "/redfish/v1/Managers/bmc/"
1284cfcd5f6bSMarri Devender Rao                                       "Truststore/Certificates/" +
1285cfcd5f6bSMarri Devender Rao                                       std::to_string(certId);
1286656ec7e3SZbigniew Kurzynski 
1287cfcd5f6bSMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath,
1288cfcd5f6bSMarri Devender Rao                                          certs::authorityServiceName, certId,
1289cfcd5f6bSMarri Devender Rao                                          certURL, "TrustStore Certificate");
1290cfcd5f6bSMarri Devender Rao                 BMCWEB_LOG_DEBUG << "TrustStore certificate install file="
1291cfcd5f6bSMarri Devender Rao                                  << certFile->getCertFilePath();
1292cfcd5f6bSMarri Devender Rao             },
1293cfcd5f6bSMarri Devender Rao             certs::authorityServiceName, certs::authorityObjectPath,
1294cfcd5f6bSMarri Devender Rao             certs::certInstallIntf, "Install", certFile->getCertFilePath());
1295cfcd5f6bSMarri Devender Rao     }
1296cfcd5f6bSMarri Devender Rao }; // TrustStoreCertificateCollection
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  */
1302cfcd5f6bSMarri Devender Rao class TrustStoreCertificate : public Node
1303cfcd5f6bSMarri Devender Rao {
1304cfcd5f6bSMarri Devender Rao   public:
130552cc112dSEd Tanous     TrustStoreCertificate(App& app) :
1306cfcd5f6bSMarri Devender Rao         Node(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/",
1307cfcd5f6bSMarri Devender Rao              std::string())
1308cfcd5f6bSMarri Devender Rao     {
1309cfcd5f6bSMarri Devender Rao         entityPrivileges = {
1310cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
1311cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
1312cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1313cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1314cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1315cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1316cfcd5f6bSMarri Devender Rao     }
1317cfcd5f6bSMarri Devender Rao 
1318cfcd5f6bSMarri Devender Rao     void doGet(crow::Response& res, const crow::Request& req,
1319*cb13a392SEd Tanous                const std::vector<std::string>&) override
1320cfcd5f6bSMarri Devender Rao     {
1321cfcd5f6bSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
1322cfcd5f6bSMarri Devender Rao         long id = getIDFromURL(req.url);
1323cfcd5f6bSMarri Devender Rao         if (id < 0)
1324cfcd5f6bSMarri Devender Rao         {
1325cfcd5f6bSMarri Devender Rao             BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
1326cfcd5f6bSMarri Devender Rao             messages::internalError(asyncResp->res);
1327cfcd5f6bSMarri Devender Rao             return;
1328cfcd5f6bSMarri Devender Rao         }
1329cfcd5f6bSMarri Devender Rao         BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doGet ID="
1330cfcd5f6bSMarri Devender Rao                          << std::to_string(id);
1331cfcd5f6bSMarri Devender Rao         std::string certURL =
1332cfcd5f6bSMarri Devender Rao             "/redfish/v1/Managers/bmc/Truststore/Certificates/" +
1333cfcd5f6bSMarri Devender Rao             std::to_string(id);
1334cfcd5f6bSMarri Devender Rao         std::string objectPath = certs::authorityObjectPath;
1335cfcd5f6bSMarri Devender Rao         objectPath += "/";
1336cfcd5f6bSMarri Devender Rao         objectPath += std::to_string(id);
1337cfcd5f6bSMarri Devender Rao         getCertificateProperties(asyncResp, objectPath,
1338cfcd5f6bSMarri Devender Rao                                  certs::authorityServiceName, id, certURL,
1339cfcd5f6bSMarri Devender Rao                                  "TrustStore Certificate");
1340cfcd5f6bSMarri Devender Rao     }
134107a60299SZbigniew Kurzynski 
134207a60299SZbigniew Kurzynski     void doDelete(crow::Response& res, const crow::Request& req,
134307a60299SZbigniew Kurzynski                   const std::vector<std::string>& params) override
134407a60299SZbigniew Kurzynski     {
134507a60299SZbigniew Kurzynski         auto asyncResp = std::make_shared<AsyncResp>(res);
134607a60299SZbigniew Kurzynski 
134707a60299SZbigniew Kurzynski         if (params.size() != 1)
134807a60299SZbigniew Kurzynski         {
134907a60299SZbigniew Kurzynski             messages::internalError(asyncResp->res);
135007a60299SZbigniew Kurzynski             return;
135107a60299SZbigniew Kurzynski         }
135207a60299SZbigniew Kurzynski 
135307a60299SZbigniew Kurzynski         long id = getIDFromURL(req.url);
135407a60299SZbigniew Kurzynski         if (id < 0)
135507a60299SZbigniew Kurzynski         {
135607a60299SZbigniew Kurzynski             BMCWEB_LOG_ERROR << "Invalid url value: " << req.url;
135707a60299SZbigniew Kurzynski             messages::resourceNotFound(asyncResp->res, "TrustStore Certificate",
135807a60299SZbigniew Kurzynski                                        std::string(req.url));
135907a60299SZbigniew Kurzynski             return;
136007a60299SZbigniew Kurzynski         }
136107a60299SZbigniew Kurzynski         BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doDelete ID="
136207a60299SZbigniew Kurzynski                          << std::to_string(id);
136307a60299SZbigniew Kurzynski         std::string certPath = certs::authorityObjectPath;
136407a60299SZbigniew Kurzynski         certPath += "/";
136507a60299SZbigniew Kurzynski         certPath += std::to_string(id);
136607a60299SZbigniew Kurzynski 
136707a60299SZbigniew Kurzynski         crow::connections::systemBus->async_method_call(
136807a60299SZbigniew Kurzynski             [asyncResp, id](const boost::system::error_code ec) {
136907a60299SZbigniew Kurzynski                 if (ec)
137007a60299SZbigniew Kurzynski                 {
137107a60299SZbigniew Kurzynski                     messages::resourceNotFound(asyncResp->res,
137207a60299SZbigniew Kurzynski                                                "TrustStore Certificate",
137307a60299SZbigniew Kurzynski                                                std::to_string(id));
137407a60299SZbigniew Kurzynski                     return;
137507a60299SZbigniew Kurzynski                 }
137607a60299SZbigniew Kurzynski                 BMCWEB_LOG_INFO << "Certificate deleted";
137707a60299SZbigniew Kurzynski                 asyncResp->res.result(boost::beast::http::status::no_content);
137807a60299SZbigniew Kurzynski             },
137907a60299SZbigniew Kurzynski             certs::authorityServiceName, certPath, certs::objDeleteIntf,
138007a60299SZbigniew Kurzynski             "Delete");
138107a60299SZbigniew Kurzynski     }
1382cfcd5f6bSMarri Devender Rao }; // TrustStoreCertificate
13835968caeeSMarri Devender Rao } // namespace redfish
1384