blob: 1b771475483b29926c2d7bd6e8884e102f97f8c6 [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
Marri Devender Rao5968cae2019-01-21 10:27:12 -06003#pragma once
4
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08005#include "app.hpp"
6#include "async_resp.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +08007#include "dbus_utility.hpp"
Ed Tanous1aa0c2b2022-02-08 12:24:30 +01008#include "http/parsing.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08009#include "http_response.hpp"
10#include "query.hpp"
11#include "registries/privilege_registry.hpp"
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +020012#include "utils/dbus_utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080013#include "utils/json_utils.hpp"
14#include "utils/time_utils.hpp"
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +020015
Jiaqing Zhao90d2d1e2022-04-13 17:01:57 +080016#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070017#include <boost/url/format.hpp>
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +020018#include <sdbusplus/asio/property.hpp>
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080019#include <sdbusplus/bus/match.hpp>
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +020020#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050021
George Liu7a1dbc42022-12-07 16:03:22 +080022#include <array>
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080023#include <memory>
George Liu7a1dbc42022-12-07 16:03:22 +080024#include <string_view>
25
Marri Devender Rao5968cae2019-01-21 10:27:12 -060026namespace redfish
27{
28namespace certs
29{
Patrick Williams89492a12023-05-10 07:51:34 -050030constexpr const char* certInstallIntf = "xyz.openbmc_project.Certs.Install";
31constexpr const char* certReplaceIntf = "xyz.openbmc_project.Certs.Replace";
32constexpr const char* objDeleteIntf = "xyz.openbmc_project.Object.Delete";
33constexpr const char* certPropIntf = "xyz.openbmc_project.Certs.Certificate";
34constexpr const char* dbusPropIntf = "org.freedesktop.DBus.Properties";
35constexpr const char* dbusObjManagerIntf = "org.freedesktop.DBus.ObjectManager";
36constexpr const char* httpsServiceName =
Marri Devender Rao37cce912019-02-20 01:05:22 -060037 "xyz.openbmc_project.Certs.Manager.Server.Https";
Patrick Williams89492a12023-05-10 07:51:34 -050038constexpr const char* ldapServiceName =
Marri Devender Rao37cce912019-02-20 01:05:22 -060039 "xyz.openbmc_project.Certs.Manager.Client.Ldap";
Patrick Williams89492a12023-05-10 07:51:34 -050040constexpr const char* authorityServiceName =
Michal Orzelb2254cc2023-07-27 14:08:32 +020041 "xyz.openbmc_project.Certs.Manager.Authority.Truststore";
Patrick Williams89492a12023-05-10 07:51:34 -050042constexpr const char* baseObjectPath = "/xyz/openbmc_project/certs";
43constexpr const char* httpsObjectPath =
Jiaqing Zhaoc6a8dfb2022-06-03 10:44:23 +080044 "/xyz/openbmc_project/certs/server/https";
Patrick Williams89492a12023-05-10 07:51:34 -050045constexpr const char* ldapObjectPath = "/xyz/openbmc_project/certs/client/ldap";
46constexpr const char* authorityObjectPath =
Michal Orzelb2254cc2023-07-27 14:08:32 +020047 "/xyz/openbmc_project/certs/authority/truststore";
Marri Devender Rao5968cae2019-01-21 10:27:12 -060048} // namespace certs
49
50/**
51 * The Certificate schema defines a Certificate Service which represents the
52 * actions available to manage certificates and links to where certificates
53 * are installed.
54 */
Marri Devender Rao5968cae2019-01-21 10:27:12 -060055
zhanghch058d1b46d2021-04-01 11:18:24 +080056inline std::string getCertificateFromReqBody(
57 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
58 const crow::Request& req)
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020059{
Ed Tanous1aa0c2b2022-02-08 12:24:30 +010060 nlohmann::json reqJson;
61 JsonParseResult ret = parseRequestAsJson(req, reqJson);
62 if (ret != JsonParseResult::Success)
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020063 {
64 // We did not receive JSON request, proceed as it is RAW data
Ed Tanous33c6b582023-02-14 15:05:48 -080065 return req.body();
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020066 }
67
68 std::string certificate;
69 std::optional<std::string> certificateType = "PEM";
70
Myung Baeafc474a2024-10-09 00:53:29 -070071 if (!json_util::readJsonPatch( //
72 req, asyncResp->res, //
73 "CertificateString", certificate, //
74 "CertificateType", certificateType //
75 ))
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020076 {
Ed Tanous62598e32023-07-17 17:06:25 -070077 BMCWEB_LOG_ERROR("Required parameters are missing");
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020078 messages::internalError(asyncResp->res);
Ed Tanousabb93cd2021-09-02 14:34:57 -070079 return {};
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020080 }
81
82 if (*certificateType != "PEM")
83 {
84 messages::propertyValueNotInList(asyncResp->res, *certificateType,
85 "CertificateType");
Ed Tanousabb93cd2021-09-02 14:34:57 -070086 return {};
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020087 }
88
89 return certificate;
90}
91
Marri Devender Rao5968cae2019-01-21 10:27:12 -060092/**
93 * Class to create a temporary certificate file for uploading to system
94 */
95class CertificateFile
96{
97 public:
98 CertificateFile() = delete;
Gunnar Mills1214b7e2020-06-04 10:11:30 -050099 CertificateFile(const CertificateFile&) = delete;
100 CertificateFile& operator=(const CertificateFile&) = delete;
101 CertificateFile(CertificateFile&&) = delete;
102 CertificateFile& operator=(CertificateFile&&) = delete;
Ed Tanous4e23a442022-06-06 09:57:26 -0700103 explicit CertificateFile(const std::string& certString)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600104 {
Ed Tanous72d52d22020-10-12 07:46:27 -0700105 std::array<char, 18> dirTemplate = {'/', 't', 'm', 'p', '/', 'C',
Ed Tanous52074382020-09-28 19:16:18 -0700106 'e', 'r', 't', 's', '.', 'X',
107 'X', 'X', 'X', 'X', 'X', '\0'};
108 char* tempDirectory = mkdtemp(dirTemplate.data());
Ed Tanouse662eae2022-01-25 10:39:19 -0800109 if (tempDirectory != nullptr)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600110 {
111 certDirectory = tempDirectory;
112 certificateFile = certDirectory / "cert.pem";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400113 std::ofstream out(certificateFile,
114 std::ofstream::out | std::ofstream::binary |
115 std::ofstream::trunc);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600116 out << certString;
117 out.close();
Ed Tanous62598e32023-07-17 17:06:25 -0700118 BMCWEB_LOG_DEBUG("Creating certificate file{}",
119 certificateFile.string());
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600120 }
121 }
122 ~CertificateFile()
123 {
124 if (std::filesystem::exists(certDirectory))
125 {
Ed Tanous62598e32023-07-17 17:06:25 -0700126 BMCWEB_LOG_DEBUG("Removing certificate file{}",
127 certificateFile.string());
Ed Tanous23a21a12020-07-25 04:45:05 +0000128 std::error_code ec;
129 std::filesystem::remove_all(certDirectory, ec);
130 if (ec)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600131 {
Ed Tanous62598e32023-07-17 17:06:25 -0700132 BMCWEB_LOG_ERROR("Failed to remove temp directory{}",
133 certDirectory.string());
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600134 }
135 }
136 }
137 std::string getCertFilePath()
138 {
139 return certificateFile;
140 }
141
142 private:
143 std::filesystem::path certificateFile;
144 std::filesystem::path certDirectory;
145};
146
147/**
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500148 * @brief Parse and update Certificate Issue/Subject property
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600149 *
150 * @param[in] asyncResp Shared pointer to the response message
151 * @param[in] str Issuer/Subject value in key=value pairs
152 * @param[in] type Issuer/Subject
153 * @return None
154 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700155inline void updateCertIssuerOrSubject(nlohmann::json& out,
Ed Tanous26ccae32023-02-16 10:28:44 -0800156 std::string_view value)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600157{
158 // example: O=openbmc-project.xyz,CN=localhost
159 std::string_view::iterator i = value.begin();
160 while (i != value.end())
161 {
162 std::string_view::iterator tokenBegin = i;
163 while (i != value.end() && *i != '=')
164 {
Patrick Williams6da47ba2023-05-11 11:53:56 -0500165 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600166 }
167 if (i == value.end())
168 {
169 break;
170 }
Ed Tanous26ccae32023-02-16 10:28:44 -0800171 std::string_view key(tokenBegin, static_cast<size_t>(i - tokenBegin));
Patrick Williams6da47ba2023-05-11 11:53:56 -0500172 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600173 tokenBegin = i;
174 while (i != value.end() && *i != ',')
175 {
Patrick Williams6da47ba2023-05-11 11:53:56 -0500176 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600177 }
Ed Tanous26ccae32023-02-16 10:28:44 -0800178 std::string_view val(tokenBegin, static_cast<size_t>(i - tokenBegin));
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600179 if (key == "L")
180 {
181 out["City"] = val;
182 }
183 else if (key == "CN")
184 {
185 out["CommonName"] = val;
186 }
187 else if (key == "C")
188 {
189 out["Country"] = val;
190 }
191 else if (key == "O")
192 {
193 out["Organization"] = val;
194 }
195 else if (key == "OU")
196 {
197 out["OrganizationalUnit"] = val;
198 }
199 else if (key == "ST")
200 {
201 out["State"] = val;
202 }
203 // skip comma character
204 if (i != value.end())
205 {
Patrick Williams6da47ba2023-05-11 11:53:56 -0500206 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600207 }
208 }
209}
210
211/**
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800212 * @brief Retrieve the installed certificate list
213 *
214 * @param[in] asyncResp Shared pointer to the response message
215 * @param[in] basePath DBus object path to search
216 * @param[in] listPtr Json pointer to the list in asyncResp
217 * @param[in] countPtr Json pointer to the count in asyncResp
218 * @return None
219 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700220inline void getCertificateList(
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400221 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
222 const std::string& basePath, const nlohmann::json::json_pointer& listPtr,
223 const nlohmann::json::json_pointer& countPtr)
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800224{
George Liu7a1dbc42022-12-07 16:03:22 +0800225 constexpr std::array<std::string_view, 1> interfaces = {
226 certs::certPropIntf};
227 dbus::utility::getSubTreePaths(
228 basePath, 0, interfaces,
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800229 [asyncResp, listPtr, countPtr](
George Liu7a1dbc42022-12-07 16:03:22 +0800230 const boost::system::error_code& ec,
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800231 const dbus::utility::MapperGetSubTreePathsResponse& certPaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400232 if (ec)
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800233 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400234 BMCWEB_LOG_ERROR("Certificate collection query failed: {}", ec);
235 messages::internalError(asyncResp->res);
236 return;
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800237 }
238
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400239 nlohmann::json& links = asyncResp->res.jsonValue[listPtr];
240 links = nlohmann::json::array();
241 for (const auto& certPath : certPaths)
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800242 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400243 sdbusplus::message::object_path objPath(certPath);
244 std::string certId = objPath.filename();
245 if (certId.empty())
246 {
247 BMCWEB_LOG_ERROR("Invalid certificate objPath {}",
248 certPath);
249 continue;
250 }
251
252 boost::urls::url certURL;
253 if (objPath.parent_path() == certs::httpsObjectPath)
254 {
255 certURL = boost::urls::format(
256 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
257 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
258 }
259 else if (objPath.parent_path() == certs::ldapObjectPath)
260 {
261 certURL = boost::urls::format(
262 "/redfish/v1/AccountService/LDAP/Certificates/{}",
263 certId);
264 }
265 else if (objPath.parent_path() == certs::authorityObjectPath)
266 {
267 certURL = boost::urls::format(
268 "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
269 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
270 }
271 else
272 {
273 continue;
274 }
275
276 nlohmann::json::object_t link;
277 link["@odata.id"] = certURL;
278 links.emplace_back(std::move(link));
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800279 }
280
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400281 asyncResp->res.jsonValue[countPtr] = links.size();
282 });
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800283}
284
285/**
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600286 * @brief Retrieve the certificates properties and append to the response
287 * message
288 *
289 * @param[in] asyncResp Shared pointer to the response message
290 * @param[in] objectPath Path of the D-Bus service object
291 * @param[in] certId Id of the certificate
292 * @param[in] certURL URL of the certificate object
293 * @param[in] name name of the certificate
294 * @return None
295 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700296inline void getCertificateProperties(
zhanghch058d1b46d2021-04-01 11:18:24 +0800297 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhaoe19e97e2022-06-06 19:43:39 +0800298 const std::string& objectPath, const std::string& service,
Jiaqing Zhao1e312592022-06-14 12:58:09 +0800299 const std::string& certId, const boost::urls::url& certURL,
Jiaqing Zhaoe19e97e2022-06-06 19:43:39 +0800300 const std::string& name)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600301{
Ed Tanous62598e32023-07-17 17:06:25 -0700302 BMCWEB_LOG_DEBUG("getCertificateProperties Path={} certId={} certURl={}",
303 objectPath, certId, certURL);
Ed Tanousdeae6a72024-11-11 21:58:57 -0800304 dbus::utility::getAllProperties(
305 service, objectPath, certs::certPropIntf,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800306 [asyncResp, certURL, certId,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800307 name](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800308 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400309 if (ec)
310 {
311 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
312 messages::resourceNotFound(asyncResp->res, "Certificate",
313 certId);
314 return;
315 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200316
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400317 const std::string* certificateString = nullptr;
318 const std::vector<std::string>* keyUsage = nullptr;
319 const std::string* issuer = nullptr;
320 const std::string* subject = nullptr;
321 const uint64_t* validNotAfter = nullptr;
322 const uint64_t* validNotBefore = nullptr;
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200323
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400324 const bool success = sdbusplus::unpackPropertiesNoThrow(
325 dbus_utils::UnpackErrorPrinter(), properties,
326 "CertificateString", certificateString, "KeyUsage", keyUsage,
327 "Issuer", issuer, "Subject", subject, "ValidNotAfter",
328 validNotAfter, "ValidNotBefore", validNotBefore);
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200329
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400330 if (!success)
331 {
332 messages::internalError(asyncResp->res);
333 return;
334 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200335
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400336 asyncResp->res.jsonValue["@odata.id"] = certURL;
337 asyncResp->res.jsonValue["@odata.type"] =
338 "#Certificate.v1_0_0.Certificate";
339 asyncResp->res.jsonValue["Id"] = certId;
340 asyncResp->res.jsonValue["Name"] = name;
341 asyncResp->res.jsonValue["Description"] = name;
342 asyncResp->res.jsonValue["CertificateString"] = "";
343 asyncResp->res.jsonValue["KeyUsage"] = nlohmann::json::array();
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200344
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400345 if (certificateString != nullptr)
346 {
347 asyncResp->res.jsonValue["CertificateString"] =
348 *certificateString;
349 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200350
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400351 if (keyUsage != nullptr)
352 {
353 asyncResp->res.jsonValue["KeyUsage"] = *keyUsage;
354 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200355
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400356 if (issuer != nullptr)
357 {
358 updateCertIssuerOrSubject(asyncResp->res.jsonValue["Issuer"],
359 *issuer);
360 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200361
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400362 if (subject != nullptr)
363 {
364 updateCertIssuerOrSubject(asyncResp->res.jsonValue["Subject"],
365 *subject);
366 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200367
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400368 if (validNotAfter != nullptr)
369 {
370 asyncResp->res.jsonValue["ValidNotAfter"] =
371 redfish::time_utils::getDateTimeUint(*validNotAfter);
372 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200373
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400374 if (validNotBefore != nullptr)
375 {
376 asyncResp->res.jsonValue["ValidNotBefore"] =
377 redfish::time_utils::getDateTimeUint(*validNotBefore);
378 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200379
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400380 asyncResp->res.addHeader(
381 boost::beast::http::field::location,
382 std::string_view(certURL.data(), certURL.size()));
383 });
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600384}
385
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700386inline void
Jiaqing Zhao7a3a8f72022-09-29 15:15:58 +0800387 deleteCertificate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
388 const std::string& service,
389 const sdbusplus::message::object_path& objectPath)
390{
391 crow::connections::systemBus->async_method_call(
392 [asyncResp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800393 id{objectPath.filename()}](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400394 if (ec)
395 {
396 messages::resourceNotFound(asyncResp->res, "Certificate", id);
397 return;
398 }
399 BMCWEB_LOG_INFO("Certificate deleted");
400 asyncResp->res.result(boost::beast::http::status::no_content);
401 },
Jiaqing Zhao7a3a8f72022-09-29 15:15:58 +0800402 service, objectPath, certs::objDeleteIntf, "Delete");
403}
404
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800405inline void handleCertificateServiceGet(
406 App& app, const crow::Request& req,
407 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600408{
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800409 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
410 {
411 return;
412 }
413
Ninad Palsule3e72c202023-03-27 17:19:55 -0500414 if (req.session == nullptr)
415 {
416 messages::internalError(asyncResp->res);
417 return;
418 }
419
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800420 asyncResp->res.jsonValue["@odata.type"] =
421 "#CertificateService.v1_0_0.CertificateService";
422 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/CertificateService";
423 asyncResp->res.jsonValue["Id"] = "CertificateService";
424 asyncResp->res.jsonValue["Name"] = "Certificate Service";
425 asyncResp->res.jsonValue["Description"] =
426 "Actions available to manage certificates";
427 // /redfish/v1/CertificateService/CertificateLocations is something
428 // only ConfigureManager can access then only display when the user
429 // has permissions ConfigureManager
430 Privileges effectiveUserPrivileges =
Ninad Palsule3e72c202023-03-27 17:19:55 -0500431 redfish::getUserPrivileges(*req.session);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800432 if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
433 effectiveUserPrivileges))
434 {
435 asyncResp->res.jsonValue["CertificateLocations"]["@odata.id"] =
436 "/redfish/v1/CertificateService/CertificateLocations";
437 }
438 nlohmann::json& actions = asyncResp->res.jsonValue["Actions"];
439 nlohmann::json& replace = actions["#CertificateService.ReplaceCertificate"];
440 replace["target"] =
441 "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate";
442 nlohmann::json::array_t allowed;
Patrick Williamsad539542023-05-12 10:10:08 -0500443 allowed.emplace_back("PEM");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800444 replace["CertificateType@Redfish.AllowableValues"] = std::move(allowed);
445 actions["#CertificateService.GenerateCSR"]["target"] =
446 "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR";
447}
448
449inline void handleCertificateLocationsGet(
450 App& app, const crow::Request& req,
451 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
452{
453 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
454 {
455 return;
456 }
457 asyncResp->res.jsonValue["@odata.id"] =
458 "/redfish/v1/CertificateService/CertificateLocations";
459 asyncResp->res.jsonValue["@odata.type"] =
460 "#CertificateLocations.v1_0_0.CertificateLocations";
461 asyncResp->res.jsonValue["Name"] = "Certificate Locations";
462 asyncResp->res.jsonValue["Id"] = "CertificateLocations";
463 asyncResp->res.jsonValue["Description"] =
464 "Defines a resource that an administrator can use in order to "
465 "locate all certificates installed on a given service";
466
467 getCertificateList(asyncResp, certs::baseObjectPath,
468 "/Links/Certificates"_json_pointer,
469 "/Links/Certificates@odata.count"_json_pointer);
470}
471
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530472inline void handleError(const std::string_view dbusErrorName,
473 const std::string& id, const std::string& certificate,
474 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
475{
476 if (dbusErrorName == "org.freedesktop.DBus.Error.UnknownObject")
477 {
478 messages::resourceNotFound(asyncResp->res, "Certificate", id);
479 }
480 else if (dbusErrorName ==
481 "xyz.openbmc_project.Certs.Error.InvalidCertificate")
482 {
483 messages::propertyValueIncorrect(asyncResp->res, "Certificate",
484 certificate);
485 }
486 else
487 {
488 messages::internalError(asyncResp->res);
489 }
490}
491
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800492inline void handleReplaceCertificateAction(
493 App& app, const crow::Request& req,
494 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
495{
496 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
497 {
498 return;
499 }
500 std::string certificate;
Ed Tanous7a31e332024-03-06 12:17:43 -0800501 std::string certURI;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800502 std::optional<std::string> certificateType = "PEM";
503
Myung Baeafc474a2024-10-09 00:53:29 -0700504 if (!json_util::readJsonAction( //
505 req, asyncResp->res, //
506 "CertificateString", certificate, //
507 "CertificateType", certificateType, //
508 "CertificateUri/@odata.id", certURI //
509 ))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800510 {
Ed Tanous62598e32023-07-17 17:06:25 -0700511 BMCWEB_LOG_ERROR("Required parameters are missing");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800512 return;
513 }
514
515 if (!certificateType)
516 {
517 // should never happen, but it never hurts to be paranoid.
518 return;
519 }
520 if (certificateType != "PEM")
521 {
522 messages::actionParameterNotSupported(asyncResp->res, "CertificateType",
523 "ReplaceCertificate");
524 return;
525 }
526
Ed Tanous62598e32023-07-17 17:06:25 -0700527 BMCWEB_LOG_INFO("Certificate URI to replace: {}", certURI);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800528
Ed Tanous6fd29552023-10-04 09:40:14 -0700529 boost::system::result<boost::urls::url> parsedUrl =
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800530 boost::urls::parse_relative_ref(certURI);
531 if (!parsedUrl)
532 {
533 messages::actionParameterValueFormatError(
534 asyncResp->res, certURI, "CertificateUri", "ReplaceCertificate");
535 return;
536 }
537
538 std::string id;
539 sdbusplus::message::object_path objectPath;
540 std::string name;
541 std::string service;
542 if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1", "Managers",
543 "bmc", "NetworkProtocol", "HTTPS",
544 "Certificates", std::ref(id)))
545 {
Patrick Williams89492a12023-05-10 07:51:34 -0500546 objectPath = sdbusplus::message::object_path(certs::httpsObjectPath) /
547 id;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800548 name = "HTTPS certificate";
549 service = certs::httpsServiceName;
550 }
551 else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
552 "AccountService", "LDAP",
553 "Certificates", std::ref(id)))
554 {
Patrick Williams89492a12023-05-10 07:51:34 -0500555 objectPath = sdbusplus::message::object_path(certs::ldapObjectPath) /
556 id;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800557 name = "LDAP certificate";
558 service = certs::ldapServiceName;
559 }
560 else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
561 "Managers", "bmc", "Truststore",
562 "Certificates", std::ref(id)))
563 {
564 objectPath =
565 sdbusplus::message::object_path(certs::authorityObjectPath) / id;
566 name = "TrustStore certificate";
567 service = certs::authorityServiceName;
568 }
569 else
570 {
571 messages::actionParameterNotSupported(asyncResp->res, "CertificateUri",
572 "ReplaceCertificate");
573 return;
574 }
575
576 std::shared_ptr<CertificateFile> certFile =
577 std::make_shared<CertificateFile>(certificate);
578 crow::connections::systemBus->async_method_call(
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530579 [asyncResp, certFile, objectPath, service, url{*parsedUrl}, id, name,
580 certificate](const boost::system::error_code& ec,
Patrick Williamsd3e08592024-09-27 02:39:55 -0400581 sdbusplus::message_t& m) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400582 if (ec)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800583 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400584 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530585 const sd_bus_error* dbusError = m.get_error();
586 if ((dbusError != nullptr) && (dbusError->name != nullptr))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400587 {
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530588 handleError(dbusError->name, id, certificate, asyncResp);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400589 }
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530590 else
591 {
592 messages::internalError(asyncResp->res);
593 }
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800594 return;
595 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400596 getCertificateProperties(asyncResp, objectPath, service, id, url,
597 name);
598 BMCWEB_LOG_DEBUG("HTTPS certificate install file={}",
599 certFile->getCertFilePath());
600 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800601 service, objectPath, certs::certReplaceIntf, "Replace",
602 certFile->getCertFilePath());
603}
604
Ed Tanouscf9e4172022-12-21 09:30:16 -0800605// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800606static std::unique_ptr<sdbusplus::bus::match_t> csrMatcher;
607/**
608 * @brief Read data from CSR D-bus object and set to response
609 *
610 * @param[in] asyncResp Shared pointer to the response message
Ed Tanous8ece0e42024-01-02 13:16:50 -0800611 * @param[in] certURI Link to certificate collection URI
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800612 * @param[in] service D-Bus service name
613 * @param[in] certObjPath certificate D-Bus object path
614 * @param[in] csrObjPath CSR D-Bus object path
615 * @return None
616 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700617inline void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800618 const std::string& certURI, const std::string& service,
619 const std::string& certObjPath,
620 const std::string& csrObjPath)
621{
Ed Tanous62598e32023-07-17 17:06:25 -0700622 BMCWEB_LOG_DEBUG("getCSR CertObjectPath{} CSRObjectPath={} service={}",
623 certObjPath, csrObjPath, service);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800624 crow::connections::systemBus->async_method_call(
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400625 [asyncResp,
626 certURI](const boost::system::error_code& ec, const std::string& csr) {
627 if (ec)
628 {
629 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
630 messages::internalError(asyncResp->res);
631 return;
632 }
633 if (csr.empty())
634 {
635 BMCWEB_LOG_ERROR("CSR read is empty");
636 messages::internalError(asyncResp->res);
637 return;
638 }
639 asyncResp->res.jsonValue["CSRString"] = csr;
640 asyncResp->res.jsonValue["CertificateCollection"]["@odata.id"] =
641 certURI;
642 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800643 service, csrObjPath, "xyz.openbmc_project.Certs.CSR", "CSR");
644}
645
646inline void
647 handleGenerateCSRAction(App& app, const crow::Request& req,
648 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
649{
650 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
651 {
652 return;
653 }
654 static const int rsaKeyBitLength = 2048;
655
656 // Required parameters
657 std::string city;
658 std::string commonName;
659 std::string country;
660 std::string organization;
661 std::string organizationalUnit;
662 std::string state;
Ed Tanous7a31e332024-03-06 12:17:43 -0800663 std::string certURI;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800664
665 // Optional parameters
666 std::optional<std::vector<std::string>> optAlternativeNames =
667 std::vector<std::string>();
668 std::optional<std::string> optContactPerson = "";
669 std::optional<std::string> optChallengePassword = "";
670 std::optional<std::string> optEmail = "";
671 std::optional<std::string> optGivenName = "";
672 std::optional<std::string> optInitials = "";
673 std::optional<int64_t> optKeyBitLength = rsaKeyBitLength;
674 std::optional<std::string> optKeyCurveId = "secp384r1";
675 std::optional<std::string> optKeyPairAlgorithm = "EC";
676 std::optional<std::vector<std::string>> optKeyUsage =
677 std::vector<std::string>();
678 std::optional<std::string> optSurname = "";
679 std::optional<std::string> optUnstructuredName = "";
Myung Baeafc474a2024-10-09 00:53:29 -0700680 if (!json_util::readJsonAction( //
681 req, asyncResp->res, //
682 "AlternativeNames", optAlternativeNames, //
683 "CertificateCollection/@odata.id", certURI, //
684 "ChallengePassword", optChallengePassword, //
685 "City", city, //
686 "CommonName", commonName, //
687 "ContactPerson", optContactPerson, //
688 "Country", country, //
689 "Email", optEmail, //
690 "GivenName", optGivenName, //
691 "Initials", optInitials, //
692 "KeyBitLength", optKeyBitLength, //
693 "KeyCurveId", optKeyCurveId, //
694 "KeyPairAlgorithm", optKeyPairAlgorithm, //
695 "KeyUsage", optKeyUsage, //
696 "Organization", organization, //
697 "OrganizationalUnit", organizationalUnit, //
698 "State", state, //
699 "Surname", optSurname, //
700 "UnstructuredName", optUnstructuredName //
701 ))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800702 {
703 return;
704 }
705
706 // bmcweb has no way to store or decode a private key challenge
707 // password, which will likely cause bmcweb to crash on startup
708 // if this is not set on a post so not allowing the user to set
709 // value
710 if (!optChallengePassword->empty())
711 {
712 messages::actionParameterNotSupported(asyncResp->res, "GenerateCSR",
713 "ChallengePassword");
714 return;
715 }
716
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800717 std::string objectPath;
718 std::string service;
Ed Tanous253f11b2024-05-16 09:38:31 -0700719 if (certURI.starts_with(std::format(
720 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates",
721 BMCWEB_REDFISH_MANAGER_URI_NAME)))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800722 {
723 objectPath = certs::httpsObjectPath;
724 service = certs::httpsServiceName;
725 }
726 else if (certURI.starts_with(
727 "/redfish/v1/AccountService/LDAP/Certificates"))
728 {
729 objectPath = certs::ldapObjectPath;
730 service = certs::ldapServiceName;
731 }
732 else
733 {
734 messages::actionParameterNotSupported(
735 asyncResp->res, "CertificateCollection", "GenerateCSR");
736 return;
737 }
738
739 // supporting only EC and RSA algorithm
740 if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
741 {
742 messages::actionParameterNotSupported(
743 asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
744 return;
745 }
746
747 // supporting only 2048 key bit length for RSA algorithm due to
748 // time consumed in generating private key
749 if (*optKeyPairAlgorithm == "RSA" && *optKeyBitLength != rsaKeyBitLength)
750 {
Ed Tanouse2616cc2022-06-27 12:45:55 -0700751 messages::propertyValueNotInList(asyncResp->res, *optKeyBitLength,
752 "KeyBitLength");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800753 return;
754 }
755
756 // validate KeyUsage supporting only 1 type based on URL
Ed Tanous253f11b2024-05-16 09:38:31 -0700757 if (certURI.starts_with(std::format(
758 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates",
759 BMCWEB_REDFISH_MANAGER_URI_NAME)))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800760 {
761 if (optKeyUsage->empty())
762 {
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500763 optKeyUsage->emplace_back("ServerAuthentication");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800764 }
765 else if (optKeyUsage->size() == 1)
766 {
767 if ((*optKeyUsage)[0] != "ServerAuthentication")
768 {
769 messages::propertyValueNotInList(asyncResp->res,
770 (*optKeyUsage)[0], "KeyUsage");
771 return;
772 }
773 }
774 else
775 {
776 messages::actionParameterNotSupported(asyncResp->res, "KeyUsage",
777 "GenerateCSR");
778 return;
779 }
780 }
781 else if (certURI.starts_with(
782 "/redfish/v1/AccountService/LDAP/Certificates"))
783 {
784 if (optKeyUsage->empty())
785 {
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500786 optKeyUsage->emplace_back("ClientAuthentication");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800787 }
788 else if (optKeyUsage->size() == 1)
789 {
790 if ((*optKeyUsage)[0] != "ClientAuthentication")
791 {
792 messages::propertyValueNotInList(asyncResp->res,
793 (*optKeyUsage)[0], "KeyUsage");
794 return;
795 }
796 }
797 else
798 {
799 messages::actionParameterNotSupported(asyncResp->res, "KeyUsage",
800 "GenerateCSR");
801 return;
802 }
803 }
804
805 // Only allow one CSR matcher at a time so setting retry
806 // time-out and timer expiry to 10 seconds for now.
807 static const int timeOut = 10;
808 if (csrMatcher)
809 {
810 messages::serviceTemporarilyUnavailable(asyncResp->res,
811 std::to_string(timeOut));
812 return;
813 }
814
Ed Tanous8e8245d2024-04-11 22:21:38 -0700815 if (req.ioService == nullptr)
816 {
817 messages::internalError(asyncResp->res);
818 return;
819 }
820
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800821 // Make this static so it survives outside this method
822 static boost::asio::steady_timer timeout(*req.ioService);
823 timeout.expires_after(std::chrono::seconds(timeOut));
824 timeout.async_wait([asyncResp](const boost::system::error_code& ec) {
825 csrMatcher = nullptr;
826 if (ec)
827 {
828 // operation_aborted is expected if timer is canceled
829 // before completion.
830 if (ec != boost::asio::error::operation_aborted)
831 {
Ed Tanous62598e32023-07-17 17:06:25 -0700832 BMCWEB_LOG_ERROR("Async_wait failed {}", ec);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800833 }
834 return;
835 }
Ed Tanous62598e32023-07-17 17:06:25 -0700836 BMCWEB_LOG_ERROR("Timed out waiting for Generating CSR");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800837 messages::internalError(asyncResp->res);
838 });
839
840 // create a matcher to wait on CSR object
Ed Tanous62598e32023-07-17 17:06:25 -0700841 BMCWEB_LOG_DEBUG("create matcher with path {}", objectPath);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800842 std::string match("type='signal',"
843 "interface='org.freedesktop.DBus.ObjectManager',"
844 "path='" +
845 objectPath +
846 "',"
847 "member='InterfacesAdded'");
848 csrMatcher = std::make_unique<sdbusplus::bus::match_t>(
849 *crow::connections::systemBus, match,
850 [asyncResp, service, objectPath, certURI](sdbusplus::message_t& m) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400851 timeout.cancel();
852 if (m.is_method_error())
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800853 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400854 BMCWEB_LOG_ERROR("Dbus method error!!!");
855 messages::internalError(asyncResp->res);
856 return;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800857 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400858
859 dbus::utility::DBusInterfacesMap interfacesProperties;
860
861 sdbusplus::message::object_path csrObjectPath;
862 m.read(csrObjectPath, interfacesProperties);
863 BMCWEB_LOG_DEBUG("CSR object added{}", csrObjectPath.str);
864 for (const auto& interface : interfacesProperties)
865 {
866 if (interface.first == "xyz.openbmc_project.Certs.CSR")
867 {
868 getCSR(asyncResp, certURI, service, objectPath,
869 csrObjectPath.str);
870 break;
871 }
872 }
873 });
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800874 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800875 [asyncResp](const boost::system::error_code& ec, const std::string&) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400876 if (ec)
877 {
878 BMCWEB_LOG_ERROR("DBUS response error: {}", ec.message());
879 messages::internalError(asyncResp->res);
880 return;
881 }
882 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800883 service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
884 "GenerateCSR", *optAlternativeNames, *optChallengePassword, city,
885 commonName, *optContactPerson, country, *optEmail, *optGivenName,
886 *optInitials, *optKeyBitLength, *optKeyCurveId, *optKeyPairAlgorithm,
887 *optKeyUsage, organization, organizationalUnit, state, *optSurname,
888 *optUnstructuredName);
889}
890
891inline void requestRoutesCertificateService(App& app)
892{
893 BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/")
894 .privileges(redfish::privileges::getCertificateService)
895 .methods(boost::beast::http::verb::get)(
896 std::bind_front(handleCertificateServiceGet, std::ref(app)));
897
898 BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/CertificateLocations/")
899 .privileges(redfish::privileges::getCertificateLocations)
900 .methods(boost::beast::http::verb::get)(
901 std::bind_front(handleCertificateLocationsGet, std::ref(app)));
902
George Liu0fda0f12021-11-16 10:06:17 +0800903 BMCWEB_ROUTE(
904 app,
905 "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate/")
Ed Tanoused398212021-06-09 17:05:54 -0700906 .privileges(redfish::privileges::postCertificateService)
Ed Tanous002d39b2022-05-31 08:59:27 -0700907 .methods(boost::beast::http::verb::post)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800908 std::bind_front(handleReplaceCertificateAction, std::ref(app)));
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600909
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800910 BMCWEB_ROUTE(
911 app,
912 "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR/")
913 .privileges(redfish::privileges::postCertificateService)
914 .methods(boost::beast::http::verb::post)(
915 std::bind_front(handleGenerateCSRAction, std::ref(app)));
916} // requestRoutesCertificateService
917
918inline void handleHTTPSCertificateCollectionGet(
919 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -0700920 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
921 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800922{
923 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
924 {
925 return;
926 }
927
Ed Tanous253f11b2024-05-16 09:38:31 -0700928 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
929 {
930 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
931 return;
932 }
933
934 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
935 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates",
936 BMCWEB_REDFISH_MANAGER_URI_NAME);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800937 asyncResp->res.jsonValue["@odata.type"] =
938 "#CertificateCollection.CertificateCollection";
939 asyncResp->res.jsonValue["Name"] = "HTTPS Certificates Collection";
940 asyncResp->res.jsonValue["Description"] =
941 "A Collection of HTTPS certificate instances";
942
943 getCertificateList(asyncResp, certs::httpsObjectPath,
944 "/Members"_json_pointer,
945 "/Members@odata.count"_json_pointer);
946}
947
948inline void handleHTTPSCertificateCollectionPost(
949 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -0700950 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
951 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800952{
953 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
954 {
955 return;
956 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700957
958 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
959 {
960 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
961 return;
962 }
963
Ed Tanous62598e32023-07-17 17:06:25 -0700964 BMCWEB_LOG_DEBUG("HTTPSCertificateCollection::doPost");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800965
966 asyncResp->res.jsonValue["Name"] = "HTTPS Certificate";
967 asyncResp->res.jsonValue["Description"] = "HTTPS Certificate";
968
Ed Tanousb2896142024-01-31 15:25:47 -0800969 std::string certHttpBody = getCertificateFromReqBody(asyncResp, req);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800970
Ed Tanousb2896142024-01-31 15:25:47 -0800971 if (certHttpBody.empty())
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800972 {
Ed Tanous62598e32023-07-17 17:06:25 -0700973 BMCWEB_LOG_ERROR("Cannot get certificate from request body.");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800974 messages::unrecognizedRequestBody(asyncResp->res);
975 return;
976 }
977
978 std::shared_ptr<CertificateFile> certFile =
Ed Tanousb2896142024-01-31 15:25:47 -0800979 std::make_shared<CertificateFile>(certHttpBody);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800980
981 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800982 [asyncResp, certFile](const boost::system::error_code& ec,
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800983 const std::string& objectPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400984 if (ec)
985 {
986 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
987 messages::internalError(asyncResp->res);
988 return;
989 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700990
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400991 sdbusplus::message::object_path path(objectPath);
992 std::string certId = path.filename();
993 const boost::urls::url certURL = boost::urls::format(
994 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
995 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
996 getCertificateProperties(asyncResp, objectPath,
997 certs::httpsServiceName, certId, certURL,
998 "HTTPS Certificate");
999 BMCWEB_LOG_DEBUG("HTTPS certificate install file={}",
1000 certFile->getCertFilePath());
1001 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001002 certs::httpsServiceName, certs::httpsObjectPath, certs::certInstallIntf,
1003 "Install", certFile->getCertFilePath());
1004}
Ed Tanous002d39b2022-05-31 08:59:27 -07001005
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001006inline void handleHTTPSCertificateGet(
1007 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001008 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1009 const std::string& managerId, const std::string& certId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001010{
1011 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1012 {
1013 return;
1014 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001015
Ed Tanous253f11b2024-05-16 09:38:31 -07001016 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1017 {
1018 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1019 return;
1020 }
1021
1022 BMCWEB_LOG_DEBUG("HTTPS Certificate ID={}", certId);
Ed Tanousef4c65b2023-04-24 15:28:50 -07001023 const boost::urls::url certURL = boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -07001024 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
1025 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001026 std::string objPath =
Ed Tanous253f11b2024-05-16 09:38:31 -07001027 sdbusplus::message::object_path(certs::httpsObjectPath) / certId;
1028 getCertificateProperties(asyncResp, objPath, certs::httpsServiceName,
1029 certId, certURL, "HTTPS Certificate");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001030}
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001031
1032inline void requestRoutesHTTPSCertificate(App& app)
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001033{
Ed Tanous253f11b2024-05-16 09:38:31 -07001034 BMCWEB_ROUTE(
1035 app, "/redfish/v1/Managers/<str>/NetworkProtocol/HTTPS/Certificates/")
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001036 .privileges(redfish::privileges::getCertificateCollection)
1037 .methods(boost::beast::http::verb::get)(std::bind_front(
1038 handleHTTPSCertificateCollectionGet, std::ref(app)));
1039
Ed Tanous253f11b2024-05-16 09:38:31 -07001040 BMCWEB_ROUTE(
1041 app, "/redfish/v1/Managers/<str>/NetworkProtocol/HTTPS/Certificates/")
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001042 .privileges(redfish::privileges::postCertificateCollection)
1043 .methods(boost::beast::http::verb::post)(std::bind_front(
1044 handleHTTPSCertificateCollectionPost, std::ref(app)));
1045
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001046 BMCWEB_ROUTE(
1047 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001048 "/redfish/v1/Managers/<str>/NetworkProtocol/HTTPS/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001049 .privileges(redfish::privileges::getCertificate)
Jiaqing Zhao1e312592022-06-14 12:58:09 +08001050 .methods(boost::beast::http::verb::get)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001051 std::bind_front(handleHTTPSCertificateGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001052}
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001053
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001054inline void handleLDAPCertificateCollectionGet(
1055 App& app, const crow::Request& req,
1056 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001057{
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001058 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1059 {
1060 return;
1061 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001062
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001063 asyncResp->res.jsonValue["@odata.id"] =
1064 "/redfish/v1/AccountService/LDAP/Certificates";
1065 asyncResp->res.jsonValue["@odata.type"] =
1066 "#CertificateCollection.CertificateCollection";
1067 asyncResp->res.jsonValue["Name"] = "LDAP Certificates Collection";
1068 asyncResp->res.jsonValue["Description"] =
1069 "A Collection of LDAP certificate instances";
Ed Tanous002d39b2022-05-31 08:59:27 -07001070
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001071 getCertificateList(asyncResp, certs::ldapObjectPath,
1072 "/Members"_json_pointer,
1073 "/Members@odata.count"_json_pointer);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001074}
Marri Devender Rao37cce912019-02-20 01:05:22 -06001075
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001076inline void handleLDAPCertificateCollectionPost(
1077 App& app, const crow::Request& req,
1078 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Marri Devender Rao37cce912019-02-20 01:05:22 -06001079{
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001080 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1081 {
1082 return;
1083 }
Ed Tanousb2896142024-01-31 15:25:47 -08001084 std::string certHttpBody = getCertificateFromReqBody(asyncResp, req);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001085
Ed Tanousb2896142024-01-31 15:25:47 -08001086 if (certHttpBody.empty())
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001087 {
Ed Tanous62598e32023-07-17 17:06:25 -07001088 BMCWEB_LOG_ERROR("Cannot get certificate from request body.");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001089 messages::unrecognizedRequestBody(asyncResp->res);
1090 return;
1091 }
1092
1093 std::shared_ptr<CertificateFile> certFile =
Ed Tanousb2896142024-01-31 15:25:47 -08001094 std::make_shared<CertificateFile>(certHttpBody);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001095
1096 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001097 [asyncResp, certFile](const boost::system::error_code& ec,
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001098 const std::string& objectPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001099 if (ec)
1100 {
1101 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
1102 messages::internalError(asyncResp->res);
1103 return;
1104 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001105
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001106 sdbusplus::message::object_path path(objectPath);
1107 std::string certId = path.filename();
1108 const boost::urls::url certURL = boost::urls::format(
1109 "/redfish/v1/AccountService/LDAP/Certificates/{}", certId);
1110 getCertificateProperties(asyncResp, objectPath,
1111 certs::ldapServiceName, certId, certURL,
1112 "LDAP Certificate");
1113 BMCWEB_LOG_DEBUG("LDAP certificate install file={}",
1114 certFile->getCertFilePath());
1115 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001116 certs::ldapServiceName, certs::ldapObjectPath, certs::certInstallIntf,
1117 "Install", certFile->getCertFilePath());
1118}
Ed Tanous002d39b2022-05-31 08:59:27 -07001119
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001120inline void handleLDAPCertificateGet(
1121 App& app, const crow::Request& req,
1122 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
1123{
1124 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1125 {
1126 return;
1127 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001128
Ed Tanous62598e32023-07-17 17:06:25 -07001129 BMCWEB_LOG_DEBUG("LDAP Certificate ID={}", id);
Ed Tanousef4c65b2023-04-24 15:28:50 -07001130 const boost::urls::url certURL = boost::urls::format(
1131 "/redfish/v1/AccountService/LDAP/Certificates/{}", id);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001132 std::string objPath =
1133 sdbusplus::message::object_path(certs::ldapObjectPath) / id;
1134 getCertificateProperties(asyncResp, objPath, certs::ldapServiceName, id,
1135 certURL, "LDAP Certificate");
1136}
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001137
Jiaqing Zhao99612242022-09-29 15:31:09 +08001138inline void handleLDAPCertificateDelete(
1139 App& app, const crow::Request& req,
1140 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
1141{
1142 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1143 {
1144 return;
1145 }
1146
Ed Tanous62598e32023-07-17 17:06:25 -07001147 BMCWEB_LOG_DEBUG("Delete LDAP Certificate ID={}", id);
Jiaqing Zhao99612242022-09-29 15:31:09 +08001148 std::string objPath =
1149 sdbusplus::message::object_path(certs::ldapObjectPath) / id;
1150
1151 deleteCertificate(asyncResp, certs::ldapServiceName, objPath);
1152}
1153
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001154inline void requestRoutesLDAPCertificate(App& app)
Marri Devender Rao37cce912019-02-20 01:05:22 -06001155{
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001156 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
1157 .privileges(redfish::privileges::getCertificateCollection)
1158 .methods(boost::beast::http::verb::get)(
1159 std::bind_front(handleLDAPCertificateCollectionGet, std::ref(app)));
1160
1161 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
1162 .privileges(redfish::privileges::postCertificateCollection)
1163 .methods(boost::beast::http::verb::post)(std::bind_front(
1164 handleLDAPCertificateCollectionPost, std::ref(app)));
1165
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001166 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001167 .privileges(redfish::privileges::getCertificate)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001168 .methods(boost::beast::http::verb::get)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001169 std::bind_front(handleLDAPCertificateGet, std::ref(app)));
Jiaqing Zhao99612242022-09-29 15:31:09 +08001170
1171 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
1172 .privileges(redfish::privileges::deleteCertificate)
1173 .methods(boost::beast::http::verb::delete_)(
1174 std::bind_front(handleLDAPCertificateDelete, std::ref(app)));
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001175} // requestRoutesLDAPCertificate
1176
1177inline void handleTrustStoreCertificateCollectionGet(
1178 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001179 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1180 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001181{
1182 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1183 {
1184 return;
1185 }
1186
Ed Tanous253f11b2024-05-16 09:38:31 -07001187 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1188 {
1189 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1190 return;
1191 }
1192
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001193 asyncResp->res.jsonValue["@odata.id"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07001194 boost::urls::format("/redfish/v1/Managers/{}/Truststore/Certificates/",
1195 BMCWEB_REDFISH_MANAGER_URI_NAME);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001196 asyncResp->res.jsonValue["@odata.type"] =
1197 "#CertificateCollection.CertificateCollection";
1198 asyncResp->res.jsonValue["Name"] = "TrustStore Certificates Collection";
1199 asyncResp->res.jsonValue["Description"] =
1200 "A Collection of TrustStore certificate instances";
1201
1202 getCertificateList(asyncResp, certs::authorityObjectPath,
1203 "/Members"_json_pointer,
1204 "/Members@odata.count"_json_pointer);
1205}
1206
1207inline void handleTrustStoreCertificateCollectionPost(
1208 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001209 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1210 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001211{
1212 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1213 {
1214 return;
1215 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001216
1217 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1218 {
1219 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1220 return;
1221 }
1222
Ed Tanousb2896142024-01-31 15:25:47 -08001223 std::string certHttpBody = getCertificateFromReqBody(asyncResp, req);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001224
Ed Tanousb2896142024-01-31 15:25:47 -08001225 if (certHttpBody.empty())
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001226 {
Ed Tanous62598e32023-07-17 17:06:25 -07001227 BMCWEB_LOG_ERROR("Cannot get certificate from request body.");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001228 messages::unrecognizedRequestBody(asyncResp->res);
1229 return;
1230 }
1231
1232 std::shared_ptr<CertificateFile> certFile =
Ed Tanousb2896142024-01-31 15:25:47 -08001233 std::make_shared<CertificateFile>(certHttpBody);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001234 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001235 [asyncResp, certFile](const boost::system::error_code& ec,
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001236 const std::string& objectPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001237 if (ec)
1238 {
1239 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
1240 messages::internalError(asyncResp->res);
1241 return;
1242 }
Jiaqing Zhao717b9802022-06-06 20:24:04 +08001243
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001244 sdbusplus::message::object_path path(objectPath);
1245 std::string certId = path.filename();
1246 const boost::urls::url certURL = boost::urls::format(
1247 "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
1248 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
1249 getCertificateProperties(asyncResp, objectPath,
1250 certs::authorityServiceName, certId,
1251 certURL, "TrustStore Certificate");
1252 BMCWEB_LOG_DEBUG("TrustStore certificate install file={}",
1253 certFile->getCertFilePath());
1254 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001255 certs::authorityServiceName, certs::authorityObjectPath,
1256 certs::certInstallIntf, "Install", certFile->getCertFilePath());
1257}
1258
1259inline void handleTrustStoreCertificateGet(
1260 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001261 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1262 const std::string& managerId, const std::string& certId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001263{
1264 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1265 {
1266 return;
1267 }
1268
Ed Tanous253f11b2024-05-16 09:38:31 -07001269 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1270 {
1271 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1272 return;
1273 }
1274
1275 BMCWEB_LOG_DEBUG("Truststore Certificate ID={}", certId);
Ed Tanousef4c65b2023-04-24 15:28:50 -07001276 const boost::urls::url certURL = boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -07001277 "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
1278 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001279 std::string objPath =
Ed Tanous253f11b2024-05-16 09:38:31 -07001280 sdbusplus::message::object_path(certs::authorityObjectPath) / certId;
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001281 getCertificateProperties(asyncResp, objPath, certs::authorityServiceName,
Ed Tanous253f11b2024-05-16 09:38:31 -07001282 certId, certURL, "TrustStore Certificate");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001283}
1284
1285inline void handleTrustStoreCertificateDelete(
1286 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001287 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1288 const std::string& managerId, const std::string& certId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001289{
1290 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1291 {
1292 return;
1293 }
1294
Ed Tanous253f11b2024-05-16 09:38:31 -07001295 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1296 {
1297 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1298 return;
1299 }
1300
1301 BMCWEB_LOG_DEBUG("Delete TrustStore Certificate ID={}", certId);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001302 std::string objPath =
Ed Tanous253f11b2024-05-16 09:38:31 -07001303 sdbusplus::message::object_path(certs::authorityObjectPath) / certId;
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001304
Jiaqing Zhao7a3a8f72022-09-29 15:15:58 +08001305 deleteCertificate(asyncResp, certs::authorityServiceName, objPath);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001306}
1307
1308inline void requestRoutesTrustStoreCertificate(App& app)
Marri Devender Raocfcd5f62019-05-17 08:34:37 -05001309{
Ed Tanous253f11b2024-05-16 09:38:31 -07001310 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/Truststore/Certificates/")
Ed Tanoused398212021-06-09 17:05:54 -07001311 .privileges(redfish::privileges::getCertificate)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001312 .methods(boost::beast::http::verb::get)(std::bind_front(
1313 handleTrustStoreCertificateCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001314
Ed Tanous253f11b2024-05-16 09:38:31 -07001315 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/Truststore/Certificates/")
Ed Tanoused398212021-06-09 17:05:54 -07001316 .privileges(redfish::privileges::postCertificateCollection)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001317 .methods(boost::beast::http::verb::post)(std::bind_front(
1318 handleTrustStoreCertificateCollectionPost, std::ref(app)));
Ed Tanous002d39b2022-05-31 08:59:27 -07001319
Ed Tanous253f11b2024-05-16 09:38:31 -07001320 BMCWEB_ROUTE(app,
1321 "/redfish/v1/Managers/<str>/Truststore/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001322 .privileges(redfish::privileges::getCertificate)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001323 .methods(boost::beast::http::verb::get)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001324 std::bind_front(handleTrustStoreCertificateGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001325
Ed Tanous253f11b2024-05-16 09:38:31 -07001326 BMCWEB_ROUTE(app,
1327 "/redfish/v1/Managers/<str>/Truststore/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001328 .privileges(redfish::privileges::deleteCertificate)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001329 .methods(boost::beast::http::verb::delete_)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001330 std::bind_front(handleTrustStoreCertificateDelete, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001331} // requestRoutesTrustStoreCertificate
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001332} // namespace redfish