blob: f16b169a238d4c541c7efdcd9fb24faa1ad2358c [file] [log] [blame]
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001#pragma once
2
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08003#include "app.hpp"
4#include "async_resp.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +08005#include "dbus_utility.hpp"
Ed Tanous1aa0c2b2022-02-08 12:24:30 +01006#include "http/parsing.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08007#include "http_response.hpp"
8#include "query.hpp"
9#include "registries/privilege_registry.hpp"
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +020010#include "utils/dbus_utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080011#include "utils/json_utils.hpp"
12#include "utils/time_utils.hpp"
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +020013
Jiaqing Zhao90d2d1e2022-04-13 17:01:57 +080014#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070015#include <boost/url/format.hpp>
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +020016#include <sdbusplus/asio/property.hpp>
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080017#include <sdbusplus/bus/match.hpp>
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +020018#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050019
George Liu7a1dbc42022-12-07 16:03:22 +080020#include <array>
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080021#include <memory>
George Liu7a1dbc42022-12-07 16:03:22 +080022#include <string_view>
23
Marri Devender Rao5968cae2019-01-21 10:27:12 -060024namespace redfish
25{
26namespace certs
27{
Patrick Williams89492a12023-05-10 07:51:34 -050028constexpr const char* certInstallIntf = "xyz.openbmc_project.Certs.Install";
29constexpr const char* certReplaceIntf = "xyz.openbmc_project.Certs.Replace";
30constexpr const char* objDeleteIntf = "xyz.openbmc_project.Object.Delete";
31constexpr const char* certPropIntf = "xyz.openbmc_project.Certs.Certificate";
32constexpr const char* dbusPropIntf = "org.freedesktop.DBus.Properties";
33constexpr const char* dbusObjManagerIntf = "org.freedesktop.DBus.ObjectManager";
34constexpr const char* httpsServiceName =
Marri Devender Rao37cce912019-02-20 01:05:22 -060035 "xyz.openbmc_project.Certs.Manager.Server.Https";
Patrick Williams89492a12023-05-10 07:51:34 -050036constexpr const char* ldapServiceName =
Marri Devender Rao37cce912019-02-20 01:05:22 -060037 "xyz.openbmc_project.Certs.Manager.Client.Ldap";
Patrick Williams89492a12023-05-10 07:51:34 -050038constexpr const char* authorityServiceName =
Michal Orzelb2254cc2023-07-27 14:08:32 +020039 "xyz.openbmc_project.Certs.Manager.Authority.Truststore";
Patrick Williams89492a12023-05-10 07:51:34 -050040constexpr const char* baseObjectPath = "/xyz/openbmc_project/certs";
41constexpr const char* httpsObjectPath =
Jiaqing Zhaoc6a8dfb2022-06-03 10:44:23 +080042 "/xyz/openbmc_project/certs/server/https";
Patrick Williams89492a12023-05-10 07:51:34 -050043constexpr const char* ldapObjectPath = "/xyz/openbmc_project/certs/client/ldap";
44constexpr const char* authorityObjectPath =
Michal Orzelb2254cc2023-07-27 14:08:32 +020045 "/xyz/openbmc_project/certs/authority/truststore";
Marri Devender Rao5968cae2019-01-21 10:27:12 -060046} // namespace certs
47
48/**
49 * The Certificate schema defines a Certificate Service which represents the
50 * actions available to manage certificates and links to where certificates
51 * are installed.
52 */
Marri Devender Rao5968cae2019-01-21 10:27:12 -060053
zhanghch058d1b46d2021-04-01 11:18:24 +080054inline std::string getCertificateFromReqBody(
55 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
56 const crow::Request& req)
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020057{
Ed Tanous1aa0c2b2022-02-08 12:24:30 +010058 nlohmann::json reqJson;
59 JsonParseResult ret = parseRequestAsJson(req, reqJson);
60 if (ret != JsonParseResult::Success)
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020061 {
62 // We did not receive JSON request, proceed as it is RAW data
Ed Tanous33c6b582023-02-14 15:05:48 -080063 return req.body();
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020064 }
65
66 std::string certificate;
67 std::optional<std::string> certificateType = "PEM";
68
Myung Baeafc474a2024-10-09 00:53:29 -070069 if (!json_util::readJsonPatch( //
70 req, asyncResp->res, //
71 "CertificateString", certificate, //
72 "CertificateType", certificateType //
73 ))
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020074 {
Ed Tanous62598e32023-07-17 17:06:25 -070075 BMCWEB_LOG_ERROR("Required parameters are missing");
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020076 messages::internalError(asyncResp->res);
Ed Tanousabb93cd2021-09-02 14:34:57 -070077 return {};
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020078 }
79
80 if (*certificateType != "PEM")
81 {
82 messages::propertyValueNotInList(asyncResp->res, *certificateType,
83 "CertificateType");
Ed Tanousabb93cd2021-09-02 14:34:57 -070084 return {};
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020085 }
86
87 return certificate;
88}
89
Marri Devender Rao5968cae2019-01-21 10:27:12 -060090/**
91 * Class to create a temporary certificate file for uploading to system
92 */
93class CertificateFile
94{
95 public:
96 CertificateFile() = delete;
Gunnar Mills1214b7e2020-06-04 10:11:30 -050097 CertificateFile(const CertificateFile&) = delete;
98 CertificateFile& operator=(const CertificateFile&) = delete;
99 CertificateFile(CertificateFile&&) = delete;
100 CertificateFile& operator=(CertificateFile&&) = delete;
Ed Tanous4e23a442022-06-06 09:57:26 -0700101 explicit CertificateFile(const std::string& certString)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600102 {
Ed Tanous72d52d22020-10-12 07:46:27 -0700103 std::array<char, 18> dirTemplate = {'/', 't', 'm', 'p', '/', 'C',
Ed Tanous52074382020-09-28 19:16:18 -0700104 'e', 'r', 't', 's', '.', 'X',
105 'X', 'X', 'X', 'X', 'X', '\0'};
106 char* tempDirectory = mkdtemp(dirTemplate.data());
Ed Tanouse662eae2022-01-25 10:39:19 -0800107 if (tempDirectory != nullptr)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600108 {
109 certDirectory = tempDirectory;
110 certificateFile = certDirectory / "cert.pem";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400111 std::ofstream out(certificateFile,
112 std::ofstream::out | std::ofstream::binary |
113 std::ofstream::trunc);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600114 out << certString;
115 out.close();
Ed Tanous62598e32023-07-17 17:06:25 -0700116 BMCWEB_LOG_DEBUG("Creating certificate file{}",
117 certificateFile.string());
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600118 }
119 }
120 ~CertificateFile()
121 {
122 if (std::filesystem::exists(certDirectory))
123 {
Ed Tanous62598e32023-07-17 17:06:25 -0700124 BMCWEB_LOG_DEBUG("Removing certificate file{}",
125 certificateFile.string());
Ed Tanous23a21a12020-07-25 04:45:05 +0000126 std::error_code ec;
127 std::filesystem::remove_all(certDirectory, ec);
128 if (ec)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600129 {
Ed Tanous62598e32023-07-17 17:06:25 -0700130 BMCWEB_LOG_ERROR("Failed to remove temp directory{}",
131 certDirectory.string());
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600132 }
133 }
134 }
135 std::string getCertFilePath()
136 {
137 return certificateFile;
138 }
139
140 private:
141 std::filesystem::path certificateFile;
142 std::filesystem::path certDirectory;
143};
144
145/**
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500146 * @brief Parse and update Certificate Issue/Subject property
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600147 *
148 * @param[in] asyncResp Shared pointer to the response message
149 * @param[in] str Issuer/Subject value in key=value pairs
150 * @param[in] type Issuer/Subject
151 * @return None
152 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700153inline void updateCertIssuerOrSubject(nlohmann::json& out,
Ed Tanous26ccae32023-02-16 10:28:44 -0800154 std::string_view value)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600155{
156 // example: O=openbmc-project.xyz,CN=localhost
157 std::string_view::iterator i = value.begin();
158 while (i != value.end())
159 {
160 std::string_view::iterator tokenBegin = i;
161 while (i != value.end() && *i != '=')
162 {
Patrick Williams6da47ba2023-05-11 11:53:56 -0500163 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600164 }
165 if (i == value.end())
166 {
167 break;
168 }
Ed Tanous26ccae32023-02-16 10:28:44 -0800169 std::string_view key(tokenBegin, static_cast<size_t>(i - tokenBegin));
Patrick Williams6da47ba2023-05-11 11:53:56 -0500170 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600171 tokenBegin = i;
172 while (i != value.end() && *i != ',')
173 {
Patrick Williams6da47ba2023-05-11 11:53:56 -0500174 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600175 }
Ed Tanous26ccae32023-02-16 10:28:44 -0800176 std::string_view val(tokenBegin, static_cast<size_t>(i - tokenBegin));
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600177 if (key == "L")
178 {
179 out["City"] = val;
180 }
181 else if (key == "CN")
182 {
183 out["CommonName"] = val;
184 }
185 else if (key == "C")
186 {
187 out["Country"] = val;
188 }
189 else if (key == "O")
190 {
191 out["Organization"] = val;
192 }
193 else if (key == "OU")
194 {
195 out["OrganizationalUnit"] = val;
196 }
197 else if (key == "ST")
198 {
199 out["State"] = val;
200 }
201 // skip comma character
202 if (i != value.end())
203 {
Patrick Williams6da47ba2023-05-11 11:53:56 -0500204 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600205 }
206 }
207}
208
209/**
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800210 * @brief Retrieve the installed certificate list
211 *
212 * @param[in] asyncResp Shared pointer to the response message
213 * @param[in] basePath DBus object path to search
214 * @param[in] listPtr Json pointer to the list in asyncResp
215 * @param[in] countPtr Json pointer to the count in asyncResp
216 * @return None
217 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700218inline void getCertificateList(
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400219 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
220 const std::string& basePath, const nlohmann::json::json_pointer& listPtr,
221 const nlohmann::json::json_pointer& countPtr)
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800222{
George Liu7a1dbc42022-12-07 16:03:22 +0800223 constexpr std::array<std::string_view, 1> interfaces = {
224 certs::certPropIntf};
225 dbus::utility::getSubTreePaths(
226 basePath, 0, interfaces,
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800227 [asyncResp, listPtr, countPtr](
George Liu7a1dbc42022-12-07 16:03:22 +0800228 const boost::system::error_code& ec,
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800229 const dbus::utility::MapperGetSubTreePathsResponse& certPaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400230 if (ec)
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800231 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400232 BMCWEB_LOG_ERROR("Certificate collection query failed: {}", ec);
233 messages::internalError(asyncResp->res);
234 return;
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800235 }
236
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400237 nlohmann::json& links = asyncResp->res.jsonValue[listPtr];
238 links = nlohmann::json::array();
239 for (const auto& certPath : certPaths)
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800240 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400241 sdbusplus::message::object_path objPath(certPath);
242 std::string certId = objPath.filename();
243 if (certId.empty())
244 {
245 BMCWEB_LOG_ERROR("Invalid certificate objPath {}",
246 certPath);
247 continue;
248 }
249
250 boost::urls::url certURL;
251 if (objPath.parent_path() == certs::httpsObjectPath)
252 {
253 certURL = boost::urls::format(
254 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
255 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
256 }
257 else if (objPath.parent_path() == certs::ldapObjectPath)
258 {
259 certURL = boost::urls::format(
260 "/redfish/v1/AccountService/LDAP/Certificates/{}",
261 certId);
262 }
263 else if (objPath.parent_path() == certs::authorityObjectPath)
264 {
265 certURL = boost::urls::format(
266 "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
267 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
268 }
269 else
270 {
271 continue;
272 }
273
274 nlohmann::json::object_t link;
275 link["@odata.id"] = certURL;
276 links.emplace_back(std::move(link));
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800277 }
278
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400279 asyncResp->res.jsonValue[countPtr] = links.size();
280 });
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800281}
282
283/**
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600284 * @brief Retrieve the certificates properties and append to the response
285 * message
286 *
287 * @param[in] asyncResp Shared pointer to the response message
288 * @param[in] objectPath Path of the D-Bus service object
289 * @param[in] certId Id of the certificate
290 * @param[in] certURL URL of the certificate object
291 * @param[in] name name of the certificate
292 * @return None
293 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700294inline void getCertificateProperties(
zhanghch058d1b46d2021-04-01 11:18:24 +0800295 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhaoe19e97e2022-06-06 19:43:39 +0800296 const std::string& objectPath, const std::string& service,
Jiaqing Zhao1e312592022-06-14 12:58:09 +0800297 const std::string& certId, const boost::urls::url& certURL,
Jiaqing Zhaoe19e97e2022-06-06 19:43:39 +0800298 const std::string& name)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600299{
Ed Tanous62598e32023-07-17 17:06:25 -0700300 BMCWEB_LOG_DEBUG("getCertificateProperties Path={} certId={} certURl={}",
301 objectPath, certId, certURL);
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200302 sdbusplus::asio::getAllProperties(
303 *crow::connections::systemBus, service, objectPath, certs::certPropIntf,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800304 [asyncResp, certURL, certId,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800305 name](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800306 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400307 if (ec)
308 {
309 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
310 messages::resourceNotFound(asyncResp->res, "Certificate",
311 certId);
312 return;
313 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200314
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400315 const std::string* certificateString = nullptr;
316 const std::vector<std::string>* keyUsage = nullptr;
317 const std::string* issuer = nullptr;
318 const std::string* subject = nullptr;
319 const uint64_t* validNotAfter = nullptr;
320 const uint64_t* validNotBefore = nullptr;
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200321
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400322 const bool success = sdbusplus::unpackPropertiesNoThrow(
323 dbus_utils::UnpackErrorPrinter(), properties,
324 "CertificateString", certificateString, "KeyUsage", keyUsage,
325 "Issuer", issuer, "Subject", subject, "ValidNotAfter",
326 validNotAfter, "ValidNotBefore", validNotBefore);
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200327
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400328 if (!success)
329 {
330 messages::internalError(asyncResp->res);
331 return;
332 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200333
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400334 asyncResp->res.jsonValue["@odata.id"] = certURL;
335 asyncResp->res.jsonValue["@odata.type"] =
336 "#Certificate.v1_0_0.Certificate";
337 asyncResp->res.jsonValue["Id"] = certId;
338 asyncResp->res.jsonValue["Name"] = name;
339 asyncResp->res.jsonValue["Description"] = name;
340 asyncResp->res.jsonValue["CertificateString"] = "";
341 asyncResp->res.jsonValue["KeyUsage"] = nlohmann::json::array();
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200342
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400343 if (certificateString != nullptr)
344 {
345 asyncResp->res.jsonValue["CertificateString"] =
346 *certificateString;
347 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200348
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400349 if (keyUsage != nullptr)
350 {
351 asyncResp->res.jsonValue["KeyUsage"] = *keyUsage;
352 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200353
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400354 if (issuer != nullptr)
355 {
356 updateCertIssuerOrSubject(asyncResp->res.jsonValue["Issuer"],
357 *issuer);
358 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200359
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400360 if (subject != nullptr)
361 {
362 updateCertIssuerOrSubject(asyncResp->res.jsonValue["Subject"],
363 *subject);
364 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200365
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400366 if (validNotAfter != nullptr)
367 {
368 asyncResp->res.jsonValue["ValidNotAfter"] =
369 redfish::time_utils::getDateTimeUint(*validNotAfter);
370 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200371
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400372 if (validNotBefore != nullptr)
373 {
374 asyncResp->res.jsonValue["ValidNotBefore"] =
375 redfish::time_utils::getDateTimeUint(*validNotBefore);
376 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200377
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400378 asyncResp->res.addHeader(
379 boost::beast::http::field::location,
380 std::string_view(certURL.data(), certURL.size()));
381 });
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600382}
383
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700384inline void
Jiaqing Zhao7a3a8f72022-09-29 15:15:58 +0800385 deleteCertificate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
386 const std::string& service,
387 const sdbusplus::message::object_path& objectPath)
388{
389 crow::connections::systemBus->async_method_call(
390 [asyncResp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800391 id{objectPath.filename()}](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400392 if (ec)
393 {
394 messages::resourceNotFound(asyncResp->res, "Certificate", id);
395 return;
396 }
397 BMCWEB_LOG_INFO("Certificate deleted");
398 asyncResp->res.result(boost::beast::http::status::no_content);
399 },
Jiaqing Zhao7a3a8f72022-09-29 15:15:58 +0800400 service, objectPath, certs::objDeleteIntf, "Delete");
401}
402
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800403inline void handleCertificateServiceGet(
404 App& app, const crow::Request& req,
405 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600406{
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800407 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
408 {
409 return;
410 }
411
Ninad Palsule3e72c202023-03-27 17:19:55 -0500412 if (req.session == nullptr)
413 {
414 messages::internalError(asyncResp->res);
415 return;
416 }
417
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800418 asyncResp->res.jsonValue["@odata.type"] =
419 "#CertificateService.v1_0_0.CertificateService";
420 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/CertificateService";
421 asyncResp->res.jsonValue["Id"] = "CertificateService";
422 asyncResp->res.jsonValue["Name"] = "Certificate Service";
423 asyncResp->res.jsonValue["Description"] =
424 "Actions available to manage certificates";
425 // /redfish/v1/CertificateService/CertificateLocations is something
426 // only ConfigureManager can access then only display when the user
427 // has permissions ConfigureManager
428 Privileges effectiveUserPrivileges =
Ninad Palsule3e72c202023-03-27 17:19:55 -0500429 redfish::getUserPrivileges(*req.session);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800430 if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
431 effectiveUserPrivileges))
432 {
433 asyncResp->res.jsonValue["CertificateLocations"]["@odata.id"] =
434 "/redfish/v1/CertificateService/CertificateLocations";
435 }
436 nlohmann::json& actions = asyncResp->res.jsonValue["Actions"];
437 nlohmann::json& replace = actions["#CertificateService.ReplaceCertificate"];
438 replace["target"] =
439 "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate";
440 nlohmann::json::array_t allowed;
Patrick Williamsad539542023-05-12 10:10:08 -0500441 allowed.emplace_back("PEM");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800442 replace["CertificateType@Redfish.AllowableValues"] = std::move(allowed);
443 actions["#CertificateService.GenerateCSR"]["target"] =
444 "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR";
445}
446
447inline void handleCertificateLocationsGet(
448 App& app, const crow::Request& req,
449 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
450{
451 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
452 {
453 return;
454 }
455 asyncResp->res.jsonValue["@odata.id"] =
456 "/redfish/v1/CertificateService/CertificateLocations";
457 asyncResp->res.jsonValue["@odata.type"] =
458 "#CertificateLocations.v1_0_0.CertificateLocations";
459 asyncResp->res.jsonValue["Name"] = "Certificate Locations";
460 asyncResp->res.jsonValue["Id"] = "CertificateLocations";
461 asyncResp->res.jsonValue["Description"] =
462 "Defines a resource that an administrator can use in order to "
463 "locate all certificates installed on a given service";
464
465 getCertificateList(asyncResp, certs::baseObjectPath,
466 "/Links/Certificates"_json_pointer,
467 "/Links/Certificates@odata.count"_json_pointer);
468}
469
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530470inline void handleError(const std::string_view dbusErrorName,
471 const std::string& id, const std::string& certificate,
472 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
473{
474 if (dbusErrorName == "org.freedesktop.DBus.Error.UnknownObject")
475 {
476 messages::resourceNotFound(asyncResp->res, "Certificate", id);
477 }
478 else if (dbusErrorName ==
479 "xyz.openbmc_project.Certs.Error.InvalidCertificate")
480 {
481 messages::propertyValueIncorrect(asyncResp->res, "Certificate",
482 certificate);
483 }
484 else
485 {
486 messages::internalError(asyncResp->res);
487 }
488}
489
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800490inline void handleReplaceCertificateAction(
491 App& app, const crow::Request& req,
492 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
493{
494 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
495 {
496 return;
497 }
498 std::string certificate;
Ed Tanous7a31e332024-03-06 12:17:43 -0800499 std::string certURI;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800500 std::optional<std::string> certificateType = "PEM";
501
Myung Baeafc474a2024-10-09 00:53:29 -0700502 if (!json_util::readJsonAction( //
503 req, asyncResp->res, //
504 "CertificateString", certificate, //
505 "CertificateType", certificateType, //
506 "CertificateUri/@odata.id", certURI //
507 ))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800508 {
Ed Tanous62598e32023-07-17 17:06:25 -0700509 BMCWEB_LOG_ERROR("Required parameters are missing");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800510 return;
511 }
512
513 if (!certificateType)
514 {
515 // should never happen, but it never hurts to be paranoid.
516 return;
517 }
518 if (certificateType != "PEM")
519 {
520 messages::actionParameterNotSupported(asyncResp->res, "CertificateType",
521 "ReplaceCertificate");
522 return;
523 }
524
Ed Tanous62598e32023-07-17 17:06:25 -0700525 BMCWEB_LOG_INFO("Certificate URI to replace: {}", certURI);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800526
Ed Tanous6fd29552023-10-04 09:40:14 -0700527 boost::system::result<boost::urls::url> parsedUrl =
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800528 boost::urls::parse_relative_ref(certURI);
529 if (!parsedUrl)
530 {
531 messages::actionParameterValueFormatError(
532 asyncResp->res, certURI, "CertificateUri", "ReplaceCertificate");
533 return;
534 }
535
536 std::string id;
537 sdbusplus::message::object_path objectPath;
538 std::string name;
539 std::string service;
540 if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1", "Managers",
541 "bmc", "NetworkProtocol", "HTTPS",
542 "Certificates", std::ref(id)))
543 {
Patrick Williams89492a12023-05-10 07:51:34 -0500544 objectPath = sdbusplus::message::object_path(certs::httpsObjectPath) /
545 id;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800546 name = "HTTPS certificate";
547 service = certs::httpsServiceName;
548 }
549 else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
550 "AccountService", "LDAP",
551 "Certificates", std::ref(id)))
552 {
Patrick Williams89492a12023-05-10 07:51:34 -0500553 objectPath = sdbusplus::message::object_path(certs::ldapObjectPath) /
554 id;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800555 name = "LDAP certificate";
556 service = certs::ldapServiceName;
557 }
558 else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
559 "Managers", "bmc", "Truststore",
560 "Certificates", std::ref(id)))
561 {
562 objectPath =
563 sdbusplus::message::object_path(certs::authorityObjectPath) / id;
564 name = "TrustStore certificate";
565 service = certs::authorityServiceName;
566 }
567 else
568 {
569 messages::actionParameterNotSupported(asyncResp->res, "CertificateUri",
570 "ReplaceCertificate");
571 return;
572 }
573
574 std::shared_ptr<CertificateFile> certFile =
575 std::make_shared<CertificateFile>(certificate);
576 crow::connections::systemBus->async_method_call(
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530577 [asyncResp, certFile, objectPath, service, url{*parsedUrl}, id, name,
578 certificate](const boost::system::error_code& ec,
Patrick Williamsd3e08592024-09-27 02:39:55 -0400579 sdbusplus::message_t& m) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400580 if (ec)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800581 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400582 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530583 const sd_bus_error* dbusError = m.get_error();
584 if ((dbusError != nullptr) && (dbusError->name != nullptr))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400585 {
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530586 handleError(dbusError->name, id, certificate, asyncResp);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400587 }
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530588 else
589 {
590 messages::internalError(asyncResp->res);
591 }
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800592 return;
593 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400594 getCertificateProperties(asyncResp, objectPath, service, id, url,
595 name);
596 BMCWEB_LOG_DEBUG("HTTPS certificate install file={}",
597 certFile->getCertFilePath());
598 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800599 service, objectPath, certs::certReplaceIntf, "Replace",
600 certFile->getCertFilePath());
601}
602
Ed Tanouscf9e4172022-12-21 09:30:16 -0800603// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800604static std::unique_ptr<sdbusplus::bus::match_t> csrMatcher;
605/**
606 * @brief Read data from CSR D-bus object and set to response
607 *
608 * @param[in] asyncResp Shared pointer to the response message
Ed Tanous8ece0e42024-01-02 13:16:50 -0800609 * @param[in] certURI Link to certificate collection URI
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800610 * @param[in] service D-Bus service name
611 * @param[in] certObjPath certificate D-Bus object path
612 * @param[in] csrObjPath CSR D-Bus object path
613 * @return None
614 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700615inline void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800616 const std::string& certURI, const std::string& service,
617 const std::string& certObjPath,
618 const std::string& csrObjPath)
619{
Ed Tanous62598e32023-07-17 17:06:25 -0700620 BMCWEB_LOG_DEBUG("getCSR CertObjectPath{} CSRObjectPath={} service={}",
621 certObjPath, csrObjPath, service);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800622 crow::connections::systemBus->async_method_call(
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400623 [asyncResp,
624 certURI](const boost::system::error_code& ec, const std::string& csr) {
625 if (ec)
626 {
627 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
628 messages::internalError(asyncResp->res);
629 return;
630 }
631 if (csr.empty())
632 {
633 BMCWEB_LOG_ERROR("CSR read is empty");
634 messages::internalError(asyncResp->res);
635 return;
636 }
637 asyncResp->res.jsonValue["CSRString"] = csr;
638 asyncResp->res.jsonValue["CertificateCollection"]["@odata.id"] =
639 certURI;
640 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800641 service, csrObjPath, "xyz.openbmc_project.Certs.CSR", "CSR");
642}
643
644inline void
645 handleGenerateCSRAction(App& app, const crow::Request& req,
646 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
647{
648 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
649 {
650 return;
651 }
652 static const int rsaKeyBitLength = 2048;
653
654 // Required parameters
655 std::string city;
656 std::string commonName;
657 std::string country;
658 std::string organization;
659 std::string organizationalUnit;
660 std::string state;
Ed Tanous7a31e332024-03-06 12:17:43 -0800661 std::string certURI;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800662
663 // Optional parameters
664 std::optional<std::vector<std::string>> optAlternativeNames =
665 std::vector<std::string>();
666 std::optional<std::string> optContactPerson = "";
667 std::optional<std::string> optChallengePassword = "";
668 std::optional<std::string> optEmail = "";
669 std::optional<std::string> optGivenName = "";
670 std::optional<std::string> optInitials = "";
671 std::optional<int64_t> optKeyBitLength = rsaKeyBitLength;
672 std::optional<std::string> optKeyCurveId = "secp384r1";
673 std::optional<std::string> optKeyPairAlgorithm = "EC";
674 std::optional<std::vector<std::string>> optKeyUsage =
675 std::vector<std::string>();
676 std::optional<std::string> optSurname = "";
677 std::optional<std::string> optUnstructuredName = "";
Myung Baeafc474a2024-10-09 00:53:29 -0700678 if (!json_util::readJsonAction( //
679 req, asyncResp->res, //
680 "AlternativeNames", optAlternativeNames, //
681 "CertificateCollection/@odata.id", certURI, //
682 "ChallengePassword", optChallengePassword, //
683 "City", city, //
684 "CommonName", commonName, //
685 "ContactPerson", optContactPerson, //
686 "Country", country, //
687 "Email", optEmail, //
688 "GivenName", optGivenName, //
689 "Initials", optInitials, //
690 "KeyBitLength", optKeyBitLength, //
691 "KeyCurveId", optKeyCurveId, //
692 "KeyPairAlgorithm", optKeyPairAlgorithm, //
693 "KeyUsage", optKeyUsage, //
694 "Organization", organization, //
695 "OrganizationalUnit", organizationalUnit, //
696 "State", state, //
697 "Surname", optSurname, //
698 "UnstructuredName", optUnstructuredName //
699 ))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800700 {
701 return;
702 }
703
704 // bmcweb has no way to store or decode a private key challenge
705 // password, which will likely cause bmcweb to crash on startup
706 // if this is not set on a post so not allowing the user to set
707 // value
708 if (!optChallengePassword->empty())
709 {
710 messages::actionParameterNotSupported(asyncResp->res, "GenerateCSR",
711 "ChallengePassword");
712 return;
713 }
714
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800715 std::string objectPath;
716 std::string service;
Ed Tanous253f11b2024-05-16 09:38:31 -0700717 if (certURI.starts_with(std::format(
718 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates",
719 BMCWEB_REDFISH_MANAGER_URI_NAME)))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800720 {
721 objectPath = certs::httpsObjectPath;
722 service = certs::httpsServiceName;
723 }
724 else if (certURI.starts_with(
725 "/redfish/v1/AccountService/LDAP/Certificates"))
726 {
727 objectPath = certs::ldapObjectPath;
728 service = certs::ldapServiceName;
729 }
730 else
731 {
732 messages::actionParameterNotSupported(
733 asyncResp->res, "CertificateCollection", "GenerateCSR");
734 return;
735 }
736
737 // supporting only EC and RSA algorithm
738 if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
739 {
740 messages::actionParameterNotSupported(
741 asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
742 return;
743 }
744
745 // supporting only 2048 key bit length for RSA algorithm due to
746 // time consumed in generating private key
747 if (*optKeyPairAlgorithm == "RSA" && *optKeyBitLength != rsaKeyBitLength)
748 {
Ed Tanouse2616cc2022-06-27 12:45:55 -0700749 messages::propertyValueNotInList(asyncResp->res, *optKeyBitLength,
750 "KeyBitLength");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800751 return;
752 }
753
754 // validate KeyUsage supporting only 1 type based on URL
Ed Tanous253f11b2024-05-16 09:38:31 -0700755 if (certURI.starts_with(std::format(
756 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates",
757 BMCWEB_REDFISH_MANAGER_URI_NAME)))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800758 {
759 if (optKeyUsage->empty())
760 {
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500761 optKeyUsage->emplace_back("ServerAuthentication");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800762 }
763 else if (optKeyUsage->size() == 1)
764 {
765 if ((*optKeyUsage)[0] != "ServerAuthentication")
766 {
767 messages::propertyValueNotInList(asyncResp->res,
768 (*optKeyUsage)[0], "KeyUsage");
769 return;
770 }
771 }
772 else
773 {
774 messages::actionParameterNotSupported(asyncResp->res, "KeyUsage",
775 "GenerateCSR");
776 return;
777 }
778 }
779 else if (certURI.starts_with(
780 "/redfish/v1/AccountService/LDAP/Certificates"))
781 {
782 if (optKeyUsage->empty())
783 {
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500784 optKeyUsage->emplace_back("ClientAuthentication");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800785 }
786 else if (optKeyUsage->size() == 1)
787 {
788 if ((*optKeyUsage)[0] != "ClientAuthentication")
789 {
790 messages::propertyValueNotInList(asyncResp->res,
791 (*optKeyUsage)[0], "KeyUsage");
792 return;
793 }
794 }
795 else
796 {
797 messages::actionParameterNotSupported(asyncResp->res, "KeyUsage",
798 "GenerateCSR");
799 return;
800 }
801 }
802
803 // Only allow one CSR matcher at a time so setting retry
804 // time-out and timer expiry to 10 seconds for now.
805 static const int timeOut = 10;
806 if (csrMatcher)
807 {
808 messages::serviceTemporarilyUnavailable(asyncResp->res,
809 std::to_string(timeOut));
810 return;
811 }
812
Ed Tanous8e8245d2024-04-11 22:21:38 -0700813 if (req.ioService == nullptr)
814 {
815 messages::internalError(asyncResp->res);
816 return;
817 }
818
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800819 // Make this static so it survives outside this method
820 static boost::asio::steady_timer timeout(*req.ioService);
821 timeout.expires_after(std::chrono::seconds(timeOut));
822 timeout.async_wait([asyncResp](const boost::system::error_code& ec) {
823 csrMatcher = nullptr;
824 if (ec)
825 {
826 // operation_aborted is expected if timer is canceled
827 // before completion.
828 if (ec != boost::asio::error::operation_aborted)
829 {
Ed Tanous62598e32023-07-17 17:06:25 -0700830 BMCWEB_LOG_ERROR("Async_wait failed {}", ec);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800831 }
832 return;
833 }
Ed Tanous62598e32023-07-17 17:06:25 -0700834 BMCWEB_LOG_ERROR("Timed out waiting for Generating CSR");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800835 messages::internalError(asyncResp->res);
836 });
837
838 // create a matcher to wait on CSR object
Ed Tanous62598e32023-07-17 17:06:25 -0700839 BMCWEB_LOG_DEBUG("create matcher with path {}", objectPath);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800840 std::string match("type='signal',"
841 "interface='org.freedesktop.DBus.ObjectManager',"
842 "path='" +
843 objectPath +
844 "',"
845 "member='InterfacesAdded'");
846 csrMatcher = std::make_unique<sdbusplus::bus::match_t>(
847 *crow::connections::systemBus, match,
848 [asyncResp, service, objectPath, certURI](sdbusplus::message_t& m) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400849 timeout.cancel();
850 if (m.is_method_error())
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800851 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400852 BMCWEB_LOG_ERROR("Dbus method error!!!");
853 messages::internalError(asyncResp->res);
854 return;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800855 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400856
857 dbus::utility::DBusInterfacesMap interfacesProperties;
858
859 sdbusplus::message::object_path csrObjectPath;
860 m.read(csrObjectPath, interfacesProperties);
861 BMCWEB_LOG_DEBUG("CSR object added{}", csrObjectPath.str);
862 for (const auto& interface : interfacesProperties)
863 {
864 if (interface.first == "xyz.openbmc_project.Certs.CSR")
865 {
866 getCSR(asyncResp, certURI, service, objectPath,
867 csrObjectPath.str);
868 break;
869 }
870 }
871 });
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800872 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800873 [asyncResp](const boost::system::error_code& ec, const std::string&) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400874 if (ec)
875 {
876 BMCWEB_LOG_ERROR("DBUS response error: {}", ec.message());
877 messages::internalError(asyncResp->res);
878 return;
879 }
880 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800881 service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
882 "GenerateCSR", *optAlternativeNames, *optChallengePassword, city,
883 commonName, *optContactPerson, country, *optEmail, *optGivenName,
884 *optInitials, *optKeyBitLength, *optKeyCurveId, *optKeyPairAlgorithm,
885 *optKeyUsage, organization, organizationalUnit, state, *optSurname,
886 *optUnstructuredName);
887}
888
889inline void requestRoutesCertificateService(App& app)
890{
891 BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/")
892 .privileges(redfish::privileges::getCertificateService)
893 .methods(boost::beast::http::verb::get)(
894 std::bind_front(handleCertificateServiceGet, std::ref(app)));
895
896 BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/CertificateLocations/")
897 .privileges(redfish::privileges::getCertificateLocations)
898 .methods(boost::beast::http::verb::get)(
899 std::bind_front(handleCertificateLocationsGet, std::ref(app)));
900
George Liu0fda0f12021-11-16 10:06:17 +0800901 BMCWEB_ROUTE(
902 app,
903 "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate/")
Ed Tanoused398212021-06-09 17:05:54 -0700904 .privileges(redfish::privileges::postCertificateService)
Ed Tanous002d39b2022-05-31 08:59:27 -0700905 .methods(boost::beast::http::verb::post)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800906 std::bind_front(handleReplaceCertificateAction, std::ref(app)));
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600907
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800908 BMCWEB_ROUTE(
909 app,
910 "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR/")
911 .privileges(redfish::privileges::postCertificateService)
912 .methods(boost::beast::http::verb::post)(
913 std::bind_front(handleGenerateCSRAction, std::ref(app)));
914} // requestRoutesCertificateService
915
916inline void handleHTTPSCertificateCollectionGet(
917 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -0700918 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
919 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800920{
921 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
922 {
923 return;
924 }
925
Ed Tanous253f11b2024-05-16 09:38:31 -0700926 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
927 {
928 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
929 return;
930 }
931
932 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
933 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates",
934 BMCWEB_REDFISH_MANAGER_URI_NAME);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800935 asyncResp->res.jsonValue["@odata.type"] =
936 "#CertificateCollection.CertificateCollection";
937 asyncResp->res.jsonValue["Name"] = "HTTPS Certificates Collection";
938 asyncResp->res.jsonValue["Description"] =
939 "A Collection of HTTPS certificate instances";
940
941 getCertificateList(asyncResp, certs::httpsObjectPath,
942 "/Members"_json_pointer,
943 "/Members@odata.count"_json_pointer);
944}
945
946inline void handleHTTPSCertificateCollectionPost(
947 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -0700948 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
949 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800950{
951 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
952 {
953 return;
954 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700955
956 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
957 {
958 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
959 return;
960 }
961
Ed Tanous62598e32023-07-17 17:06:25 -0700962 BMCWEB_LOG_DEBUG("HTTPSCertificateCollection::doPost");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800963
964 asyncResp->res.jsonValue["Name"] = "HTTPS Certificate";
965 asyncResp->res.jsonValue["Description"] = "HTTPS Certificate";
966
Ed Tanousb2896142024-01-31 15:25:47 -0800967 std::string certHttpBody = getCertificateFromReqBody(asyncResp, req);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800968
Ed Tanousb2896142024-01-31 15:25:47 -0800969 if (certHttpBody.empty())
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800970 {
Ed Tanous62598e32023-07-17 17:06:25 -0700971 BMCWEB_LOG_ERROR("Cannot get certificate from request body.");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800972 messages::unrecognizedRequestBody(asyncResp->res);
973 return;
974 }
975
976 std::shared_ptr<CertificateFile> certFile =
Ed Tanousb2896142024-01-31 15:25:47 -0800977 std::make_shared<CertificateFile>(certHttpBody);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800978
979 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800980 [asyncResp, certFile](const boost::system::error_code& ec,
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800981 const std::string& objectPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400982 if (ec)
983 {
984 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
985 messages::internalError(asyncResp->res);
986 return;
987 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700988
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400989 sdbusplus::message::object_path path(objectPath);
990 std::string certId = path.filename();
991 const boost::urls::url certURL = boost::urls::format(
992 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
993 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
994 getCertificateProperties(asyncResp, objectPath,
995 certs::httpsServiceName, certId, certURL,
996 "HTTPS Certificate");
997 BMCWEB_LOG_DEBUG("HTTPS certificate install file={}",
998 certFile->getCertFilePath());
999 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001000 certs::httpsServiceName, certs::httpsObjectPath, certs::certInstallIntf,
1001 "Install", certFile->getCertFilePath());
1002}
Ed Tanous002d39b2022-05-31 08:59:27 -07001003
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001004inline void handleHTTPSCertificateGet(
1005 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001006 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1007 const std::string& managerId, const std::string& certId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001008{
1009 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1010 {
1011 return;
1012 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001013
Ed Tanous253f11b2024-05-16 09:38:31 -07001014 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1015 {
1016 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1017 return;
1018 }
1019
1020 BMCWEB_LOG_DEBUG("HTTPS Certificate ID={}", certId);
Ed Tanousef4c65b2023-04-24 15:28:50 -07001021 const boost::urls::url certURL = boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -07001022 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
1023 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001024 std::string objPath =
Ed Tanous253f11b2024-05-16 09:38:31 -07001025 sdbusplus::message::object_path(certs::httpsObjectPath) / certId;
1026 getCertificateProperties(asyncResp, objPath, certs::httpsServiceName,
1027 certId, certURL, "HTTPS Certificate");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001028}
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001029
1030inline void requestRoutesHTTPSCertificate(App& app)
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001031{
Ed Tanous253f11b2024-05-16 09:38:31 -07001032 BMCWEB_ROUTE(
1033 app, "/redfish/v1/Managers/<str>/NetworkProtocol/HTTPS/Certificates/")
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001034 .privileges(redfish::privileges::getCertificateCollection)
1035 .methods(boost::beast::http::verb::get)(std::bind_front(
1036 handleHTTPSCertificateCollectionGet, std::ref(app)));
1037
Ed Tanous253f11b2024-05-16 09:38:31 -07001038 BMCWEB_ROUTE(
1039 app, "/redfish/v1/Managers/<str>/NetworkProtocol/HTTPS/Certificates/")
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001040 .privileges(redfish::privileges::postCertificateCollection)
1041 .methods(boost::beast::http::verb::post)(std::bind_front(
1042 handleHTTPSCertificateCollectionPost, std::ref(app)));
1043
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001044 BMCWEB_ROUTE(
1045 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001046 "/redfish/v1/Managers/<str>/NetworkProtocol/HTTPS/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001047 .privileges(redfish::privileges::getCertificate)
Jiaqing Zhao1e312592022-06-14 12:58:09 +08001048 .methods(boost::beast::http::verb::get)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001049 std::bind_front(handleHTTPSCertificateGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001050}
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001051
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001052inline void handleLDAPCertificateCollectionGet(
1053 App& app, const crow::Request& req,
1054 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001055{
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001056 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1057 {
1058 return;
1059 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001060
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001061 asyncResp->res.jsonValue["@odata.id"] =
1062 "/redfish/v1/AccountService/LDAP/Certificates";
1063 asyncResp->res.jsonValue["@odata.type"] =
1064 "#CertificateCollection.CertificateCollection";
1065 asyncResp->res.jsonValue["Name"] = "LDAP Certificates Collection";
1066 asyncResp->res.jsonValue["Description"] =
1067 "A Collection of LDAP certificate instances";
Ed Tanous002d39b2022-05-31 08:59:27 -07001068
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001069 getCertificateList(asyncResp, certs::ldapObjectPath,
1070 "/Members"_json_pointer,
1071 "/Members@odata.count"_json_pointer);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001072}
Marri Devender Rao37cce912019-02-20 01:05:22 -06001073
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001074inline void handleLDAPCertificateCollectionPost(
1075 App& app, const crow::Request& req,
1076 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Marri Devender Rao37cce912019-02-20 01:05:22 -06001077{
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001078 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1079 {
1080 return;
1081 }
Ed Tanousb2896142024-01-31 15:25:47 -08001082 std::string certHttpBody = getCertificateFromReqBody(asyncResp, req);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001083
Ed Tanousb2896142024-01-31 15:25:47 -08001084 if (certHttpBody.empty())
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001085 {
Ed Tanous62598e32023-07-17 17:06:25 -07001086 BMCWEB_LOG_ERROR("Cannot get certificate from request body.");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001087 messages::unrecognizedRequestBody(asyncResp->res);
1088 return;
1089 }
1090
1091 std::shared_ptr<CertificateFile> certFile =
Ed Tanousb2896142024-01-31 15:25:47 -08001092 std::make_shared<CertificateFile>(certHttpBody);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001093
1094 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001095 [asyncResp, certFile](const boost::system::error_code& ec,
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001096 const std::string& objectPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001097 if (ec)
1098 {
1099 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
1100 messages::internalError(asyncResp->res);
1101 return;
1102 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001103
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001104 sdbusplus::message::object_path path(objectPath);
1105 std::string certId = path.filename();
1106 const boost::urls::url certURL = boost::urls::format(
1107 "/redfish/v1/AccountService/LDAP/Certificates/{}", certId);
1108 getCertificateProperties(asyncResp, objectPath,
1109 certs::ldapServiceName, certId, certURL,
1110 "LDAP Certificate");
1111 BMCWEB_LOG_DEBUG("LDAP certificate install file={}",
1112 certFile->getCertFilePath());
1113 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001114 certs::ldapServiceName, certs::ldapObjectPath, certs::certInstallIntf,
1115 "Install", certFile->getCertFilePath());
1116}
Ed Tanous002d39b2022-05-31 08:59:27 -07001117
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001118inline void handleLDAPCertificateGet(
1119 App& app, const crow::Request& req,
1120 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
1121{
1122 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1123 {
1124 return;
1125 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001126
Ed Tanous62598e32023-07-17 17:06:25 -07001127 BMCWEB_LOG_DEBUG("LDAP Certificate ID={}", id);
Ed Tanousef4c65b2023-04-24 15:28:50 -07001128 const boost::urls::url certURL = boost::urls::format(
1129 "/redfish/v1/AccountService/LDAP/Certificates/{}", id);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001130 std::string objPath =
1131 sdbusplus::message::object_path(certs::ldapObjectPath) / id;
1132 getCertificateProperties(asyncResp, objPath, certs::ldapServiceName, id,
1133 certURL, "LDAP Certificate");
1134}
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001135
Jiaqing Zhao99612242022-09-29 15:31:09 +08001136inline void handleLDAPCertificateDelete(
1137 App& app, const crow::Request& req,
1138 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
1139{
1140 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1141 {
1142 return;
1143 }
1144
Ed Tanous62598e32023-07-17 17:06:25 -07001145 BMCWEB_LOG_DEBUG("Delete LDAP Certificate ID={}", id);
Jiaqing Zhao99612242022-09-29 15:31:09 +08001146 std::string objPath =
1147 sdbusplus::message::object_path(certs::ldapObjectPath) / id;
1148
1149 deleteCertificate(asyncResp, certs::ldapServiceName, objPath);
1150}
1151
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001152inline void requestRoutesLDAPCertificate(App& app)
Marri Devender Rao37cce912019-02-20 01:05:22 -06001153{
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001154 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
1155 .privileges(redfish::privileges::getCertificateCollection)
1156 .methods(boost::beast::http::verb::get)(
1157 std::bind_front(handleLDAPCertificateCollectionGet, std::ref(app)));
1158
1159 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
1160 .privileges(redfish::privileges::postCertificateCollection)
1161 .methods(boost::beast::http::verb::post)(std::bind_front(
1162 handleLDAPCertificateCollectionPost, std::ref(app)));
1163
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001164 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001165 .privileges(redfish::privileges::getCertificate)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001166 .methods(boost::beast::http::verb::get)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001167 std::bind_front(handleLDAPCertificateGet, std::ref(app)));
Jiaqing Zhao99612242022-09-29 15:31:09 +08001168
1169 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
1170 .privileges(redfish::privileges::deleteCertificate)
1171 .methods(boost::beast::http::verb::delete_)(
1172 std::bind_front(handleLDAPCertificateDelete, std::ref(app)));
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001173} // requestRoutesLDAPCertificate
1174
1175inline void handleTrustStoreCertificateCollectionGet(
1176 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001177 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1178 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001179{
1180 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1181 {
1182 return;
1183 }
1184
Ed Tanous253f11b2024-05-16 09:38:31 -07001185 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1186 {
1187 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1188 return;
1189 }
1190
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001191 asyncResp->res.jsonValue["@odata.id"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07001192 boost::urls::format("/redfish/v1/Managers/{}/Truststore/Certificates/",
1193 BMCWEB_REDFISH_MANAGER_URI_NAME);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001194 asyncResp->res.jsonValue["@odata.type"] =
1195 "#CertificateCollection.CertificateCollection";
1196 asyncResp->res.jsonValue["Name"] = "TrustStore Certificates Collection";
1197 asyncResp->res.jsonValue["Description"] =
1198 "A Collection of TrustStore certificate instances";
1199
1200 getCertificateList(asyncResp, certs::authorityObjectPath,
1201 "/Members"_json_pointer,
1202 "/Members@odata.count"_json_pointer);
1203}
1204
1205inline void handleTrustStoreCertificateCollectionPost(
1206 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001207 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1208 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001209{
1210 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1211 {
1212 return;
1213 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001214
1215 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1216 {
1217 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1218 return;
1219 }
1220
Ed Tanousb2896142024-01-31 15:25:47 -08001221 std::string certHttpBody = getCertificateFromReqBody(asyncResp, req);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001222
Ed Tanousb2896142024-01-31 15:25:47 -08001223 if (certHttpBody.empty())
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001224 {
Ed Tanous62598e32023-07-17 17:06:25 -07001225 BMCWEB_LOG_ERROR("Cannot get certificate from request body.");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001226 messages::unrecognizedRequestBody(asyncResp->res);
1227 return;
1228 }
1229
1230 std::shared_ptr<CertificateFile> certFile =
Ed Tanousb2896142024-01-31 15:25:47 -08001231 std::make_shared<CertificateFile>(certHttpBody);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001232 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001233 [asyncResp, certFile](const boost::system::error_code& ec,
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001234 const std::string& objectPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001235 if (ec)
1236 {
1237 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
1238 messages::internalError(asyncResp->res);
1239 return;
1240 }
Jiaqing Zhao717b9802022-06-06 20:24:04 +08001241
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001242 sdbusplus::message::object_path path(objectPath);
1243 std::string certId = path.filename();
1244 const boost::urls::url certURL = boost::urls::format(
1245 "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
1246 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
1247 getCertificateProperties(asyncResp, objectPath,
1248 certs::authorityServiceName, certId,
1249 certURL, "TrustStore Certificate");
1250 BMCWEB_LOG_DEBUG("TrustStore certificate install file={}",
1251 certFile->getCertFilePath());
1252 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001253 certs::authorityServiceName, certs::authorityObjectPath,
1254 certs::certInstallIntf, "Install", certFile->getCertFilePath());
1255}
1256
1257inline void handleTrustStoreCertificateGet(
1258 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001259 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1260 const std::string& managerId, const std::string& certId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001261{
1262 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1263 {
1264 return;
1265 }
1266
Ed Tanous253f11b2024-05-16 09:38:31 -07001267 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1268 {
1269 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1270 return;
1271 }
1272
1273 BMCWEB_LOG_DEBUG("Truststore Certificate ID={}", certId);
Ed Tanousef4c65b2023-04-24 15:28:50 -07001274 const boost::urls::url certURL = boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -07001275 "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
1276 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001277 std::string objPath =
Ed Tanous253f11b2024-05-16 09:38:31 -07001278 sdbusplus::message::object_path(certs::authorityObjectPath) / certId;
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001279 getCertificateProperties(asyncResp, objPath, certs::authorityServiceName,
Ed Tanous253f11b2024-05-16 09:38:31 -07001280 certId, certURL, "TrustStore Certificate");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001281}
1282
1283inline void handleTrustStoreCertificateDelete(
1284 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001285 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1286 const std::string& managerId, const std::string& certId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001287{
1288 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1289 {
1290 return;
1291 }
1292
Ed Tanous253f11b2024-05-16 09:38:31 -07001293 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1294 {
1295 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1296 return;
1297 }
1298
1299 BMCWEB_LOG_DEBUG("Delete TrustStore Certificate ID={}", certId);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001300 std::string objPath =
Ed Tanous253f11b2024-05-16 09:38:31 -07001301 sdbusplus::message::object_path(certs::authorityObjectPath) / certId;
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001302
Jiaqing Zhao7a3a8f72022-09-29 15:15:58 +08001303 deleteCertificate(asyncResp, certs::authorityServiceName, objPath);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001304}
1305
1306inline void requestRoutesTrustStoreCertificate(App& app)
Marri Devender Raocfcd5f62019-05-17 08:34:37 -05001307{
Ed Tanous253f11b2024-05-16 09:38:31 -07001308 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/Truststore/Certificates/")
Ed Tanoused398212021-06-09 17:05:54 -07001309 .privileges(redfish::privileges::getCertificate)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001310 .methods(boost::beast::http::verb::get)(std::bind_front(
1311 handleTrustStoreCertificateCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001312
Ed Tanous253f11b2024-05-16 09:38:31 -07001313 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/Truststore/Certificates/")
Ed Tanoused398212021-06-09 17:05:54 -07001314 .privileges(redfish::privileges::postCertificateCollection)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001315 .methods(boost::beast::http::verb::post)(std::bind_front(
1316 handleTrustStoreCertificateCollectionPost, std::ref(app)));
Ed Tanous002d39b2022-05-31 08:59:27 -07001317
Ed Tanous253f11b2024-05-16 09:38:31 -07001318 BMCWEB_ROUTE(app,
1319 "/redfish/v1/Managers/<str>/Truststore/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001320 .privileges(redfish::privileges::getCertificate)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001321 .methods(boost::beast::http::verb::get)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001322 std::bind_front(handleTrustStoreCertificateGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001323
Ed Tanous253f11b2024-05-16 09:38:31 -07001324 BMCWEB_ROUTE(app,
1325 "/redfish/v1/Managers/<str>/Truststore/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001326 .privileges(redfish::privileges::deleteCertificate)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001327 .methods(boost::beast::http::verb::delete_)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001328 std::bind_front(handleTrustStoreCertificateDelete, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001329} // requestRoutesTrustStoreCertificate
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001330} // namespace redfish