xref: /openbmc/bmcweb/features/redfish/lib/certificate_service.hpp (revision 07a602993f1007b0b0b764bdb3f14f302a8d2e26)
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 
205968caeeSMarri Devender Rao #include <variant>
215968caeeSMarri Devender Rao namespace redfish
225968caeeSMarri Devender Rao {
235968caeeSMarri Devender Rao namespace certs
245968caeeSMarri Devender Rao {
255968caeeSMarri Devender Rao constexpr char const *httpsObjectPath =
265968caeeSMarri Devender Rao     "/xyz/openbmc_project/certs/server/https";
275968caeeSMarri Devender Rao constexpr char const *certInstallIntf = "xyz.openbmc_project.Certs.Install";
285968caeeSMarri Devender Rao constexpr char const *certReplaceIntf = "xyz.openbmc_project.Certs.Replace";
29*07a60299SZbigniew Kurzynski constexpr char const *objDeleteIntf = "xyz.openbmc_project.Object.Delete";
305968caeeSMarri Devender Rao constexpr char const *certPropIntf = "xyz.openbmc_project.Certs.Certificate";
315968caeeSMarri Devender Rao constexpr char const *dbusPropIntf = "org.freedesktop.DBus.Properties";
325968caeeSMarri Devender Rao constexpr char const *dbusObjManagerIntf = "org.freedesktop.DBus.ObjectManager";
3337cce918SMarri Devender Rao constexpr char const *ldapObjectPath = "/xyz/openbmc_project/certs/client/ldap";
3437cce918SMarri Devender Rao constexpr char const *httpsServiceName =
3537cce918SMarri Devender Rao     "xyz.openbmc_project.Certs.Manager.Server.Https";
3637cce918SMarri Devender Rao constexpr char const *ldapServiceName =
3737cce918SMarri Devender Rao     "xyz.openbmc_project.Certs.Manager.Client.Ldap";
38cfcd5f6bSMarri Devender Rao constexpr char const *authorityServiceName =
39cfcd5f6bSMarri Devender Rao     "xyz.openbmc_project.Certs.Manager.Authority.Ldap";
40cfcd5f6bSMarri Devender Rao constexpr char const *authorityObjectPath =
41cfcd5f6bSMarri Devender Rao     "/xyz/openbmc_project/certs/authority/ldap";
425968caeeSMarri Devender Rao } // namespace certs
435968caeeSMarri Devender Rao 
445968caeeSMarri Devender Rao /**
455968caeeSMarri Devender Rao  * The Certificate schema defines a Certificate Service which represents the
465968caeeSMarri Devender Rao  * actions available to manage certificates and links to where certificates
475968caeeSMarri Devender Rao  * are installed.
485968caeeSMarri Devender Rao  */
495968caeeSMarri Devender Rao class CertificateService : public Node
505968caeeSMarri Devender Rao {
515968caeeSMarri Devender Rao   public:
525968caeeSMarri Devender Rao     CertificateService(CrowApp &app) :
535968caeeSMarri Devender Rao         Node(app, "/redfish/v1/CertificateService/")
545968caeeSMarri Devender Rao     {
555968caeeSMarri Devender Rao         // TODO: Issue#61 No entries are available for Certificate
565968caeeSMarri Devender Rao         // sevice at https://www.dmtf.org/standards/redfish
575968caeeSMarri Devender Rao         // "redfish standard registries". Need to modify after DMTF
585968caeeSMarri Devender Rao         // publish Privilege details for certificate service
595968caeeSMarri Devender Rao         entityPrivileges = {
605968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
615968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
625968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
635968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
645968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
655968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
665968caeeSMarri Devender Rao     }
675968caeeSMarri Devender Rao 
685968caeeSMarri Devender Rao   private:
695968caeeSMarri Devender Rao     void doGet(crow::Response &res, const crow::Request &req,
705968caeeSMarri Devender Rao                const std::vector<std::string> &params) override
715968caeeSMarri Devender Rao     {
725968caeeSMarri Devender Rao         res.jsonValue = {
735968caeeSMarri Devender Rao             {"@odata.type", "#CertificateService.v1_0_0.CertificateService"},
745968caeeSMarri Devender Rao             {"@odata.id", "/redfish/v1/CertificateService"},
755968caeeSMarri Devender Rao             {"@odata.context",
765968caeeSMarri Devender Rao              "/redfish/v1/$metadata#CertificateService.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  */
1005968caeeSMarri Devender Rao 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     }
1075968caeeSMarri Devender Rao     if ((found + 1) < url.length())
1085968caeeSMarri Devender Rao     {
1095968caeeSMarri Devender Rao         char *endPtr;
1105968caeeSMarri Devender Rao         std::string_view str = url.substr(found + 1);
1115968caeeSMarri Devender Rao         long value = std::strtol(str.data(), &endPtr, 10);
11237cce918SMarri Devender Rao         if (endPtr != str.end())
1135968caeeSMarri Devender Rao         {
1145968caeeSMarri Devender Rao             return -1;
1155968caeeSMarri Devender Rao         }
1165968caeeSMarri Devender Rao         return value;
1175968caeeSMarri Devender Rao     }
1185968caeeSMarri Devender Rao     return -1;
1195968caeeSMarri Devender Rao }
1205968caeeSMarri Devender Rao 
12158eb238fSKowalski, Kamil std::string
12258eb238fSKowalski, Kamil     getCertificateFromReqBody(const std::shared_ptr<AsyncResp> &asyncResp,
12358eb238fSKowalski, Kamil                               const crow::Request &req)
12458eb238fSKowalski, Kamil {
12558eb238fSKowalski, Kamil     nlohmann::json reqJson = nlohmann::json::parse(req.body, nullptr, false);
12658eb238fSKowalski, Kamil 
12758eb238fSKowalski, Kamil     if (reqJson.is_discarded())
12858eb238fSKowalski, Kamil     {
12958eb238fSKowalski, Kamil         // We did not receive JSON request, proceed as it is RAW data
13058eb238fSKowalski, Kamil         return req.body;
13158eb238fSKowalski, Kamil     }
13258eb238fSKowalski, Kamil 
13358eb238fSKowalski, Kamil     std::string certificate;
13458eb238fSKowalski, Kamil     std::optional<std::string> certificateType = "PEM";
13558eb238fSKowalski, Kamil 
13658eb238fSKowalski, Kamil     if (!json_util::readJson(reqJson, asyncResp->res, "CertificateString",
13758eb238fSKowalski, Kamil                              certificate, "CertificateType", certificateType))
13858eb238fSKowalski, Kamil     {
13958eb238fSKowalski, Kamil         BMCWEB_LOG_ERROR << "Required parameters are missing";
14058eb238fSKowalski, Kamil         messages::internalError(asyncResp->res);
14158eb238fSKowalski, Kamil         return std::string();
14258eb238fSKowalski, Kamil     }
14358eb238fSKowalski, Kamil 
14458eb238fSKowalski, Kamil     if (*certificateType != "PEM")
14558eb238fSKowalski, Kamil     {
14658eb238fSKowalski, Kamil         messages::propertyValueNotInList(asyncResp->res, *certificateType,
14758eb238fSKowalski, Kamil                                          "CertificateType");
14858eb238fSKowalski, Kamil         return std::string();
14958eb238fSKowalski, Kamil     }
15058eb238fSKowalski, Kamil 
15158eb238fSKowalski, Kamil     return certificate;
15258eb238fSKowalski, Kamil }
15358eb238fSKowalski, Kamil 
1545968caeeSMarri Devender Rao /**
1555968caeeSMarri Devender Rao  * Class to create a temporary certificate file for uploading to system
1565968caeeSMarri Devender Rao  */
1575968caeeSMarri Devender Rao class CertificateFile
1585968caeeSMarri Devender Rao {
1595968caeeSMarri Devender Rao   public:
1605968caeeSMarri Devender Rao     CertificateFile() = delete;
1615968caeeSMarri Devender Rao     CertificateFile(const CertificateFile &) = delete;
1625968caeeSMarri Devender Rao     CertificateFile &operator=(const CertificateFile &) = delete;
1635968caeeSMarri Devender Rao     CertificateFile(CertificateFile &&) = delete;
1645968caeeSMarri Devender Rao     CertificateFile &operator=(CertificateFile &&) = delete;
1655968caeeSMarri Devender Rao     CertificateFile(const std::string &certString)
1665968caeeSMarri Devender Rao     {
1675968caeeSMarri Devender Rao         char dirTemplate[] = "/tmp/Certs.XXXXXX";
1685968caeeSMarri Devender Rao         char *tempDirectory = mkdtemp(dirTemplate);
1695968caeeSMarri Devender Rao         if (tempDirectory)
1705968caeeSMarri Devender Rao         {
1715968caeeSMarri Devender Rao             certDirectory = tempDirectory;
1725968caeeSMarri Devender Rao             certificateFile = certDirectory / "cert.pem";
1735968caeeSMarri Devender Rao             std::ofstream out(certificateFile, std::ofstream::out |
1745968caeeSMarri Devender Rao                                                    std::ofstream::binary |
1755968caeeSMarri Devender Rao                                                    std::ofstream::trunc);
1765968caeeSMarri Devender Rao             out << certString;
1775968caeeSMarri Devender Rao             out.close();
1785968caeeSMarri Devender Rao             BMCWEB_LOG_DEBUG << "Creating certificate file" << certificateFile;
1795968caeeSMarri Devender Rao         }
1805968caeeSMarri Devender Rao     }
1815968caeeSMarri Devender Rao     ~CertificateFile()
1825968caeeSMarri Devender Rao     {
1835968caeeSMarri Devender Rao         if (std::filesystem::exists(certDirectory))
1845968caeeSMarri Devender Rao         {
1855968caeeSMarri Devender Rao             BMCWEB_LOG_DEBUG << "Removing certificate file" << certificateFile;
1865968caeeSMarri Devender Rao             try
1875968caeeSMarri Devender Rao             {
1885968caeeSMarri Devender Rao                 std::filesystem::remove_all(certDirectory);
1895968caeeSMarri Devender Rao             }
1905968caeeSMarri Devender Rao             catch (const std::filesystem::filesystem_error &e)
1915968caeeSMarri Devender Rao             {
1925968caeeSMarri Devender Rao                 BMCWEB_LOG_ERROR << "Failed to remove temp directory"
1935968caeeSMarri Devender Rao                                  << certDirectory;
1945968caeeSMarri Devender Rao             }
1955968caeeSMarri Devender Rao         }
1965968caeeSMarri Devender Rao     }
1975968caeeSMarri Devender Rao     std::string getCertFilePath()
1985968caeeSMarri Devender Rao     {
1995968caeeSMarri Devender Rao         return certificateFile;
2005968caeeSMarri Devender Rao     }
2015968caeeSMarri Devender Rao 
2025968caeeSMarri Devender Rao   private:
2035968caeeSMarri Devender Rao     std::filesystem::path certificateFile;
2045968caeeSMarri Devender Rao     std::filesystem::path certDirectory;
2055968caeeSMarri Devender Rao };
2065968caeeSMarri Devender Rao 
20730215816SMarri Devender Rao static std::unique_ptr<sdbusplus::bus::match::match> csrMatcher;
20830215816SMarri Devender Rao /**
20930215816SMarri Devender Rao  * @brief Read data from CSR D-bus object and set to response
21030215816SMarri Devender Rao  *
21130215816SMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
21230215816SMarri Devender Rao  * @param[in] certURI Link to certifiate collection URI
21330215816SMarri Devender Rao  * @param[in] service D-Bus service name
21430215816SMarri Devender Rao  * @param[in] certObjPath certificate D-Bus object path
21530215816SMarri Devender Rao  * @param[in] csrObjPath CSR D-Bus object path
21630215816SMarri Devender Rao  * @return None
21730215816SMarri Devender Rao  */
21830215816SMarri Devender Rao static void getCSR(const std::shared_ptr<AsyncResp> &asyncResp,
21930215816SMarri Devender Rao                    const std::string &certURI, const std::string &service,
22030215816SMarri Devender Rao                    const std::string &certObjPath,
22130215816SMarri Devender Rao                    const std::string &csrObjPath)
22230215816SMarri Devender Rao {
22330215816SMarri Devender Rao     BMCWEB_LOG_DEBUG << "getCSR CertObjectPath" << certObjPath
22430215816SMarri Devender Rao                      << " CSRObjectPath=" << csrObjPath
22530215816SMarri Devender Rao                      << " service=" << service;
22630215816SMarri Devender Rao     crow::connections::systemBus->async_method_call(
22730215816SMarri Devender Rao         [asyncResp, certURI](const boost::system::error_code ec,
22830215816SMarri Devender Rao                              const std::string &csr) {
22930215816SMarri Devender Rao             if (ec)
23030215816SMarri Devender Rao             {
23130215816SMarri Devender Rao                 BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
23230215816SMarri Devender Rao                 messages::internalError(asyncResp->res);
23330215816SMarri Devender Rao                 return;
23430215816SMarri Devender Rao             }
23530215816SMarri Devender Rao             if (csr.empty())
23630215816SMarri Devender Rao             {
23730215816SMarri Devender Rao                 BMCWEB_LOG_ERROR << "CSR read is empty";
23830215816SMarri Devender Rao                 messages::internalError(asyncResp->res);
23930215816SMarri Devender Rao                 return;
24030215816SMarri Devender Rao             }
24130215816SMarri Devender Rao             asyncResp->res.jsonValue["CSRString"] = csr;
24230215816SMarri Devender Rao             asyncResp->res.jsonValue["CertificateCollection"] = {
24330215816SMarri Devender Rao                 {"@odata.id", certURI}};
24430215816SMarri Devender Rao         },
24530215816SMarri Devender Rao         service, csrObjPath, "xyz.openbmc_project.Certs.CSR", "CSR");
24630215816SMarri Devender Rao }
24730215816SMarri Devender Rao 
24830215816SMarri Devender Rao /**
24930215816SMarri Devender Rao  * Action to Generate CSR
25030215816SMarri Devender Rao  */
25130215816SMarri Devender Rao class CertificateActionGenerateCSR : public Node
25230215816SMarri Devender Rao {
25330215816SMarri Devender Rao   public:
25430215816SMarri Devender Rao     CertificateActionGenerateCSR(CrowApp &app) :
25530215816SMarri Devender Rao         Node(app, "/redfish/v1/CertificateService/Actions/"
25630215816SMarri Devender Rao                   "CertificateService.GenerateCSR/")
25730215816SMarri Devender Rao     {
25830215816SMarri Devender Rao         entityPrivileges = {
25930215816SMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
26030215816SMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
26130215816SMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
26230215816SMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
26330215816SMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
26430215816SMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
26530215816SMarri Devender Rao     }
26630215816SMarri Devender Rao 
26730215816SMarri Devender Rao   private:
26830215816SMarri Devender Rao     void doPost(crow::Response &res, const crow::Request &req,
26930215816SMarri Devender Rao                 const std::vector<std::string> &params) override
27030215816SMarri Devender Rao     {
27130215816SMarri Devender Rao         static const int RSA_KEY_BIT_LENGTH = 2048;
27230215816SMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
27330215816SMarri Devender Rao         // Required parameters
27430215816SMarri Devender Rao         std::string city;
27530215816SMarri Devender Rao         std::string commonName;
27630215816SMarri Devender Rao         std::string country;
27730215816SMarri Devender Rao         std::string organization;
27830215816SMarri Devender Rao         std::string organizationalUnit;
27930215816SMarri Devender Rao         std::string state;
28030215816SMarri Devender Rao         nlohmann::json certificateCollection;
28130215816SMarri Devender Rao 
28230215816SMarri Devender Rao         // Optional parameters
28330215816SMarri Devender Rao         std::optional<std::vector<std::string>> optAlternativeNames =
28430215816SMarri Devender Rao             std::vector<std::string>();
28530215816SMarri Devender Rao         std::optional<std::string> optContactPerson = "";
28630215816SMarri Devender Rao         std::optional<std::string> optChallengePassword = "";
28730215816SMarri Devender Rao         std::optional<std::string> optEmail = "";
28830215816SMarri Devender Rao         std::optional<std::string> optGivenName = "";
28930215816SMarri Devender Rao         std::optional<std::string> optInitials = "";
29030215816SMarri Devender Rao         std::optional<int64_t> optKeyBitLength = RSA_KEY_BIT_LENGTH;
29130215816SMarri Devender Rao         std::optional<std::string> optKeyCurveId = "prime256v1";
29230215816SMarri Devender Rao         std::optional<std::string> optKeyPairAlgorithm = "EC";
29330215816SMarri Devender Rao         std::optional<std::vector<std::string>> optKeyUsage =
29430215816SMarri Devender Rao             std::vector<std::string>();
29530215816SMarri Devender Rao         std::optional<std::string> optSurname = "";
29630215816SMarri Devender Rao         std::optional<std::string> optUnstructuredName = "";
29730215816SMarri Devender Rao         if (!json_util::readJson(
29830215816SMarri Devender Rao                 req, asyncResp->res, "City", city, "CommonName", commonName,
29930215816SMarri Devender Rao                 "ContactPerson", optContactPerson, "Country", country,
30030215816SMarri Devender Rao                 "Organization", organization, "OrganizationalUnit",
30130215816SMarri Devender Rao                 organizationalUnit, "State", state, "CertificateCollection",
30230215816SMarri Devender Rao                 certificateCollection, "AlternativeNames", optAlternativeNames,
30330215816SMarri Devender Rao                 "ChallengePassword", optChallengePassword, "Email", optEmail,
30430215816SMarri Devender Rao                 "GivenName", optGivenName, "Initials", optInitials,
30530215816SMarri Devender Rao                 "KeyBitLength", optKeyBitLength, "KeyCurveId", optKeyCurveId,
30630215816SMarri Devender Rao                 "KeyPairAlgorithm", optKeyPairAlgorithm, "KeyUsage",
30730215816SMarri Devender Rao                 optKeyUsage, "Surname", optSurname, "UnstructuredName",
30830215816SMarri Devender Rao                 optUnstructuredName))
30930215816SMarri Devender Rao         {
31030215816SMarri Devender Rao             return;
31130215816SMarri Devender Rao         }
31230215816SMarri Devender Rao 
31330215816SMarri Devender Rao         // bmcweb has no way to store or decode a private key challenge
31430215816SMarri Devender Rao         // password, which will likely cause bmcweb to crash on startup if this
31530215816SMarri Devender Rao         // is not set on a post so not allowing the user to set value
31630215816SMarri Devender Rao         if (*optChallengePassword != "")
31730215816SMarri Devender Rao         {
31830215816SMarri Devender Rao             messages::actionParameterNotSupported(asyncResp->res, "GenerateCSR",
31930215816SMarri Devender Rao                                                   "ChallengePassword");
32030215816SMarri Devender Rao             return;
32130215816SMarri Devender Rao         }
32230215816SMarri Devender Rao 
32330215816SMarri Devender Rao         std::string certURI;
32430215816SMarri Devender Rao         if (!redfish::json_util::readJson(certificateCollection, asyncResp->res,
32530215816SMarri Devender Rao                                           "@odata.id", certURI))
32630215816SMarri Devender Rao         {
32730215816SMarri Devender Rao             return;
32830215816SMarri Devender Rao         }
32930215816SMarri Devender Rao 
33030215816SMarri Devender Rao         std::string objectPath;
33130215816SMarri Devender Rao         std::string service;
33230215816SMarri Devender Rao         if (boost::starts_with(
33330215816SMarri Devender Rao                 certURI,
33430215816SMarri Devender Rao                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
33530215816SMarri Devender Rao         {
33630215816SMarri Devender Rao             objectPath = certs::httpsObjectPath;
33730215816SMarri Devender Rao             service = certs::httpsServiceName;
33830215816SMarri Devender Rao         }
3393b7f0149SMarri Devender Rao         else if (boost::starts_with(
3403b7f0149SMarri Devender Rao                      certURI, "/redfish/v1/AccountService/LDAP/Certificates"))
3413b7f0149SMarri Devender Rao         {
3423b7f0149SMarri Devender Rao             objectPath = certs::ldapObjectPath;
3433b7f0149SMarri Devender Rao             service = certs::ldapServiceName;
3443b7f0149SMarri Devender Rao         }
34530215816SMarri Devender Rao         else
34630215816SMarri Devender Rao         {
34730215816SMarri Devender Rao             messages::actionParameterNotSupported(
34830215816SMarri Devender Rao                 asyncResp->res, "CertificateCollection", "GenerateCSR");
34930215816SMarri Devender Rao             return;
35030215816SMarri Devender Rao         }
35130215816SMarri Devender Rao 
35230215816SMarri Devender Rao         // supporting only EC and RSA algorithm
35330215816SMarri Devender Rao         if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
35430215816SMarri Devender Rao         {
35530215816SMarri Devender Rao             messages::actionParameterNotSupported(
35630215816SMarri Devender Rao                 asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
35730215816SMarri Devender Rao             return;
35830215816SMarri Devender Rao         }
35930215816SMarri Devender Rao 
36030215816SMarri Devender Rao         // supporting only 2048 key bit length for RSA algorithm due to time
36130215816SMarri Devender Rao         // consumed in generating private key
36230215816SMarri Devender Rao         if (*optKeyPairAlgorithm == "RSA" &&
36330215816SMarri Devender Rao             *optKeyBitLength != RSA_KEY_BIT_LENGTH)
36430215816SMarri Devender Rao         {
36530215816SMarri Devender Rao             messages::propertyValueNotInList(asyncResp->res,
36630215816SMarri Devender Rao                                              std::to_string(*optKeyBitLength),
36730215816SMarri Devender Rao                                              "KeyBitLength");
36830215816SMarri Devender Rao             return;
36930215816SMarri Devender Rao         }
37030215816SMarri Devender Rao 
37130215816SMarri Devender Rao         // validate KeyUsage supporting only 1 type based on URL
37230215816SMarri Devender Rao         if (boost::starts_with(
37330215816SMarri Devender Rao                 certURI,
37430215816SMarri Devender Rao                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
37530215816SMarri Devender Rao         {
37630215816SMarri Devender Rao             if (optKeyUsage->size() == 0)
37730215816SMarri Devender Rao             {
37830215816SMarri Devender Rao                 optKeyUsage->push_back("ServerAuthentication");
37930215816SMarri Devender Rao             }
38030215816SMarri Devender Rao             else if (optKeyUsage->size() == 1)
38130215816SMarri Devender Rao             {
38230215816SMarri Devender Rao                 if ((*optKeyUsage)[0] != "ServerAuthentication")
38330215816SMarri Devender Rao                 {
38430215816SMarri Devender Rao                     messages::propertyValueNotInList(
38530215816SMarri Devender Rao                         asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
38630215816SMarri Devender Rao                     return;
38730215816SMarri Devender Rao                 }
38830215816SMarri Devender Rao             }
38930215816SMarri Devender Rao             else
39030215816SMarri Devender Rao             {
39130215816SMarri Devender Rao                 messages::actionParameterNotSupported(
39230215816SMarri Devender Rao                     asyncResp->res, "KeyUsage", "GenerateCSR");
39330215816SMarri Devender Rao                 return;
39430215816SMarri Devender Rao             }
39530215816SMarri Devender Rao         }
3963b7f0149SMarri Devender Rao         else if (boost::starts_with(
3973b7f0149SMarri Devender Rao                      certURI, "/redfish/v1/AccountService/LDAP/Certificates"))
3983b7f0149SMarri Devender Rao         {
3993b7f0149SMarri Devender Rao             if (optKeyUsage->size() == 0)
4003b7f0149SMarri Devender Rao             {
4013b7f0149SMarri Devender Rao                 optKeyUsage->push_back("ClientAuthentication");
4023b7f0149SMarri Devender Rao             }
4033b7f0149SMarri Devender Rao             else if (optKeyUsage->size() == 1)
4043b7f0149SMarri Devender Rao             {
4053b7f0149SMarri Devender Rao                 if ((*optKeyUsage)[0] != "ClientAuthentication")
4063b7f0149SMarri Devender Rao                 {
4073b7f0149SMarri Devender Rao                     messages::propertyValueNotInList(
4083b7f0149SMarri Devender Rao                         asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
4093b7f0149SMarri Devender Rao                     return;
4103b7f0149SMarri Devender Rao                 }
4113b7f0149SMarri Devender Rao             }
4123b7f0149SMarri Devender Rao             else
4133b7f0149SMarri Devender Rao             {
4143b7f0149SMarri Devender Rao                 messages::actionParameterNotSupported(
4153b7f0149SMarri Devender Rao                     asyncResp->res, "KeyUsage", "GenerateCSR");
4163b7f0149SMarri Devender Rao                 return;
4173b7f0149SMarri Devender Rao             }
4183b7f0149SMarri Devender Rao         }
41930215816SMarri Devender Rao 
42030215816SMarri Devender Rao         // Only allow one CSR matcher at a time so setting retry time-out and
42130215816SMarri Devender Rao         // timer expiry to 10 seconds for now.
42230215816SMarri Devender Rao         static const int TIME_OUT = 10;
42330215816SMarri Devender Rao         if (csrMatcher)
42430215816SMarri Devender Rao         {
42530215816SMarri Devender Rao             res.addHeader("Retry-After", std::to_string(TIME_OUT));
42630215816SMarri Devender Rao             messages::serviceTemporarilyUnavailable(asyncResp->res,
42730215816SMarri Devender Rao                                                     std::to_string(TIME_OUT));
42830215816SMarri Devender Rao             return;
42930215816SMarri Devender Rao         }
43030215816SMarri Devender Rao 
43130215816SMarri Devender Rao         // Make this static so it survives outside this method
43230215816SMarri Devender Rao         static boost::asio::steady_timer timeout(*req.ioService);
43330215816SMarri Devender Rao         timeout.expires_after(std::chrono::seconds(TIME_OUT));
43430215816SMarri Devender Rao         timeout.async_wait([asyncResp](const boost::system::error_code &ec) {
43530215816SMarri Devender Rao             csrMatcher = nullptr;
43630215816SMarri Devender Rao             if (ec)
43730215816SMarri Devender Rao             {
43830215816SMarri Devender Rao                 // operation_aborted is expected if timer is canceled before
43930215816SMarri Devender Rao                 // completion.
44030215816SMarri Devender Rao                 if (ec != boost::asio::error::operation_aborted)
44130215816SMarri Devender Rao                 {
44230215816SMarri Devender Rao                     BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
44330215816SMarri Devender Rao                 }
44430215816SMarri Devender Rao                 return;
44530215816SMarri Devender Rao             }
44630215816SMarri Devender Rao             BMCWEB_LOG_ERROR << "Timed out waiting for Generating CSR";
44730215816SMarri Devender Rao             messages::internalError(asyncResp->res);
44830215816SMarri Devender Rao         });
44930215816SMarri Devender Rao 
45030215816SMarri Devender Rao         // create a matcher to wait on CSR object
45130215816SMarri Devender Rao         BMCWEB_LOG_DEBUG << "create matcher with path " << objectPath;
45230215816SMarri Devender Rao         std::string match("type='signal',"
45330215816SMarri Devender Rao                           "interface='org.freedesktop.DBus.ObjectManager',"
45430215816SMarri Devender Rao                           "path='" +
45530215816SMarri Devender Rao                           objectPath +
45630215816SMarri Devender Rao                           "',"
45730215816SMarri Devender Rao                           "member='InterfacesAdded'");
45830215816SMarri Devender Rao         csrMatcher = std::make_unique<sdbusplus::bus::match::match>(
45930215816SMarri Devender Rao             *crow::connections::systemBus, match,
46030215816SMarri Devender Rao             [asyncResp, service, objectPath,
46130215816SMarri Devender Rao              certURI](sdbusplus::message::message &m) {
462271584abSEd Tanous                 timeout.cancel();
46330215816SMarri Devender Rao                 if (m.is_method_error())
46430215816SMarri Devender Rao                 {
46530215816SMarri Devender Rao                     BMCWEB_LOG_ERROR << "Dbus method error!!!";
46630215816SMarri Devender Rao                     messages::internalError(asyncResp->res);
46730215816SMarri Devender Rao                     return;
46830215816SMarri Devender Rao                 }
46930215816SMarri Devender Rao                 std::vector<std::pair<
47030215816SMarri Devender Rao                     std::string, std::vector<std::pair<
47130215816SMarri Devender Rao                                      std::string, std::variant<std::string>>>>>
47230215816SMarri Devender Rao                     interfacesProperties;
47330215816SMarri Devender Rao                 sdbusplus::message::object_path csrObjectPath;
47430215816SMarri Devender Rao                 m.read(csrObjectPath, interfacesProperties);
47530215816SMarri Devender Rao                 BMCWEB_LOG_DEBUG << "CSR object added" << csrObjectPath.str;
47630215816SMarri Devender Rao                 for (auto &interface : interfacesProperties)
47730215816SMarri Devender Rao                 {
47830215816SMarri Devender Rao                     if (interface.first == "xyz.openbmc_project.Certs.CSR")
47930215816SMarri Devender Rao                     {
48030215816SMarri Devender Rao                         getCSR(asyncResp, certURI, service, objectPath,
48130215816SMarri Devender Rao                                csrObjectPath.str);
48230215816SMarri Devender Rao                         break;
48330215816SMarri Devender Rao                     }
48430215816SMarri Devender Rao                 }
48530215816SMarri Devender Rao             });
48630215816SMarri Devender Rao         crow::connections::systemBus->async_method_call(
487271584abSEd Tanous             [asyncResp](const boost::system::error_code &ec,
48830215816SMarri Devender Rao                         const std::string &path) {
48930215816SMarri Devender Rao                 if (ec)
49030215816SMarri Devender Rao                 {
49130215816SMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec.message();
49230215816SMarri Devender Rao                     messages::internalError(asyncResp->res);
49330215816SMarri Devender Rao                     return;
49430215816SMarri Devender Rao                 }
49530215816SMarri Devender Rao             },
49630215816SMarri Devender Rao             service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
49730215816SMarri Devender Rao             "GenerateCSR", *optAlternativeNames, *optChallengePassword, city,
49830215816SMarri Devender Rao             commonName, *optContactPerson, country, *optEmail, *optGivenName,
49930215816SMarri Devender Rao             *optInitials, *optKeyBitLength, *optKeyCurveId,
50030215816SMarri Devender Rao             *optKeyPairAlgorithm, *optKeyUsage, organization,
50130215816SMarri Devender Rao             organizationalUnit, state, *optSurname, *optUnstructuredName);
50230215816SMarri Devender Rao     }
50330215816SMarri Devender Rao }; // CertificateActionGenerateCSR
50430215816SMarri Devender Rao 
5055968caeeSMarri Devender Rao /**
5065968caeeSMarri Devender Rao  * @brief Parse and update Certficate Issue/Subject property
5075968caeeSMarri Devender Rao  *
5085968caeeSMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
5095968caeeSMarri Devender Rao  * @param[in] str  Issuer/Subject value in key=value pairs
5105968caeeSMarri Devender Rao  * @param[in] type Issuer/Subject
5115968caeeSMarri Devender Rao  * @return None
5125968caeeSMarri Devender Rao  */
5135968caeeSMarri Devender Rao static void updateCertIssuerOrSubject(nlohmann::json &out,
5145968caeeSMarri Devender Rao                                       const std::string_view value)
5155968caeeSMarri Devender Rao {
5165968caeeSMarri Devender Rao     // example: O=openbmc-project.xyz,CN=localhost
5175968caeeSMarri Devender Rao     std::string_view::iterator i = value.begin();
5185968caeeSMarri Devender Rao     while (i != value.end())
5195968caeeSMarri Devender Rao     {
5205968caeeSMarri Devender Rao         std::string_view::iterator tokenBegin = i;
5215968caeeSMarri Devender Rao         while (i != value.end() && *i != '=')
5225968caeeSMarri Devender Rao         {
5235968caeeSMarri Devender Rao             i++;
5245968caeeSMarri Devender Rao         }
5255968caeeSMarri Devender Rao         if (i == value.end())
5265968caeeSMarri Devender Rao         {
5275968caeeSMarri Devender Rao             break;
5285968caeeSMarri Devender Rao         }
529271584abSEd Tanous         const std::string_view key(tokenBegin,
530271584abSEd Tanous                                    static_cast<size_t>(i - tokenBegin));
5315968caeeSMarri Devender Rao         i++;
5325968caeeSMarri Devender Rao         tokenBegin = i;
5335968caeeSMarri Devender Rao         while (i != value.end() && *i != ',')
5345968caeeSMarri Devender Rao         {
5355968caeeSMarri Devender Rao             i++;
5365968caeeSMarri Devender Rao         }
537271584abSEd Tanous         const std::string_view val(tokenBegin,
538271584abSEd Tanous                                    static_cast<size_t>(i - tokenBegin));
5395968caeeSMarri Devender Rao         if (key == "L")
5405968caeeSMarri Devender Rao         {
5415968caeeSMarri Devender Rao             out["City"] = val;
5425968caeeSMarri Devender Rao         }
5435968caeeSMarri Devender Rao         else if (key == "CN")
5445968caeeSMarri Devender Rao         {
5455968caeeSMarri Devender Rao             out["CommonName"] = val;
5465968caeeSMarri Devender Rao         }
5475968caeeSMarri Devender Rao         else if (key == "C")
5485968caeeSMarri Devender Rao         {
5495968caeeSMarri Devender Rao             out["Country"] = val;
5505968caeeSMarri Devender Rao         }
5515968caeeSMarri Devender Rao         else if (key == "O")
5525968caeeSMarri Devender Rao         {
5535968caeeSMarri Devender Rao             out["Organization"] = val;
5545968caeeSMarri Devender Rao         }
5555968caeeSMarri Devender Rao         else if (key == "OU")
5565968caeeSMarri Devender Rao         {
5575968caeeSMarri Devender Rao             out["OrganizationalUnit"] = val;
5585968caeeSMarri Devender Rao         }
5595968caeeSMarri Devender Rao         else if (key == "ST")
5605968caeeSMarri Devender Rao         {
5615968caeeSMarri Devender Rao             out["State"] = val;
5625968caeeSMarri Devender Rao         }
5635968caeeSMarri Devender Rao         // skip comma character
5645968caeeSMarri Devender Rao         if (i != value.end())
5655968caeeSMarri Devender Rao         {
5665968caeeSMarri Devender Rao             i++;
5675968caeeSMarri Devender Rao         }
5685968caeeSMarri Devender Rao     }
5695968caeeSMarri Devender Rao }
5705968caeeSMarri Devender Rao 
5715968caeeSMarri Devender Rao /**
5725968caeeSMarri Devender Rao  * @brief Retrieve the certificates properties and append to the response
5735968caeeSMarri Devender Rao  * message
5745968caeeSMarri Devender Rao  *
5755968caeeSMarri Devender Rao  * @param[in] asyncResp Shared pointer to the response message
5765968caeeSMarri Devender Rao  * @param[in] objectPath  Path of the D-Bus service object
5775968caeeSMarri Devender Rao  * @param[in] certId  Id of the certificate
5785968caeeSMarri Devender Rao  * @param[in] certURL  URL of the certificate object
5795968caeeSMarri Devender Rao  * @param[in] name  name of the certificate
5805968caeeSMarri Devender Rao  * @return None
5815968caeeSMarri Devender Rao  */
5825968caeeSMarri Devender Rao static void getCertificateProperties(
5835968caeeSMarri Devender Rao     const std::shared_ptr<AsyncResp> &asyncResp, const std::string &objectPath,
58437cce918SMarri Devender Rao     const std::string &service, long certId, const std::string &certURL,
58537cce918SMarri Devender Rao     const std::string &name)
5865968caeeSMarri Devender Rao {
5875968caeeSMarri Devender Rao     using PropertyType =
5885968caeeSMarri Devender Rao         std::variant<std::string, uint64_t, std::vector<std::string>>;
5895968caeeSMarri Devender Rao     using PropertiesMap = boost::container::flat_map<std::string, PropertyType>;
5905968caeeSMarri Devender Rao     BMCWEB_LOG_DEBUG << "getCertificateProperties Path=" << objectPath
5915968caeeSMarri Devender Rao                      << " certId=" << certId << " certURl=" << certURL;
5925968caeeSMarri Devender Rao     crow::connections::systemBus->async_method_call(
59337cce918SMarri Devender Rao         [asyncResp, certURL, certId, name](const boost::system::error_code ec,
5945968caeeSMarri Devender Rao                                            const PropertiesMap &properties) {
5955968caeeSMarri Devender Rao             if (ec)
5965968caeeSMarri Devender Rao             {
5975968caeeSMarri Devender Rao                 BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
5988aae75adSMarri Devender Rao                 messages::resourceNotFound(asyncResp->res, name,
5998aae75adSMarri Devender Rao                                            std::to_string(certId));
6005968caeeSMarri Devender Rao                 return;
6015968caeeSMarri Devender Rao             }
6025968caeeSMarri Devender Rao             asyncResp->res.jsonValue = {
6035968caeeSMarri Devender Rao                 {"@odata.id", certURL},
6045968caeeSMarri Devender Rao                 {"@odata.type", "#Certificate.v1_0_0.Certificate"},
6055968caeeSMarri Devender Rao                 {"@odata.context",
6065968caeeSMarri Devender Rao                  "/redfish/v1/$metadata#Certificate.Certificate"},
6075968caeeSMarri Devender Rao                 {"Id", std::to_string(certId)},
6085968caeeSMarri Devender Rao                 {"Name", name},
6095968caeeSMarri Devender Rao                 {"Description", name}};
6105968caeeSMarri Devender Rao             for (const auto &property : properties)
6115968caeeSMarri Devender Rao             {
6125968caeeSMarri Devender Rao                 if (property.first == "CertificateString")
6135968caeeSMarri Devender Rao                 {
6145968caeeSMarri Devender Rao                     asyncResp->res.jsonValue["CertificateString"] = "";
6155968caeeSMarri Devender Rao                     const std::string *value =
6165968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
6175968caeeSMarri Devender Rao                     if (value)
6185968caeeSMarri Devender Rao                     {
61937cce918SMarri Devender Rao                         asyncResp->res.jsonValue["CertificateString"] = *value;
6205968caeeSMarri Devender Rao                     }
6215968caeeSMarri Devender Rao                 }
6225968caeeSMarri Devender Rao                 else if (property.first == "KeyUsage")
6235968caeeSMarri Devender Rao                 {
6245968caeeSMarri Devender Rao                     nlohmann::json &keyUsage =
6255968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["KeyUsage"];
6265968caeeSMarri Devender Rao                     keyUsage = nlohmann::json::array();
6275968caeeSMarri Devender Rao                     const std::vector<std::string> *value =
62837cce918SMarri Devender Rao                         std::get_if<std::vector<std::string>>(&property.second);
6295968caeeSMarri Devender Rao                     if (value)
6305968caeeSMarri Devender Rao                     {
6315968caeeSMarri Devender Rao                         for (const std::string &usage : *value)
6325968caeeSMarri Devender Rao                         {
6335968caeeSMarri Devender Rao                             keyUsage.push_back(usage);
6345968caeeSMarri Devender Rao                         }
6355968caeeSMarri Devender Rao                     }
6365968caeeSMarri Devender Rao                 }
6375968caeeSMarri Devender Rao                 else if (property.first == "Issuer")
6385968caeeSMarri Devender Rao                 {
6395968caeeSMarri Devender Rao                     const std::string *value =
6405968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
6415968caeeSMarri Devender Rao                     if (value)
6425968caeeSMarri Devender Rao                     {
6435968caeeSMarri Devender Rao                         updateCertIssuerOrSubject(
6445968caeeSMarri Devender Rao                             asyncResp->res.jsonValue["Issuer"], *value);
6455968caeeSMarri Devender Rao                     }
6465968caeeSMarri Devender Rao                 }
6475968caeeSMarri Devender Rao                 else if (property.first == "Subject")
6485968caeeSMarri Devender Rao                 {
6495968caeeSMarri Devender Rao                     const std::string *value =
6505968caeeSMarri Devender Rao                         std::get_if<std::string>(&property.second);
6515968caeeSMarri Devender Rao                     if (value)
6525968caeeSMarri Devender Rao                     {
6535968caeeSMarri Devender Rao                         updateCertIssuerOrSubject(
65437cce918SMarri Devender Rao                             asyncResp->res.jsonValue["Subject"], *value);
6555968caeeSMarri Devender Rao                     }
6565968caeeSMarri Devender Rao                 }
6575968caeeSMarri Devender Rao                 else if (property.first == "ValidNotAfter")
6585968caeeSMarri Devender Rao                 {
6595968caeeSMarri Devender Rao                     const uint64_t *value =
6605968caeeSMarri Devender Rao                         std::get_if<uint64_t>(&property.second);
6615968caeeSMarri Devender Rao                     if (value)
6625968caeeSMarri Devender Rao                     {
66337cce918SMarri Devender Rao                         std::time_t time = static_cast<std::time_t>(*value);
6645968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["ValidNotAfter"] =
6655968caeeSMarri Devender Rao                             crow::utility::getDateTime(time);
6665968caeeSMarri Devender Rao                     }
6675968caeeSMarri Devender Rao                 }
6685968caeeSMarri Devender Rao                 else if (property.first == "ValidNotBefore")
6695968caeeSMarri Devender Rao                 {
6705968caeeSMarri Devender Rao                     const uint64_t *value =
6715968caeeSMarri Devender Rao                         std::get_if<uint64_t>(&property.second);
6725968caeeSMarri Devender Rao                     if (value)
6735968caeeSMarri Devender Rao                     {
67437cce918SMarri Devender Rao                         std::time_t time = static_cast<std::time_t>(*value);
6755968caeeSMarri Devender Rao                         asyncResp->res.jsonValue["ValidNotBefore"] =
6765968caeeSMarri Devender Rao                             crow::utility::getDateTime(time);
6775968caeeSMarri Devender Rao                     }
6785968caeeSMarri Devender Rao                 }
6795968caeeSMarri Devender Rao             }
6805968caeeSMarri Devender Rao             asyncResp->res.addHeader("Location", certURL);
6815968caeeSMarri Devender Rao         },
6825968caeeSMarri Devender Rao         service, objectPath, certs::dbusPropIntf, "GetAll",
6835968caeeSMarri Devender Rao         certs::certPropIntf);
6845968caeeSMarri Devender Rao }
6855968caeeSMarri Devender Rao 
6865968caeeSMarri Devender Rao using GetObjectType =
6875968caeeSMarri Devender Rao     std::vector<std::pair<std::string, std::vector<std::string>>>;
6885968caeeSMarri Devender Rao 
6895968caeeSMarri Devender Rao /**
6905968caeeSMarri Devender Rao  * Action to replace an existing certificate
6915968caeeSMarri Devender Rao  */
6925968caeeSMarri Devender Rao class CertificateActionsReplaceCertificate : public Node
6935968caeeSMarri Devender Rao {
6945968caeeSMarri Devender Rao   public:
6955968caeeSMarri Devender Rao     CertificateActionsReplaceCertificate(CrowApp &app) :
6965968caeeSMarri Devender Rao         Node(app, "/redfish/v1/CertificateService/Actions/"
6975968caeeSMarri Devender Rao                   "CertificateService.ReplaceCertificate/")
6985968caeeSMarri Devender Rao     {
6995968caeeSMarri Devender Rao         entityPrivileges = {
7005968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
7015968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
7025968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
7035968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
7045968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
7055968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
7065968caeeSMarri Devender Rao     }
7075968caeeSMarri Devender Rao 
7085968caeeSMarri Devender Rao   private:
7095968caeeSMarri Devender Rao     void doPost(crow::Response &res, const crow::Request &req,
7105968caeeSMarri Devender Rao                 const std::vector<std::string> &params) override
7115968caeeSMarri Devender Rao     {
7125968caeeSMarri Devender Rao         std::string certificate;
7135968caeeSMarri Devender Rao         nlohmann::json certificateUri;
7145968caeeSMarri Devender Rao         std::optional<std::string> certificateType = "PEM";
7155968caeeSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
7165968caeeSMarri Devender Rao         if (!json_util::readJson(req, asyncResp->res, "CertificateString",
7175968caeeSMarri Devender Rao                                  certificate, "CertificateUri", certificateUri,
7185968caeeSMarri Devender Rao                                  "CertificateType", certificateType))
7195968caeeSMarri Devender Rao         {
7205968caeeSMarri Devender Rao             BMCWEB_LOG_ERROR << "Required parameters are missing";
7215968caeeSMarri Devender Rao             messages::internalError(asyncResp->res);
7225968caeeSMarri Devender Rao             return;
7235968caeeSMarri Devender Rao         }
7245968caeeSMarri Devender Rao 
7255968caeeSMarri Devender Rao         if (!certificateType)
7265968caeeSMarri Devender Rao         {
7275968caeeSMarri Devender Rao             // should never happen, but it never hurts to be paranoid.
7285968caeeSMarri Devender Rao             return;
7295968caeeSMarri Devender Rao         }
7305968caeeSMarri Devender Rao         if (certificateType != "PEM")
7315968caeeSMarri Devender Rao         {
7325968caeeSMarri Devender Rao             messages::actionParameterNotSupported(
7335968caeeSMarri Devender Rao                 asyncResp->res, "CertificateType", "ReplaceCertificate");
7345968caeeSMarri Devender Rao             return;
7355968caeeSMarri Devender Rao         }
7365968caeeSMarri Devender Rao 
7375968caeeSMarri Devender Rao         std::string certURI;
7385968caeeSMarri Devender Rao         if (!redfish::json_util::readJson(certificateUri, asyncResp->res,
7395968caeeSMarri Devender Rao                                           "@odata.id", certURI))
7405968caeeSMarri Devender Rao         {
7415968caeeSMarri Devender Rao             messages::actionParameterMissing(
7425968caeeSMarri Devender Rao                 asyncResp->res, "ReplaceCertificate", "CertificateUri");
7435968caeeSMarri Devender Rao             return;
7445968caeeSMarri Devender Rao         }
7455968caeeSMarri Devender Rao 
7465968caeeSMarri Devender Rao         BMCWEB_LOG_INFO << "Certificate URI to replace" << certURI;
7475968caeeSMarri Devender Rao         long id = getIDFromURL(certURI);
7485968caeeSMarri Devender Rao         if (id < 0)
7495968caeeSMarri Devender Rao         {
7505968caeeSMarri Devender Rao             messages::actionParameterValueFormatError(asyncResp->res, certURI,
7515968caeeSMarri Devender Rao                                                       "CertificateUri",
7525968caeeSMarri Devender Rao                                                       "ReplaceCertificate");
7535968caeeSMarri Devender Rao             return;
7545968caeeSMarri Devender Rao         }
7555968caeeSMarri Devender Rao         std::string objectPath;
7565968caeeSMarri Devender Rao         std::string name;
75737cce918SMarri Devender Rao         std::string service;
7585968caeeSMarri Devender Rao         if (boost::starts_with(
7595968caeeSMarri Devender Rao                 certURI,
7605968caeeSMarri Devender Rao                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/"))
7615968caeeSMarri Devender Rao         {
7625968caeeSMarri Devender Rao             objectPath =
7635968caeeSMarri Devender Rao                 std::string(certs::httpsObjectPath) + "/" + std::to_string(id);
7645968caeeSMarri Devender Rao             name = "HTTPS certificate";
76537cce918SMarri Devender Rao             service = certs::httpsServiceName;
76637cce918SMarri Devender Rao         }
76737cce918SMarri Devender Rao         else if (boost::starts_with(
76837cce918SMarri Devender Rao                      certURI, "/redfish/v1/AccountService/LDAP/Certificates/"))
76937cce918SMarri Devender Rao         {
77037cce918SMarri Devender Rao             objectPath =
77137cce918SMarri Devender Rao                 std::string(certs::ldapObjectPath) + "/" + std::to_string(id);
77237cce918SMarri Devender Rao             name = "LDAP certificate";
77337cce918SMarri Devender Rao             service = certs::ldapServiceName;
7745968caeeSMarri Devender Rao         }
775cfcd5f6bSMarri Devender Rao         else if (boost::starts_with(
776cfcd5f6bSMarri Devender Rao                      certURI,
777cfcd5f6bSMarri Devender Rao                      "/redfish/v1/Managers/bmc/Truststore/Certificates/"))
778cfcd5f6bSMarri Devender Rao         {
779cfcd5f6bSMarri Devender Rao             objectPath = std::string(certs::authorityObjectPath) + "/" +
780cfcd5f6bSMarri Devender Rao                          std::to_string(id);
781cfcd5f6bSMarri Devender Rao             name = "TrustStore certificate";
782cfcd5f6bSMarri Devender Rao             service = certs::authorityServiceName;
783cfcd5f6bSMarri Devender Rao         }
7845968caeeSMarri Devender Rao         else
7855968caeeSMarri Devender Rao         {
7865968caeeSMarri Devender Rao             messages::actionParameterNotSupported(
7875968caeeSMarri Devender Rao                 asyncResp->res, "CertificateUri", "ReplaceCertificate");
7885968caeeSMarri Devender Rao             return;
7895968caeeSMarri Devender Rao         }
7905968caeeSMarri Devender Rao 
7915968caeeSMarri Devender Rao         std::shared_ptr<CertificateFile> certFile =
7925968caeeSMarri Devender Rao             std::make_shared<CertificateFile>(certificate);
7935968caeeSMarri Devender Rao         crow::connections::systemBus->async_method_call(
79437cce918SMarri Devender Rao             [asyncResp, certFile, objectPath, service, certURI, id,
7955968caeeSMarri Devender Rao              name](const boost::system::error_code ec) {
7965968caeeSMarri Devender Rao                 if (ec)
7975968caeeSMarri Devender Rao                 {
7985968caeeSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
7998aae75adSMarri Devender Rao                     messages::resourceNotFound(asyncResp->res, name,
8008aae75adSMarri Devender Rao                                                std::to_string(id));
8015968caeeSMarri Devender Rao                     return;
8025968caeeSMarri Devender Rao                 }
80337cce918SMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath, service, id,
8045968caeeSMarri Devender Rao                                          certURI, name);
8055968caeeSMarri Devender Rao                 BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
8065968caeeSMarri Devender Rao                                  << certFile->getCertFilePath();
8075968caeeSMarri Devender Rao             },
8085968caeeSMarri Devender Rao             service, objectPath, certs::certReplaceIntf, "Replace",
8095968caeeSMarri Devender Rao             certFile->getCertFilePath());
8105968caeeSMarri Devender Rao     }
8115968caeeSMarri Devender Rao }; // CertificateActionsReplaceCertificate
8125968caeeSMarri Devender Rao 
8135968caeeSMarri Devender Rao /**
8145968caeeSMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
8155968caeeSMarri Devender Rao  * of a component, account or service.
8165968caeeSMarri Devender Rao  */
8175968caeeSMarri Devender Rao class HTTPSCertificate : public Node
8185968caeeSMarri Devender Rao {
8195968caeeSMarri Devender Rao   public:
8205968caeeSMarri Devender Rao     template <typename CrowApp>
8215968caeeSMarri Devender Rao     HTTPSCertificate(CrowApp &app) :
8225968caeeSMarri Devender Rao         Node(app,
8235968caeeSMarri Devender Rao              "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/"
8245968caeeSMarri Devender Rao              "<str>/",
8255968caeeSMarri Devender Rao              std::string())
8265968caeeSMarri Devender Rao     {
8275968caeeSMarri Devender Rao         entityPrivileges = {
8285968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
8295968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
8305968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
8315968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
8325968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
8335968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
8345968caeeSMarri Devender Rao     }
8355968caeeSMarri Devender Rao 
8365968caeeSMarri Devender Rao     void doGet(crow::Response &res, const crow::Request &req,
8375968caeeSMarri Devender Rao                const std::vector<std::string> &params) override
8385968caeeSMarri Devender Rao     {
8395968caeeSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
8405968caeeSMarri Devender Rao         if (params.size() != 1)
8415968caeeSMarri Devender Rao         {
8425968caeeSMarri Devender Rao             messages::internalError(asyncResp->res);
8435968caeeSMarri Devender Rao             return;
8445968caeeSMarri Devender Rao         }
8455968caeeSMarri Devender Rao         long id = getIDFromURL(req.url);
8465968caeeSMarri Devender Rao 
8475968caeeSMarri Devender Rao         BMCWEB_LOG_DEBUG << "HTTPSCertificate::doGet ID=" << std::to_string(id);
8485968caeeSMarri Devender Rao         std::string certURL =
8495968caeeSMarri Devender Rao             "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" +
8505968caeeSMarri Devender Rao             std::to_string(id);
8515968caeeSMarri Devender Rao         std::string objectPath = certs::httpsObjectPath;
8525968caeeSMarri Devender Rao         objectPath += "/";
8535968caeeSMarri Devender Rao         objectPath += std::to_string(id);
85437cce918SMarri Devender Rao         getCertificateProperties(asyncResp, objectPath, certs::httpsServiceName,
85537cce918SMarri Devender Rao                                  id, certURL, "HTTPS Certificate");
8565968caeeSMarri Devender Rao     }
8575968caeeSMarri Devender Rao 
8585968caeeSMarri Devender Rao }; // namespace redfish
8595968caeeSMarri Devender Rao 
8605968caeeSMarri Devender Rao /**
8615968caeeSMarri Devender Rao  * Collection of HTTPS certificates
8625968caeeSMarri Devender Rao  */
8635968caeeSMarri Devender Rao class HTTPSCertificateCollection : public Node
8645968caeeSMarri Devender Rao {
8655968caeeSMarri Devender Rao   public:
8665968caeeSMarri Devender Rao     template <typename CrowApp>
8675968caeeSMarri Devender Rao     HTTPSCertificateCollection(CrowApp &app) :
8685968caeeSMarri Devender Rao         Node(app,
8695968caeeSMarri Devender Rao              "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
8705968caeeSMarri Devender Rao     {
8715968caeeSMarri Devender Rao         entityPrivileges = {
8725968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
8735968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
8745968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
8755968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
8765968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
8775968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
8785968caeeSMarri Devender Rao     }
8795968caeeSMarri Devender Rao     void doGet(crow::Response &res, const crow::Request &req,
8805968caeeSMarri Devender Rao                const std::vector<std::string> &params) override
8815968caeeSMarri Devender Rao     {
8825968caeeSMarri Devender Rao         res.jsonValue = {
8835968caeeSMarri Devender Rao             {"@odata.id",
8845968caeeSMarri Devender Rao              "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"},
8855968caeeSMarri Devender Rao             {"@odata.type", "#CertificateCollection.CertificateCollection"},
8865968caeeSMarri Devender Rao             {"@odata.context",
8875968caeeSMarri Devender Rao              "/redfish/v1/"
8885968caeeSMarri Devender Rao              "$metadata#CertificateCollection.CertificateCollection"},
8895968caeeSMarri Devender Rao             {"Name", "HTTPS Certificates Collection"},
8905968caeeSMarri Devender Rao             {"Description", "A Collection of HTTPS certificate instances"}};
8915968caeeSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
8925968caeeSMarri Devender Rao         crow::connections::systemBus->async_method_call(
8935968caeeSMarri Devender Rao             [asyncResp](const boost::system::error_code ec,
8945968caeeSMarri Devender Rao                         const ManagedObjectType &certs) {
8955968caeeSMarri Devender Rao                 if (ec)
8965968caeeSMarri Devender Rao                 {
8975968caeeSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
8985968caeeSMarri Devender Rao                     messages::internalError(asyncResp->res);
8995968caeeSMarri Devender Rao                     return;
9005968caeeSMarri Devender Rao                 }
90137cce918SMarri Devender Rao                 nlohmann::json &members = asyncResp->res.jsonValue["Members"];
9025968caeeSMarri Devender Rao                 members = nlohmann::json::array();
9035968caeeSMarri Devender Rao                 for (const auto &cert : certs)
9045968caeeSMarri Devender Rao                 {
9055968caeeSMarri Devender Rao                     long id = getIDFromURL(cert.first.str);
90637cce918SMarri Devender Rao                     if (id >= 0)
9075968caeeSMarri Devender Rao                     {
9085968caeeSMarri Devender Rao                         members.push_back(
9095968caeeSMarri Devender Rao                             {{"@odata.id",
9105968caeeSMarri Devender Rao                               "/redfish/v1/Managers/bmc/"
9115968caeeSMarri Devender Rao                               "NetworkProtocol/HTTPS/Certificates/" +
9125968caeeSMarri Devender Rao                                   std::to_string(id)}});
9135968caeeSMarri Devender Rao                     }
9145968caeeSMarri Devender Rao                 }
9155968caeeSMarri Devender Rao                 asyncResp->res.jsonValue["Members@odata.count"] =
9165968caeeSMarri Devender Rao                     members.size();
9175968caeeSMarri Devender Rao             },
91837cce918SMarri Devender Rao             certs::httpsServiceName, certs::httpsObjectPath,
91937cce918SMarri Devender Rao             certs::dbusObjManagerIntf, "GetManagedObjects");
9205968caeeSMarri Devender Rao     }
9215968caeeSMarri Devender Rao 
9225968caeeSMarri Devender Rao     void doPost(crow::Response &res, const crow::Request &req,
9235968caeeSMarri Devender Rao                 const std::vector<std::string> &params) override
9245968caeeSMarri Devender Rao     {
9255968caeeSMarri Devender Rao         BMCWEB_LOG_DEBUG << "HTTPSCertificateCollection::doPost";
9265968caeeSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
9275968caeeSMarri Devender Rao         asyncResp->res.jsonValue = {{"Name", "HTTPS Certificate"},
9285968caeeSMarri Devender Rao                                     {"Description", "HTTPS Certificate"}};
9295968caeeSMarri Devender Rao 
93058eb238fSKowalski, Kamil         std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
93158eb238fSKowalski, Kamil 
93258eb238fSKowalski, Kamil         if (certFileBody.empty())
93358eb238fSKowalski, Kamil         {
934a08752f5SZbigniew Kurzynski             BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
935a08752f5SZbigniew Kurzynski             messages::unrecognizedRequestBody(asyncResp->res);
93658eb238fSKowalski, Kamil             return;
93758eb238fSKowalski, Kamil         }
93858eb238fSKowalski, Kamil 
9395968caeeSMarri Devender Rao         std::shared_ptr<CertificateFile> certFile =
94058eb238fSKowalski, Kamil             std::make_shared<CertificateFile>(certFileBody);
9415968caeeSMarri Devender Rao 
9425968caeeSMarri Devender Rao         crow::connections::systemBus->async_method_call(
943656ec7e3SZbigniew Kurzynski             [asyncResp, certFile](const boost::system::error_code ec,
944656ec7e3SZbigniew Kurzynski                                   const std::string &objectPath) {
9455968caeeSMarri Devender Rao                 if (ec)
9465968caeeSMarri Devender Rao                 {
9475968caeeSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
9485968caeeSMarri Devender Rao                     messages::internalError(asyncResp->res);
9495968caeeSMarri Devender Rao                     return;
9505968caeeSMarri Devender Rao                 }
951656ec7e3SZbigniew Kurzynski                 long certId = getIDFromURL(objectPath);
952656ec7e3SZbigniew Kurzynski                 if (certId < 0)
953656ec7e3SZbigniew Kurzynski                 {
954656ec7e3SZbigniew Kurzynski                     BMCWEB_LOG_ERROR << "Invalid objectPath value"
955656ec7e3SZbigniew Kurzynski                                      << objectPath;
956656ec7e3SZbigniew Kurzynski                     messages::internalError(asyncResp->res);
957656ec7e3SZbigniew Kurzynski                     return;
958656ec7e3SZbigniew Kurzynski                 }
9595968caeeSMarri Devender Rao                 std::string certURL =
9605968caeeSMarri Devender Rao                     "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/"
9615968caeeSMarri Devender Rao                     "Certificates/" +
9625968caeeSMarri Devender Rao                     std::to_string(certId);
96337cce918SMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath,
96437cce918SMarri Devender Rao                                          certs::httpsServiceName, certId,
9655968caeeSMarri Devender Rao                                          certURL, "HTTPS Certificate");
9665968caeeSMarri Devender Rao                 BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
9675968caeeSMarri Devender Rao                                  << certFile->getCertFilePath();
9685968caeeSMarri Devender Rao             },
96937cce918SMarri Devender Rao             certs::httpsServiceName, certs::httpsObjectPath,
97037cce918SMarri Devender Rao             certs::certInstallIntf, "Install", certFile->getCertFilePath());
9715968caeeSMarri Devender Rao     }
9725968caeeSMarri Devender Rao }; // HTTPSCertificateCollection
9735968caeeSMarri Devender Rao 
9745968caeeSMarri Devender Rao /**
9755968caeeSMarri Devender Rao  * The certificate location schema defines a resource that an administrator
9765968caeeSMarri Devender Rao  * can use in order to locate all certificates installed on a given service.
9775968caeeSMarri Devender Rao  */
9785968caeeSMarri Devender Rao class CertificateLocations : public Node
9795968caeeSMarri Devender Rao {
9805968caeeSMarri Devender Rao   public:
9815968caeeSMarri Devender Rao     template <typename CrowApp>
9825968caeeSMarri Devender Rao     CertificateLocations(CrowApp &app) :
9835968caeeSMarri Devender Rao         Node(app, "/redfish/v1/CertificateService/CertificateLocations/")
9845968caeeSMarri Devender Rao     {
9855968caeeSMarri Devender Rao         entityPrivileges = {
9865968caeeSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
9875968caeeSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
9885968caeeSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
9895968caeeSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
9905968caeeSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
9915968caeeSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
9925968caeeSMarri Devender Rao     }
9935968caeeSMarri Devender Rao 
9945968caeeSMarri Devender Rao   private:
9955968caeeSMarri Devender Rao     void doGet(crow::Response &res, const crow::Request &req,
9965968caeeSMarri Devender Rao                const std::vector<std::string> &params) override
9975968caeeSMarri Devender Rao     {
9985968caeeSMarri Devender Rao         res.jsonValue = {
9995968caeeSMarri Devender Rao             {"@odata.id",
10005968caeeSMarri Devender Rao              "/redfish/v1/CertificateService/CertificateLocations"},
10015968caeeSMarri Devender Rao             {"@odata.type",
10025968caeeSMarri Devender Rao              "#CertificateLocations.v1_0_0.CertificateLocations"},
10035968caeeSMarri Devender Rao             {"@odata.context",
10045968caeeSMarri Devender Rao              "/redfish/v1/$metadata#CertificateLocations.CertificateLocations"},
10055968caeeSMarri Devender Rao             {"Name", "Certificate Locations"},
10065968caeeSMarri Devender Rao             {"Id", "CertificateLocations"},
10075968caeeSMarri Devender Rao             {"Description",
10085968caeeSMarri Devender Rao              "Defines a resource that an administrator can use in order to "
10095968caeeSMarri Devender Rao              "locate all certificates installed on a given service"}};
10105968caeeSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
10115968caeeSMarri Devender Rao         nlohmann::json &links =
10125968caeeSMarri Devender Rao             asyncResp->res.jsonValue["Links"]["Certificates"];
10135968caeeSMarri Devender Rao         links = nlohmann::json::array();
10145968caeeSMarri Devender Rao         getCertificateLocations(
10155968caeeSMarri Devender Rao             asyncResp,
10165968caeeSMarri Devender Rao             "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/",
101737cce918SMarri Devender Rao             certs::httpsObjectPath, certs::httpsServiceName);
101837cce918SMarri Devender Rao         getCertificateLocations(asyncResp,
101937cce918SMarri Devender Rao                                 "/redfish/v1/AccountService/LDAP/Certificates/",
102037cce918SMarri Devender Rao                                 certs::ldapObjectPath, certs::ldapServiceName);
1021cfcd5f6bSMarri Devender Rao         getCertificateLocations(
1022cfcd5f6bSMarri Devender Rao             asyncResp, "/redfish/v1/Managers/bmc/Truststore/Certificates/",
1023cfcd5f6bSMarri Devender Rao             certs::authorityObjectPath, certs::authorityServiceName);
102437cce918SMarri Devender Rao     }
102537cce918SMarri Devender Rao     /**
102637cce918SMarri Devender Rao      * @brief Retrieve the certificates installed list and append to the
102737cce918SMarri Devender Rao      * response
102837cce918SMarri Devender Rao      *
102937cce918SMarri Devender Rao      * @param[in] asyncResp Shared pointer to the response message
103037cce918SMarri Devender Rao      * @param[in] certURL  Path of the certificate object
103137cce918SMarri Devender Rao      * @param[in] path  Path of the D-Bus service object
103237cce918SMarri Devender Rao      * @return None
103337cce918SMarri Devender Rao      */
103437cce918SMarri Devender Rao     void getCertificateLocations(std::shared_ptr<AsyncResp> &asyncResp,
103537cce918SMarri Devender Rao                                  const std::string &certURL,
103637cce918SMarri Devender Rao                                  const std::string &path,
103737cce918SMarri Devender Rao                                  const std::string &service)
103837cce918SMarri Devender Rao     {
103937cce918SMarri Devender Rao         BMCWEB_LOG_DEBUG << "getCertificateLocations URI=" << certURL
104037cce918SMarri Devender Rao                          << " Path=" << path << " service= " << service;
104137cce918SMarri Devender Rao         crow::connections::systemBus->async_method_call(
104237cce918SMarri Devender Rao             [asyncResp, certURL](const boost::system::error_code ec,
104337cce918SMarri Devender Rao                                  const ManagedObjectType &certs) {
104437cce918SMarri Devender Rao                 if (ec)
104537cce918SMarri Devender Rao                 {
104637cce918SMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
104737cce918SMarri Devender Rao                     messages::internalError(asyncResp->res);
104837cce918SMarri Devender Rao                     return;
104937cce918SMarri Devender Rao                 }
105037cce918SMarri Devender Rao                 nlohmann::json &links =
105137cce918SMarri Devender Rao                     asyncResp->res.jsonValue["Links"]["Certificates"];
105237cce918SMarri Devender Rao                 for (auto &cert : certs)
105337cce918SMarri Devender Rao                 {
105437cce918SMarri Devender Rao                     long id = getIDFromURL(cert.first.str);
105537cce918SMarri Devender Rao                     if (id >= 0)
105637cce918SMarri Devender Rao                     {
105737cce918SMarri Devender Rao                         links.push_back(
105837cce918SMarri Devender Rao                             {{"@odata.id", certURL + std::to_string(id)}});
105937cce918SMarri Devender Rao                     }
106037cce918SMarri Devender Rao                 }
106137cce918SMarri Devender Rao                 asyncResp->res.jsonValue["Links"]["Certificates@odata.count"] =
106237cce918SMarri Devender Rao                     links.size();
106337cce918SMarri Devender Rao             },
106437cce918SMarri Devender Rao             service, path, certs::dbusObjManagerIntf, "GetManagedObjects");
10655968caeeSMarri Devender Rao     }
10665968caeeSMarri Devender Rao }; // CertificateLocations
106737cce918SMarri Devender Rao 
106837cce918SMarri Devender Rao /**
106937cce918SMarri Devender Rao  * Collection of LDAP certificates
107037cce918SMarri Devender Rao  */
107137cce918SMarri Devender Rao class LDAPCertificateCollection : public Node
107237cce918SMarri Devender Rao {
107337cce918SMarri Devender Rao   public:
107437cce918SMarri Devender Rao     template <typename CrowApp>
107537cce918SMarri Devender Rao     LDAPCertificateCollection(CrowApp &app) :
107637cce918SMarri Devender Rao         Node(app, "/redfish/v1/AccountService/LDAP/Certificates/")
107737cce918SMarri Devender Rao     {
107837cce918SMarri Devender Rao         entityPrivileges = {
107937cce918SMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
108037cce918SMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
108137cce918SMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
108237cce918SMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
108337cce918SMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
108437cce918SMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
108537cce918SMarri Devender Rao     }
108637cce918SMarri Devender Rao     void doGet(crow::Response &res, const crow::Request &req,
108737cce918SMarri Devender Rao                const std::vector<std::string> &params) override
108837cce918SMarri Devender Rao     {
108937cce918SMarri Devender Rao         res.jsonValue = {
109037cce918SMarri Devender Rao             {"@odata.id", "/redfish/v1/AccountService/LDAP/Certificates"},
109137cce918SMarri Devender Rao             {"@odata.type", "#CertificateCollection.CertificateCollection"},
109237cce918SMarri Devender Rao             {"@odata.context",
109337cce918SMarri Devender Rao              "/redfish/v1/"
109437cce918SMarri Devender Rao              "$metadata#CertificateCollection.CertificateCollection"},
109537cce918SMarri Devender Rao             {"Name", "LDAP Certificates Collection"},
109637cce918SMarri Devender Rao             {"Description", "A Collection of LDAP certificate instances"}};
109737cce918SMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
109837cce918SMarri Devender Rao         crow::connections::systemBus->async_method_call(
109937cce918SMarri Devender Rao             [asyncResp](const boost::system::error_code ec,
110037cce918SMarri Devender Rao                         const ManagedObjectType &certs) {
110137cce918SMarri Devender Rao                 if (ec)
110237cce918SMarri Devender Rao                 {
110337cce918SMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
110437cce918SMarri Devender Rao                     messages::internalError(asyncResp->res);
110537cce918SMarri Devender Rao                     return;
110637cce918SMarri Devender Rao                 }
110737cce918SMarri Devender Rao                 nlohmann::json &members = asyncResp->res.jsonValue["Members"];
110837cce918SMarri Devender Rao                 members = nlohmann::json::array();
110937cce918SMarri Devender Rao                 for (const auto &cert : certs)
111037cce918SMarri Devender Rao                 {
111137cce918SMarri Devender Rao                     long id = getIDFromURL(cert.first.str);
111237cce918SMarri Devender Rao                     if (id >= 0)
111337cce918SMarri Devender Rao                     {
111437cce918SMarri Devender Rao                         members.push_back(
111537cce918SMarri Devender Rao                             {{"@odata.id", "/redfish/v1/AccountService/"
111637cce918SMarri Devender Rao                                            "LDAP/Certificates/" +
111737cce918SMarri Devender Rao                                                std::to_string(id)}});
111837cce918SMarri Devender Rao                     }
111937cce918SMarri Devender Rao                 }
112037cce918SMarri Devender Rao                 asyncResp->res.jsonValue["Members@odata.count"] =
112137cce918SMarri Devender Rao                     members.size();
112237cce918SMarri Devender Rao             },
112337cce918SMarri Devender Rao             certs::ldapServiceName, certs::ldapObjectPath,
112437cce918SMarri Devender Rao             certs::dbusObjManagerIntf, "GetManagedObjects");
112537cce918SMarri Devender Rao     }
112637cce918SMarri Devender Rao 
112737cce918SMarri Devender Rao     void doPost(crow::Response &res, const crow::Request &req,
112837cce918SMarri Devender Rao                 const std::vector<std::string> &params) override
112937cce918SMarri Devender Rao     {
113037cce918SMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
113158eb238fSKowalski, Kamil         std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
113258eb238fSKowalski, Kamil 
113358eb238fSKowalski, Kamil         if (certFileBody.empty())
113458eb238fSKowalski, Kamil         {
1135a08752f5SZbigniew Kurzynski             BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
1136a08752f5SZbigniew Kurzynski             messages::unrecognizedRequestBody(asyncResp->res);
113758eb238fSKowalski, Kamil             return;
113858eb238fSKowalski, Kamil         }
113958eb238fSKowalski, Kamil 
114058eb238fSKowalski, Kamil         std::shared_ptr<CertificateFile> certFile =
114158eb238fSKowalski, Kamil             std::make_shared<CertificateFile>(certFileBody);
114258eb238fSKowalski, Kamil 
114337cce918SMarri Devender Rao         crow::connections::systemBus->async_method_call(
1144656ec7e3SZbigniew Kurzynski             [asyncResp, certFile](const boost::system::error_code ec,
1145656ec7e3SZbigniew Kurzynski                                   const std::string &objectPath) {
114637cce918SMarri Devender Rao                 if (ec)
114737cce918SMarri Devender Rao                 {
114837cce918SMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
114937cce918SMarri Devender Rao                     messages::internalError(asyncResp->res);
115037cce918SMarri Devender Rao                     return;
115137cce918SMarri Devender Rao                 }
1152656ec7e3SZbigniew Kurzynski                 long certId = getIDFromURL(objectPath);
1153656ec7e3SZbigniew Kurzynski                 if (certId < 0)
1154656ec7e3SZbigniew Kurzynski                 {
1155656ec7e3SZbigniew Kurzynski                     BMCWEB_LOG_ERROR << "Invalid objectPath value"
1156656ec7e3SZbigniew Kurzynski                                      << objectPath;
1157656ec7e3SZbigniew Kurzynski                     messages::internalError(asyncResp->res);
1158656ec7e3SZbigniew Kurzynski                     return;
1159656ec7e3SZbigniew Kurzynski                 }
116037cce918SMarri Devender Rao                 std::string certURL =
116137cce918SMarri Devender Rao                     "/redfish/v1/AccountService/LDAP/Certificates/" +
116237cce918SMarri Devender Rao                     std::to_string(certId);
116337cce918SMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath,
116437cce918SMarri Devender Rao                                          certs::ldapServiceName, certId,
116537cce918SMarri Devender Rao                                          certURL, "LDAP Certificate");
116637cce918SMarri Devender Rao                 BMCWEB_LOG_DEBUG << "LDAP certificate install file="
116737cce918SMarri Devender Rao                                  << certFile->getCertFilePath();
116837cce918SMarri Devender Rao             },
116937cce918SMarri Devender Rao             certs::ldapServiceName, certs::ldapObjectPath,
117037cce918SMarri Devender Rao             certs::certInstallIntf, "Install", certFile->getCertFilePath());
117137cce918SMarri Devender Rao     }
117237cce918SMarri Devender Rao }; // LDAPCertificateCollection
117337cce918SMarri Devender Rao 
117437cce918SMarri Devender Rao /**
117537cce918SMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
117637cce918SMarri Devender Rao  * of a component, account or service.
117737cce918SMarri Devender Rao  */
117837cce918SMarri Devender Rao class LDAPCertificate : public Node
117937cce918SMarri Devender Rao {
118037cce918SMarri Devender Rao   public:
118137cce918SMarri Devender Rao     template <typename CrowApp>
118237cce918SMarri Devender Rao     LDAPCertificate(CrowApp &app) :
118337cce918SMarri Devender Rao         Node(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/",
118437cce918SMarri Devender Rao              std::string())
118537cce918SMarri Devender Rao     {
118637cce918SMarri Devender Rao         entityPrivileges = {
118737cce918SMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
118837cce918SMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
118937cce918SMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
119037cce918SMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
119137cce918SMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
119237cce918SMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
119337cce918SMarri Devender Rao     }
119437cce918SMarri Devender Rao 
119537cce918SMarri Devender Rao     void doGet(crow::Response &res, const crow::Request &req,
119637cce918SMarri Devender Rao                const std::vector<std::string> &params) override
119737cce918SMarri Devender Rao     {
119837cce918SMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
119937cce918SMarri Devender Rao         long id = getIDFromURL(req.url);
120037cce918SMarri Devender Rao         if (id < 0)
120137cce918SMarri Devender Rao         {
120237cce918SMarri Devender Rao             BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
120337cce918SMarri Devender Rao             messages::internalError(asyncResp->res);
120437cce918SMarri Devender Rao             return;
120537cce918SMarri Devender Rao         }
120637cce918SMarri Devender Rao         BMCWEB_LOG_DEBUG << "LDAP Certificate ID=" << std::to_string(id);
120737cce918SMarri Devender Rao         std::string certURL = "/redfish/v1/AccountService/LDAP/Certificates/" +
120837cce918SMarri Devender Rao                               std::to_string(id);
120937cce918SMarri Devender Rao         std::string objectPath = certs::ldapObjectPath;
121037cce918SMarri Devender Rao         objectPath += "/";
121137cce918SMarri Devender Rao         objectPath += std::to_string(id);
121237cce918SMarri Devender Rao         getCertificateProperties(asyncResp, objectPath, certs::ldapServiceName,
121337cce918SMarri Devender Rao                                  id, certURL, "LDAP Certificate");
121437cce918SMarri Devender Rao     }
121537cce918SMarri Devender Rao }; // LDAPCertificate
1216cfcd5f6bSMarri Devender Rao /**
1217cfcd5f6bSMarri Devender Rao  * Collection of TrustStoreCertificate certificates
1218cfcd5f6bSMarri Devender Rao  */
1219cfcd5f6bSMarri Devender Rao class TrustStoreCertificateCollection : public Node
1220cfcd5f6bSMarri Devender Rao {
1221cfcd5f6bSMarri Devender Rao   public:
1222cfcd5f6bSMarri Devender Rao     template <typename CrowApp>
1223cfcd5f6bSMarri Devender Rao     TrustStoreCertificateCollection(CrowApp &app) :
1224cfcd5f6bSMarri Devender Rao         Node(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
1225cfcd5f6bSMarri Devender Rao     {
1226cfcd5f6bSMarri Devender Rao         entityPrivileges = {
1227cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
1228cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
1229cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1230cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1231cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1232cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1233cfcd5f6bSMarri Devender Rao     }
1234cfcd5f6bSMarri Devender Rao     void doGet(crow::Response &res, const crow::Request &req,
1235cfcd5f6bSMarri Devender Rao                const std::vector<std::string> &params) override
1236cfcd5f6bSMarri Devender Rao     {
1237cfcd5f6bSMarri Devender Rao         res.jsonValue = {
1238cfcd5f6bSMarri Devender Rao             {"@odata.id", "/redfish/v1/Managers/bmc/Truststore/Certificates/"},
1239cfcd5f6bSMarri Devender Rao             {"@odata.type", "#CertificateCollection.CertificateCollection"},
1240cfcd5f6bSMarri Devender Rao             {"@odata.context",
1241cfcd5f6bSMarri Devender Rao              "/redfish/v1/"
1242cfcd5f6bSMarri Devender Rao              "$metadata#CertificateCollection.CertificateCollection"},
1243cfcd5f6bSMarri Devender Rao             {"Name", "TrustStore Certificates Collection"},
1244cfcd5f6bSMarri Devender Rao             {"Description",
1245cfcd5f6bSMarri Devender Rao              "A Collection of TrustStore certificate instances"}};
1246cfcd5f6bSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
1247cfcd5f6bSMarri Devender Rao         crow::connections::systemBus->async_method_call(
1248cfcd5f6bSMarri Devender Rao             [asyncResp](const boost::system::error_code ec,
1249cfcd5f6bSMarri Devender Rao                         const ManagedObjectType &certs) {
1250cfcd5f6bSMarri Devender Rao                 if (ec)
1251cfcd5f6bSMarri Devender Rao                 {
1252cfcd5f6bSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
1253cfcd5f6bSMarri Devender Rao                     messages::internalError(asyncResp->res);
1254cfcd5f6bSMarri Devender Rao                     return;
1255cfcd5f6bSMarri Devender Rao                 }
1256cfcd5f6bSMarri Devender Rao                 nlohmann::json &members = asyncResp->res.jsonValue["Members"];
1257cfcd5f6bSMarri Devender Rao                 members = nlohmann::json::array();
1258cfcd5f6bSMarri Devender Rao                 for (const auto &cert : certs)
1259cfcd5f6bSMarri Devender Rao                 {
1260cfcd5f6bSMarri Devender Rao                     long id = getIDFromURL(cert.first.str);
1261cfcd5f6bSMarri Devender Rao                     if (id >= 0)
1262cfcd5f6bSMarri Devender Rao                     {
1263cfcd5f6bSMarri Devender Rao                         members.push_back(
1264cfcd5f6bSMarri Devender Rao                             {{"@odata.id", "/redfish/v1/Managers/bmc/"
1265cfcd5f6bSMarri Devender Rao                                            "Truststore/Certificates/" +
1266cfcd5f6bSMarri Devender Rao                                                std::to_string(id)}});
1267cfcd5f6bSMarri Devender Rao                     }
1268cfcd5f6bSMarri Devender Rao                 }
1269cfcd5f6bSMarri Devender Rao                 asyncResp->res.jsonValue["Members@odata.count"] =
1270cfcd5f6bSMarri Devender Rao                     members.size();
1271cfcd5f6bSMarri Devender Rao             },
1272cfcd5f6bSMarri Devender Rao             certs::authorityServiceName, certs::authorityObjectPath,
1273cfcd5f6bSMarri Devender Rao             certs::dbusObjManagerIntf, "GetManagedObjects");
1274cfcd5f6bSMarri Devender Rao     }
1275cfcd5f6bSMarri Devender Rao 
1276cfcd5f6bSMarri Devender Rao     void doPost(crow::Response &res, const crow::Request &req,
1277cfcd5f6bSMarri Devender Rao                 const std::vector<std::string> &params) override
1278cfcd5f6bSMarri Devender Rao     {
1279cfcd5f6bSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
1280a08752f5SZbigniew Kurzynski         std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
1281a08752f5SZbigniew Kurzynski 
1282a08752f5SZbigniew Kurzynski         if (certFileBody.empty())
1283a08752f5SZbigniew Kurzynski         {
1284a08752f5SZbigniew Kurzynski             BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
1285a08752f5SZbigniew Kurzynski             messages::unrecognizedRequestBody(asyncResp->res);
1286a08752f5SZbigniew Kurzynski             return;
1287a08752f5SZbigniew Kurzynski         }
1288a08752f5SZbigniew Kurzynski 
1289a08752f5SZbigniew Kurzynski         std::shared_ptr<CertificateFile> certFile =
1290a08752f5SZbigniew Kurzynski             std::make_shared<CertificateFile>(certFileBody);
1291cfcd5f6bSMarri Devender Rao         crow::connections::systemBus->async_method_call(
1292656ec7e3SZbigniew Kurzynski             [asyncResp, certFile](const boost::system::error_code ec,
1293656ec7e3SZbigniew Kurzynski                                   const std::string &objectPath) {
1294cfcd5f6bSMarri Devender Rao                 if (ec)
1295cfcd5f6bSMarri Devender Rao                 {
1296cfcd5f6bSMarri Devender Rao                     BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
1297cfcd5f6bSMarri Devender Rao                     messages::internalError(asyncResp->res);
1298cfcd5f6bSMarri Devender Rao                     return;
1299cfcd5f6bSMarri Devender Rao                 }
1300656ec7e3SZbigniew Kurzynski                 long certId = getIDFromURL(objectPath);
1301656ec7e3SZbigniew Kurzynski                 if (certId < 0)
1302656ec7e3SZbigniew Kurzynski                 {
1303656ec7e3SZbigniew Kurzynski                     BMCWEB_LOG_ERROR << "Invalid objectPath value"
1304656ec7e3SZbigniew Kurzynski                                      << objectPath;
1305656ec7e3SZbigniew Kurzynski                     messages::internalError(asyncResp->res);
1306656ec7e3SZbigniew Kurzynski                     return;
1307656ec7e3SZbigniew Kurzynski                 }
1308cfcd5f6bSMarri Devender Rao                 std::string certURL = "/redfish/v1/Managers/bmc/"
1309cfcd5f6bSMarri Devender Rao                                       "Truststore/Certificates/" +
1310cfcd5f6bSMarri Devender Rao                                       std::to_string(certId);
1311656ec7e3SZbigniew Kurzynski 
1312cfcd5f6bSMarri Devender Rao                 getCertificateProperties(asyncResp, objectPath,
1313cfcd5f6bSMarri Devender Rao                                          certs::authorityServiceName, certId,
1314cfcd5f6bSMarri Devender Rao                                          certURL, "TrustStore Certificate");
1315cfcd5f6bSMarri Devender Rao                 BMCWEB_LOG_DEBUG << "TrustStore certificate install file="
1316cfcd5f6bSMarri Devender Rao                                  << certFile->getCertFilePath();
1317cfcd5f6bSMarri Devender Rao             },
1318cfcd5f6bSMarri Devender Rao             certs::authorityServiceName, certs::authorityObjectPath,
1319cfcd5f6bSMarri Devender Rao             certs::certInstallIntf, "Install", certFile->getCertFilePath());
1320cfcd5f6bSMarri Devender Rao     }
1321cfcd5f6bSMarri Devender Rao }; // TrustStoreCertificateCollection
1322cfcd5f6bSMarri Devender Rao 
1323cfcd5f6bSMarri Devender Rao /**
1324cfcd5f6bSMarri Devender Rao  * Certificate resource describes a certificate used to prove the identity
1325cfcd5f6bSMarri Devender Rao  * of a component, account or service.
1326cfcd5f6bSMarri Devender Rao  */
1327cfcd5f6bSMarri Devender Rao class TrustStoreCertificate : public Node
1328cfcd5f6bSMarri Devender Rao {
1329cfcd5f6bSMarri Devender Rao   public:
1330cfcd5f6bSMarri Devender Rao     template <typename CrowApp>
1331cfcd5f6bSMarri Devender Rao     TrustStoreCertificate(CrowApp &app) :
1332cfcd5f6bSMarri Devender Rao         Node(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/",
1333cfcd5f6bSMarri Devender Rao              std::string())
1334cfcd5f6bSMarri Devender Rao     {
1335cfcd5f6bSMarri Devender Rao         entityPrivileges = {
1336cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::get, {{"Login"}}},
1337cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::head, {{"Login"}}},
1338cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1339cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1340cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1341cfcd5f6bSMarri Devender Rao             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1342cfcd5f6bSMarri Devender Rao     }
1343cfcd5f6bSMarri Devender Rao 
1344cfcd5f6bSMarri Devender Rao     void doGet(crow::Response &res, const crow::Request &req,
1345cfcd5f6bSMarri Devender Rao                const std::vector<std::string> &params) override
1346cfcd5f6bSMarri Devender Rao     {
1347cfcd5f6bSMarri Devender Rao         auto asyncResp = std::make_shared<AsyncResp>(res);
1348cfcd5f6bSMarri Devender Rao         long id = getIDFromURL(req.url);
1349cfcd5f6bSMarri Devender Rao         if (id < 0)
1350cfcd5f6bSMarri Devender Rao         {
1351cfcd5f6bSMarri Devender Rao             BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
1352cfcd5f6bSMarri Devender Rao             messages::internalError(asyncResp->res);
1353cfcd5f6bSMarri Devender Rao             return;
1354cfcd5f6bSMarri Devender Rao         }
1355cfcd5f6bSMarri Devender Rao         BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doGet ID="
1356cfcd5f6bSMarri Devender Rao                          << std::to_string(id);
1357cfcd5f6bSMarri Devender Rao         std::string certURL =
1358cfcd5f6bSMarri Devender Rao             "/redfish/v1/Managers/bmc/Truststore/Certificates/" +
1359cfcd5f6bSMarri Devender Rao             std::to_string(id);
1360cfcd5f6bSMarri Devender Rao         std::string objectPath = certs::authorityObjectPath;
1361cfcd5f6bSMarri Devender Rao         objectPath += "/";
1362cfcd5f6bSMarri Devender Rao         objectPath += std::to_string(id);
1363cfcd5f6bSMarri Devender Rao         getCertificateProperties(asyncResp, objectPath,
1364cfcd5f6bSMarri Devender Rao                                  certs::authorityServiceName, id, certURL,
1365cfcd5f6bSMarri Devender Rao                                  "TrustStore Certificate");
1366cfcd5f6bSMarri Devender Rao     }
1367*07a60299SZbigniew Kurzynski 
1368*07a60299SZbigniew Kurzynski     void doDelete(crow::Response &res, const crow::Request &req,
1369*07a60299SZbigniew Kurzynski                   const std::vector<std::string> &params) override
1370*07a60299SZbigniew Kurzynski     {
1371*07a60299SZbigniew Kurzynski         auto asyncResp = std::make_shared<AsyncResp>(res);
1372*07a60299SZbigniew Kurzynski 
1373*07a60299SZbigniew Kurzynski         if (params.size() != 1)
1374*07a60299SZbigniew Kurzynski         {
1375*07a60299SZbigniew Kurzynski             messages::internalError(asyncResp->res);
1376*07a60299SZbigniew Kurzynski             return;
1377*07a60299SZbigniew Kurzynski         }
1378*07a60299SZbigniew Kurzynski 
1379*07a60299SZbigniew Kurzynski         long id = getIDFromURL(req.url);
1380*07a60299SZbigniew Kurzynski         if (id < 0)
1381*07a60299SZbigniew Kurzynski         {
1382*07a60299SZbigniew Kurzynski             BMCWEB_LOG_ERROR << "Invalid url value: " << req.url;
1383*07a60299SZbigniew Kurzynski             messages::resourceNotFound(asyncResp->res, "TrustStore Certificate",
1384*07a60299SZbigniew Kurzynski                                        std::string(req.url));
1385*07a60299SZbigniew Kurzynski             return;
1386*07a60299SZbigniew Kurzynski         }
1387*07a60299SZbigniew Kurzynski         BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doDelete ID="
1388*07a60299SZbigniew Kurzynski                          << std::to_string(id);
1389*07a60299SZbigniew Kurzynski         std::string certPath = certs::authorityObjectPath;
1390*07a60299SZbigniew Kurzynski         certPath += "/";
1391*07a60299SZbigniew Kurzynski         certPath += std::to_string(id);
1392*07a60299SZbigniew Kurzynski 
1393*07a60299SZbigniew Kurzynski         crow::connections::systemBus->async_method_call(
1394*07a60299SZbigniew Kurzynski             [asyncResp, id](const boost::system::error_code ec) {
1395*07a60299SZbigniew Kurzynski                 if (ec)
1396*07a60299SZbigniew Kurzynski                 {
1397*07a60299SZbigniew Kurzynski                     messages::resourceNotFound(asyncResp->res,
1398*07a60299SZbigniew Kurzynski                                                "TrustStore Certificate",
1399*07a60299SZbigniew Kurzynski                                                std::to_string(id));
1400*07a60299SZbigniew Kurzynski                     return;
1401*07a60299SZbigniew Kurzynski                 }
1402*07a60299SZbigniew Kurzynski                 BMCWEB_LOG_INFO << "Certificate deleted";
1403*07a60299SZbigniew Kurzynski                 asyncResp->res.result(boost::beast::http::status::no_content);
1404*07a60299SZbigniew Kurzynski             },
1405*07a60299SZbigniew Kurzynski             certs::authorityServiceName, certPath, certs::objDeleteIntf,
1406*07a60299SZbigniew Kurzynski             "Delete");
1407*07a60299SZbigniew Kurzynski     }
1408cfcd5f6bSMarri Devender Rao }; // TrustStoreCertificate
14095968caeeSMarri Devender Rao } // namespace redfish
1410