blob: cb391bc75e56d48e57077117c7e3ead77b781a99 [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 Tanousd7857202025-01-28 15:32:26 -08005#include "bmcweb_config.h"
6
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08007#include "app.hpp"
8#include "async_resp.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -08009#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080010#include "dbus_utility.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080011#include "error_messages.hpp"
Ed Tanous1aa0c2b2022-02-08 12:24:30 +010012#include "http/parsing.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080013#include "http_request.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080014#include "http_response.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080015#include "logging.hpp"
16#include "privileges.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080017#include "query.hpp"
18#include "registries/privilege_registry.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080019#include "utility.hpp"
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +020020#include "utils/dbus_utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080021#include "utils/json_utils.hpp"
22#include "utils/time_utils.hpp"
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +020023
Ed Tanousd7857202025-01-28 15:32:26 -080024// NOLINTNEXTLINE(modernize-deprecated-headers)
25#include <stdlib.h>
26#include <systemd/sd-bus.h>
27
28#include <boost/asio/error.hpp>
29#include <boost/asio/steady_timer.hpp>
30#include <boost/beast/http/field.hpp>
31#include <boost/beast/http/status.hpp>
32#include <boost/beast/http/verb.hpp>
33#include <boost/system/result.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070034#include <boost/url/format.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080035#include <boost/url/parse.hpp>
36#include <boost/url/url.hpp>
37#include <nlohmann/json.hpp>
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080038#include <sdbusplus/bus/match.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080039#include <sdbusplus/message.hpp>
40#include <sdbusplus/message/native_types.hpp>
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +020041#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050042
George Liu7a1dbc42022-12-07 16:03:22 +080043#include <array>
Ed Tanousd7857202025-01-28 15:32:26 -080044#include <chrono>
45#include <cstddef>
46#include <cstdint>
47#include <cstdlib>
48#include <filesystem>
49#include <format>
50#include <fstream>
51#include <functional>
52#include <iterator>
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080053#include <memory>
Ed Tanousd7857202025-01-28 15:32:26 -080054#include <optional>
55#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080056#include <string_view>
Ed Tanousd7857202025-01-28 15:32:26 -080057#include <system_error>
58#include <utility>
59#include <vector>
George Liu7a1dbc42022-12-07 16:03:22 +080060
Marri Devender Rao5968cae2019-01-21 10:27:12 -060061namespace redfish
62{
63namespace certs
64{
Patrick Williams89492a12023-05-10 07:51:34 -050065constexpr const char* certInstallIntf = "xyz.openbmc_project.Certs.Install";
66constexpr const char* certReplaceIntf = "xyz.openbmc_project.Certs.Replace";
67constexpr const char* objDeleteIntf = "xyz.openbmc_project.Object.Delete";
68constexpr const char* certPropIntf = "xyz.openbmc_project.Certs.Certificate";
69constexpr const char* dbusPropIntf = "org.freedesktop.DBus.Properties";
70constexpr const char* dbusObjManagerIntf = "org.freedesktop.DBus.ObjectManager";
71constexpr const char* httpsServiceName =
Marri Devender Rao37cce912019-02-20 01:05:22 -060072 "xyz.openbmc_project.Certs.Manager.Server.Https";
Patrick Williams89492a12023-05-10 07:51:34 -050073constexpr const char* ldapServiceName =
Marri Devender Rao37cce912019-02-20 01:05:22 -060074 "xyz.openbmc_project.Certs.Manager.Client.Ldap";
Patrick Williams89492a12023-05-10 07:51:34 -050075constexpr const char* authorityServiceName =
Michal Orzelb2254cc2023-07-27 14:08:32 +020076 "xyz.openbmc_project.Certs.Manager.Authority.Truststore";
Patrick Williams89492a12023-05-10 07:51:34 -050077constexpr const char* baseObjectPath = "/xyz/openbmc_project/certs";
78constexpr const char* httpsObjectPath =
Jiaqing Zhaoc6a8dfb2022-06-03 10:44:23 +080079 "/xyz/openbmc_project/certs/server/https";
Patrick Williams89492a12023-05-10 07:51:34 -050080constexpr const char* ldapObjectPath = "/xyz/openbmc_project/certs/client/ldap";
81constexpr const char* authorityObjectPath =
Michal Orzelb2254cc2023-07-27 14:08:32 +020082 "/xyz/openbmc_project/certs/authority/truststore";
Marri Devender Rao5968cae2019-01-21 10:27:12 -060083} // namespace certs
84
85/**
86 * The Certificate schema defines a Certificate Service which represents the
87 * actions available to manage certificates and links to where certificates
88 * are installed.
89 */
Marri Devender Rao5968cae2019-01-21 10:27:12 -060090
zhanghch058d1b46d2021-04-01 11:18:24 +080091inline std::string getCertificateFromReqBody(
92 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
93 const crow::Request& req)
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020094{
Ed Tanous1aa0c2b2022-02-08 12:24:30 +010095 nlohmann::json reqJson;
96 JsonParseResult ret = parseRequestAsJson(req, reqJson);
97 if (ret != JsonParseResult::Success)
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020098 {
99 // We did not receive JSON request, proceed as it is RAW data
Ed Tanous33c6b582023-02-14 15:05:48 -0800100 return req.body();
Kowalski, Kamil58eb2382019-08-12 11:54:31 +0200101 }
102
103 std::string certificate;
104 std::optional<std::string> certificateType = "PEM";
105
Myung Baeafc474a2024-10-09 00:53:29 -0700106 if (!json_util::readJsonPatch( //
107 req, asyncResp->res, //
108 "CertificateString", certificate, //
109 "CertificateType", certificateType //
110 ))
Kowalski, Kamil58eb2382019-08-12 11:54:31 +0200111 {
Ed Tanous62598e32023-07-17 17:06:25 -0700112 BMCWEB_LOG_ERROR("Required parameters are missing");
Kowalski, Kamil58eb2382019-08-12 11:54:31 +0200113 messages::internalError(asyncResp->res);
Ed Tanousabb93cd2021-09-02 14:34:57 -0700114 return {};
Kowalski, Kamil58eb2382019-08-12 11:54:31 +0200115 }
116
117 if (*certificateType != "PEM")
118 {
119 messages::propertyValueNotInList(asyncResp->res, *certificateType,
120 "CertificateType");
Ed Tanousabb93cd2021-09-02 14:34:57 -0700121 return {};
Kowalski, Kamil58eb2382019-08-12 11:54:31 +0200122 }
123
124 return certificate;
125}
126
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600127/**
128 * Class to create a temporary certificate file for uploading to system
129 */
130class CertificateFile
131{
132 public:
133 CertificateFile() = delete;
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500134 CertificateFile(const CertificateFile&) = delete;
135 CertificateFile& operator=(const CertificateFile&) = delete;
136 CertificateFile(CertificateFile&&) = delete;
137 CertificateFile& operator=(CertificateFile&&) = delete;
Ed Tanous4e23a442022-06-06 09:57:26 -0700138 explicit CertificateFile(const std::string& certString)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600139 {
Ed Tanous72d52d22020-10-12 07:46:27 -0700140 std::array<char, 18> dirTemplate = {'/', 't', 'm', 'p', '/', 'C',
Ed Tanous52074382020-09-28 19:16:18 -0700141 'e', 'r', 't', 's', '.', 'X',
142 'X', 'X', 'X', 'X', 'X', '\0'};
143 char* tempDirectory = mkdtemp(dirTemplate.data());
Ed Tanouse662eae2022-01-25 10:39:19 -0800144 if (tempDirectory != nullptr)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600145 {
146 certDirectory = tempDirectory;
147 certificateFile = certDirectory / "cert.pem";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400148 std::ofstream out(certificateFile,
149 std::ofstream::out | std::ofstream::binary |
150 std::ofstream::trunc);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600151 out << certString;
152 out.close();
Ed Tanous62598e32023-07-17 17:06:25 -0700153 BMCWEB_LOG_DEBUG("Creating certificate file{}",
154 certificateFile.string());
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600155 }
156 }
157 ~CertificateFile()
158 {
159 if (std::filesystem::exists(certDirectory))
160 {
Ed Tanous62598e32023-07-17 17:06:25 -0700161 BMCWEB_LOG_DEBUG("Removing certificate file{}",
162 certificateFile.string());
Ed Tanous23a21a12020-07-25 04:45:05 +0000163 std::error_code ec;
164 std::filesystem::remove_all(certDirectory, ec);
165 if (ec)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600166 {
Ed Tanous62598e32023-07-17 17:06:25 -0700167 BMCWEB_LOG_ERROR("Failed to remove temp directory{}",
168 certDirectory.string());
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600169 }
170 }
171 }
172 std::string getCertFilePath()
173 {
174 return certificateFile;
175 }
176
177 private:
178 std::filesystem::path certificateFile;
179 std::filesystem::path certDirectory;
180};
181
182/**
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500183 * @brief Parse and update Certificate Issue/Subject property
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600184 *
185 * @param[in] asyncResp Shared pointer to the response message
186 * @param[in] str Issuer/Subject value in key=value pairs
187 * @param[in] type Issuer/Subject
188 * @return None
189 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700190inline void updateCertIssuerOrSubject(nlohmann::json& out,
Ed Tanous26ccae32023-02-16 10:28:44 -0800191 std::string_view value)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600192{
193 // example: O=openbmc-project.xyz,CN=localhost
194 std::string_view::iterator i = value.begin();
195 while (i != value.end())
196 {
197 std::string_view::iterator tokenBegin = i;
198 while (i != value.end() && *i != '=')
199 {
Patrick Williams6da47ba2023-05-11 11:53:56 -0500200 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600201 }
202 if (i == value.end())
203 {
204 break;
205 }
Ed Tanous26ccae32023-02-16 10:28:44 -0800206 std::string_view key(tokenBegin, static_cast<size_t>(i - tokenBegin));
Patrick Williams6da47ba2023-05-11 11:53:56 -0500207 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600208 tokenBegin = i;
209 while (i != value.end() && *i != ',')
210 {
Patrick Williams6da47ba2023-05-11 11:53:56 -0500211 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600212 }
Ed Tanous26ccae32023-02-16 10:28:44 -0800213 std::string_view val(tokenBegin, static_cast<size_t>(i - tokenBegin));
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600214 if (key == "L")
215 {
216 out["City"] = val;
217 }
218 else if (key == "CN")
219 {
220 out["CommonName"] = val;
221 }
222 else if (key == "C")
223 {
224 out["Country"] = val;
225 }
226 else if (key == "O")
227 {
228 out["Organization"] = val;
229 }
230 else if (key == "OU")
231 {
232 out["OrganizationalUnit"] = val;
233 }
234 else if (key == "ST")
235 {
236 out["State"] = val;
237 }
238 // skip comma character
239 if (i != value.end())
240 {
Patrick Williams6da47ba2023-05-11 11:53:56 -0500241 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600242 }
243 }
244}
245
246/**
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800247 * @brief Retrieve the installed certificate list
248 *
249 * @param[in] asyncResp Shared pointer to the response message
250 * @param[in] basePath DBus object path to search
251 * @param[in] listPtr Json pointer to the list in asyncResp
252 * @param[in] countPtr Json pointer to the count in asyncResp
253 * @return None
254 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700255inline void getCertificateList(
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400256 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
257 const std::string& basePath, const nlohmann::json::json_pointer& listPtr,
258 const nlohmann::json::json_pointer& countPtr)
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800259{
George Liu7a1dbc42022-12-07 16:03:22 +0800260 constexpr std::array<std::string_view, 1> interfaces = {
261 certs::certPropIntf};
262 dbus::utility::getSubTreePaths(
263 basePath, 0, interfaces,
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800264 [asyncResp, listPtr, countPtr](
George Liu7a1dbc42022-12-07 16:03:22 +0800265 const boost::system::error_code& ec,
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800266 const dbus::utility::MapperGetSubTreePathsResponse& certPaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400267 if (ec)
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800268 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400269 BMCWEB_LOG_ERROR("Certificate collection query failed: {}", ec);
270 messages::internalError(asyncResp->res);
271 return;
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800272 }
273
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400274 nlohmann::json& links = asyncResp->res.jsonValue[listPtr];
275 links = nlohmann::json::array();
276 for (const auto& certPath : certPaths)
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800277 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400278 sdbusplus::message::object_path objPath(certPath);
279 std::string certId = objPath.filename();
280 if (certId.empty())
281 {
282 BMCWEB_LOG_ERROR("Invalid certificate objPath {}",
283 certPath);
284 continue;
285 }
286
287 boost::urls::url certURL;
288 if (objPath.parent_path() == certs::httpsObjectPath)
289 {
290 certURL = boost::urls::format(
291 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
292 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
293 }
294 else if (objPath.parent_path() == certs::ldapObjectPath)
295 {
296 certURL = boost::urls::format(
297 "/redfish/v1/AccountService/LDAP/Certificates/{}",
298 certId);
299 }
300 else if (objPath.parent_path() == certs::authorityObjectPath)
301 {
302 certURL = boost::urls::format(
303 "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
304 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
305 }
306 else
307 {
308 continue;
309 }
310
311 nlohmann::json::object_t link;
312 link["@odata.id"] = certURL;
313 links.emplace_back(std::move(link));
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800314 }
315
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400316 asyncResp->res.jsonValue[countPtr] = links.size();
317 });
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800318}
319
320/**
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600321 * @brief Retrieve the certificates properties and append to the response
322 * message
323 *
324 * @param[in] asyncResp Shared pointer to the response message
325 * @param[in] objectPath Path of the D-Bus service object
326 * @param[in] certId Id of the certificate
327 * @param[in] certURL URL of the certificate object
328 * @param[in] name name of the certificate
329 * @return None
330 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700331inline void getCertificateProperties(
zhanghch058d1b46d2021-04-01 11:18:24 +0800332 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhaoe19e97e2022-06-06 19:43:39 +0800333 const std::string& objectPath, const std::string& service,
Jiaqing Zhao1e312592022-06-14 12:58:09 +0800334 const std::string& certId, const boost::urls::url& certURL,
Jiaqing Zhaoe19e97e2022-06-06 19:43:39 +0800335 const std::string& name)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600336{
Ed Tanous62598e32023-07-17 17:06:25 -0700337 BMCWEB_LOG_DEBUG("getCertificateProperties Path={} certId={} certURl={}",
338 objectPath, certId, certURL);
Ed Tanousdeae6a72024-11-11 21:58:57 -0800339 dbus::utility::getAllProperties(
340 service, objectPath, certs::certPropIntf,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800341 [asyncResp, certURL, certId,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800342 name](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800343 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400344 if (ec)
345 {
346 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
347 messages::resourceNotFound(asyncResp->res, "Certificate",
348 certId);
349 return;
350 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200351
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400352 const std::string* certificateString = nullptr;
353 const std::vector<std::string>* keyUsage = nullptr;
354 const std::string* issuer = nullptr;
355 const std::string* subject = nullptr;
356 const uint64_t* validNotAfter = nullptr;
357 const uint64_t* validNotBefore = nullptr;
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200358
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400359 const bool success = sdbusplus::unpackPropertiesNoThrow(
360 dbus_utils::UnpackErrorPrinter(), properties,
361 "CertificateString", certificateString, "KeyUsage", keyUsage,
362 "Issuer", issuer, "Subject", subject, "ValidNotAfter",
363 validNotAfter, "ValidNotBefore", validNotBefore);
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200364
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400365 if (!success)
366 {
367 messages::internalError(asyncResp->res);
368 return;
369 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200370
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400371 asyncResp->res.jsonValue["@odata.id"] = certURL;
372 asyncResp->res.jsonValue["@odata.type"] =
373 "#Certificate.v1_0_0.Certificate";
374 asyncResp->res.jsonValue["Id"] = certId;
375 asyncResp->res.jsonValue["Name"] = name;
376 asyncResp->res.jsonValue["Description"] = name;
377 asyncResp->res.jsonValue["CertificateString"] = "";
378 asyncResp->res.jsonValue["KeyUsage"] = nlohmann::json::array();
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200379
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400380 if (certificateString != nullptr)
381 {
382 asyncResp->res.jsonValue["CertificateString"] =
383 *certificateString;
384 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200385
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400386 if (keyUsage != nullptr)
387 {
388 asyncResp->res.jsonValue["KeyUsage"] = *keyUsage;
389 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200390
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400391 if (issuer != nullptr)
392 {
393 updateCertIssuerOrSubject(asyncResp->res.jsonValue["Issuer"],
394 *issuer);
395 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200396
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400397 if (subject != nullptr)
398 {
399 updateCertIssuerOrSubject(asyncResp->res.jsonValue["Subject"],
400 *subject);
401 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200402
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400403 if (validNotAfter != nullptr)
404 {
405 asyncResp->res.jsonValue["ValidNotAfter"] =
406 redfish::time_utils::getDateTimeUint(*validNotAfter);
407 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200408
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400409 if (validNotBefore != nullptr)
410 {
411 asyncResp->res.jsonValue["ValidNotBefore"] =
412 redfish::time_utils::getDateTimeUint(*validNotBefore);
413 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200414
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400415 asyncResp->res.addHeader(
416 boost::beast::http::field::location,
417 std::string_view(certURL.data(), certURL.size()));
418 });
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600419}
420
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700421inline void
Jiaqing Zhao7a3a8f72022-09-29 15:15:58 +0800422 deleteCertificate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
423 const std::string& service,
424 const sdbusplus::message::object_path& objectPath)
425{
426 crow::connections::systemBus->async_method_call(
427 [asyncResp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800428 id{objectPath.filename()}](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400429 if (ec)
430 {
431 messages::resourceNotFound(asyncResp->res, "Certificate", id);
432 return;
433 }
434 BMCWEB_LOG_INFO("Certificate deleted");
435 asyncResp->res.result(boost::beast::http::status::no_content);
436 },
Jiaqing Zhao7a3a8f72022-09-29 15:15:58 +0800437 service, objectPath, certs::objDeleteIntf, "Delete");
438}
439
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800440inline void handleCertificateServiceGet(
441 App& app, const crow::Request& req,
442 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600443{
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800444 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
445 {
446 return;
447 }
448
Ninad Palsule3e72c202023-03-27 17:19:55 -0500449 if (req.session == nullptr)
450 {
451 messages::internalError(asyncResp->res);
452 return;
453 }
454
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800455 asyncResp->res.jsonValue["@odata.type"] =
456 "#CertificateService.v1_0_0.CertificateService";
457 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/CertificateService";
458 asyncResp->res.jsonValue["Id"] = "CertificateService";
459 asyncResp->res.jsonValue["Name"] = "Certificate Service";
460 asyncResp->res.jsonValue["Description"] =
461 "Actions available to manage certificates";
462 // /redfish/v1/CertificateService/CertificateLocations is something
463 // only ConfigureManager can access then only display when the user
464 // has permissions ConfigureManager
465 Privileges effectiveUserPrivileges =
Ninad Palsule3e72c202023-03-27 17:19:55 -0500466 redfish::getUserPrivileges(*req.session);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800467 if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
468 effectiveUserPrivileges))
469 {
470 asyncResp->res.jsonValue["CertificateLocations"]["@odata.id"] =
471 "/redfish/v1/CertificateService/CertificateLocations";
472 }
473 nlohmann::json& actions = asyncResp->res.jsonValue["Actions"];
474 nlohmann::json& replace = actions["#CertificateService.ReplaceCertificate"];
475 replace["target"] =
476 "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate";
477 nlohmann::json::array_t allowed;
Patrick Williamsad539542023-05-12 10:10:08 -0500478 allowed.emplace_back("PEM");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800479 replace["CertificateType@Redfish.AllowableValues"] = std::move(allowed);
480 actions["#CertificateService.GenerateCSR"]["target"] =
481 "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR";
482}
483
484inline void handleCertificateLocationsGet(
485 App& app, const crow::Request& req,
486 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
487{
488 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
489 {
490 return;
491 }
492 asyncResp->res.jsonValue["@odata.id"] =
493 "/redfish/v1/CertificateService/CertificateLocations";
494 asyncResp->res.jsonValue["@odata.type"] =
495 "#CertificateLocations.v1_0_0.CertificateLocations";
496 asyncResp->res.jsonValue["Name"] = "Certificate Locations";
497 asyncResp->res.jsonValue["Id"] = "CertificateLocations";
498 asyncResp->res.jsonValue["Description"] =
499 "Defines a resource that an administrator can use in order to "
500 "locate all certificates installed on a given service";
501
502 getCertificateList(asyncResp, certs::baseObjectPath,
503 "/Links/Certificates"_json_pointer,
504 "/Links/Certificates@odata.count"_json_pointer);
505}
506
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530507inline void handleError(const std::string_view dbusErrorName,
508 const std::string& id, const std::string& certificate,
509 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
510{
511 if (dbusErrorName == "org.freedesktop.DBus.Error.UnknownObject")
512 {
513 messages::resourceNotFound(asyncResp->res, "Certificate", id);
514 }
515 else if (dbusErrorName ==
516 "xyz.openbmc_project.Certs.Error.InvalidCertificate")
517 {
518 messages::propertyValueIncorrect(asyncResp->res, "Certificate",
519 certificate);
520 }
521 else
522 {
523 messages::internalError(asyncResp->res);
524 }
525}
526
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800527inline void handleReplaceCertificateAction(
528 App& app, const crow::Request& req,
529 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
530{
531 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
532 {
533 return;
534 }
535 std::string certificate;
Ed Tanous7a31e332024-03-06 12:17:43 -0800536 std::string certURI;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800537 std::optional<std::string> certificateType = "PEM";
538
Myung Baeafc474a2024-10-09 00:53:29 -0700539 if (!json_util::readJsonAction( //
540 req, asyncResp->res, //
541 "CertificateString", certificate, //
542 "CertificateType", certificateType, //
543 "CertificateUri/@odata.id", certURI //
544 ))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800545 {
Ed Tanous62598e32023-07-17 17:06:25 -0700546 BMCWEB_LOG_ERROR("Required parameters are missing");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800547 return;
548 }
549
550 if (!certificateType)
551 {
552 // should never happen, but it never hurts to be paranoid.
553 return;
554 }
555 if (certificateType != "PEM")
556 {
557 messages::actionParameterNotSupported(asyncResp->res, "CertificateType",
558 "ReplaceCertificate");
559 return;
560 }
561
Ed Tanous62598e32023-07-17 17:06:25 -0700562 BMCWEB_LOG_INFO("Certificate URI to replace: {}", certURI);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800563
Ed Tanous6fd29552023-10-04 09:40:14 -0700564 boost::system::result<boost::urls::url> parsedUrl =
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800565 boost::urls::parse_relative_ref(certURI);
566 if (!parsedUrl)
567 {
568 messages::actionParameterValueFormatError(
569 asyncResp->res, certURI, "CertificateUri", "ReplaceCertificate");
570 return;
571 }
572
573 std::string id;
574 sdbusplus::message::object_path objectPath;
575 std::string name;
576 std::string service;
577 if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1", "Managers",
578 "bmc", "NetworkProtocol", "HTTPS",
579 "Certificates", std::ref(id)))
580 {
Patrick Williams89492a12023-05-10 07:51:34 -0500581 objectPath = sdbusplus::message::object_path(certs::httpsObjectPath) /
582 id;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800583 name = "HTTPS certificate";
584 service = certs::httpsServiceName;
585 }
586 else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
587 "AccountService", "LDAP",
588 "Certificates", std::ref(id)))
589 {
Patrick Williams89492a12023-05-10 07:51:34 -0500590 objectPath = sdbusplus::message::object_path(certs::ldapObjectPath) /
591 id;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800592 name = "LDAP certificate";
593 service = certs::ldapServiceName;
594 }
595 else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
596 "Managers", "bmc", "Truststore",
597 "Certificates", std::ref(id)))
598 {
599 objectPath =
600 sdbusplus::message::object_path(certs::authorityObjectPath) / id;
601 name = "TrustStore certificate";
602 service = certs::authorityServiceName;
603 }
604 else
605 {
606 messages::actionParameterNotSupported(asyncResp->res, "CertificateUri",
607 "ReplaceCertificate");
608 return;
609 }
610
611 std::shared_ptr<CertificateFile> certFile =
612 std::make_shared<CertificateFile>(certificate);
613 crow::connections::systemBus->async_method_call(
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530614 [asyncResp, certFile, objectPath, service, url{*parsedUrl}, id, name,
615 certificate](const boost::system::error_code& ec,
Patrick Williamsd3e08592024-09-27 02:39:55 -0400616 sdbusplus::message_t& m) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400617 if (ec)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800618 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400619 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530620 const sd_bus_error* dbusError = m.get_error();
621 if ((dbusError != nullptr) && (dbusError->name != nullptr))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400622 {
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530623 handleError(dbusError->name, id, certificate, asyncResp);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400624 }
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530625 else
626 {
627 messages::internalError(asyncResp->res);
628 }
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800629 return;
630 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400631 getCertificateProperties(asyncResp, objectPath, service, id, url,
632 name);
633 BMCWEB_LOG_DEBUG("HTTPS certificate install file={}",
634 certFile->getCertFilePath());
635 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800636 service, objectPath, certs::certReplaceIntf, "Replace",
637 certFile->getCertFilePath());
638}
639
Ed Tanouscf9e4172022-12-21 09:30:16 -0800640// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800641static std::unique_ptr<sdbusplus::bus::match_t> csrMatcher;
642/**
643 * @brief Read data from CSR D-bus object and set to response
644 *
645 * @param[in] asyncResp Shared pointer to the response message
Ed Tanous8ece0e42024-01-02 13:16:50 -0800646 * @param[in] certURI Link to certificate collection URI
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800647 * @param[in] service D-Bus service name
648 * @param[in] certObjPath certificate D-Bus object path
649 * @param[in] csrObjPath CSR D-Bus object path
650 * @return None
651 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700652inline void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800653 const std::string& certURI, const std::string& service,
654 const std::string& certObjPath,
655 const std::string& csrObjPath)
656{
Ed Tanous62598e32023-07-17 17:06:25 -0700657 BMCWEB_LOG_DEBUG("getCSR CertObjectPath{} CSRObjectPath={} service={}",
658 certObjPath, csrObjPath, service);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800659 crow::connections::systemBus->async_method_call(
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400660 [asyncResp,
661 certURI](const boost::system::error_code& ec, const std::string& csr) {
662 if (ec)
663 {
664 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
665 messages::internalError(asyncResp->res);
666 return;
667 }
668 if (csr.empty())
669 {
670 BMCWEB_LOG_ERROR("CSR read is empty");
671 messages::internalError(asyncResp->res);
672 return;
673 }
674 asyncResp->res.jsonValue["CSRString"] = csr;
675 asyncResp->res.jsonValue["CertificateCollection"]["@odata.id"] =
676 certURI;
677 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800678 service, csrObjPath, "xyz.openbmc_project.Certs.CSR", "CSR");
679}
680
681inline void
682 handleGenerateCSRAction(App& app, const crow::Request& req,
683 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
684{
685 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
686 {
687 return;
688 }
689 static const int rsaKeyBitLength = 2048;
690
691 // Required parameters
692 std::string city;
693 std::string commonName;
694 std::string country;
695 std::string organization;
696 std::string organizationalUnit;
697 std::string state;
Ed Tanous7a31e332024-03-06 12:17:43 -0800698 std::string certURI;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800699
700 // Optional parameters
701 std::optional<std::vector<std::string>> optAlternativeNames =
702 std::vector<std::string>();
703 std::optional<std::string> optContactPerson = "";
704 std::optional<std::string> optChallengePassword = "";
705 std::optional<std::string> optEmail = "";
706 std::optional<std::string> optGivenName = "";
707 std::optional<std::string> optInitials = "";
708 std::optional<int64_t> optKeyBitLength = rsaKeyBitLength;
709 std::optional<std::string> optKeyCurveId = "secp384r1";
710 std::optional<std::string> optKeyPairAlgorithm = "EC";
711 std::optional<std::vector<std::string>> optKeyUsage =
712 std::vector<std::string>();
713 std::optional<std::string> optSurname = "";
714 std::optional<std::string> optUnstructuredName = "";
Myung Baeafc474a2024-10-09 00:53:29 -0700715 if (!json_util::readJsonAction( //
716 req, asyncResp->res, //
717 "AlternativeNames", optAlternativeNames, //
718 "CertificateCollection/@odata.id", certURI, //
719 "ChallengePassword", optChallengePassword, //
720 "City", city, //
721 "CommonName", commonName, //
722 "ContactPerson", optContactPerson, //
723 "Country", country, //
724 "Email", optEmail, //
725 "GivenName", optGivenName, //
726 "Initials", optInitials, //
727 "KeyBitLength", optKeyBitLength, //
728 "KeyCurveId", optKeyCurveId, //
729 "KeyPairAlgorithm", optKeyPairAlgorithm, //
730 "KeyUsage", optKeyUsage, //
731 "Organization", organization, //
732 "OrganizationalUnit", organizationalUnit, //
733 "State", state, //
734 "Surname", optSurname, //
735 "UnstructuredName", optUnstructuredName //
736 ))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800737 {
738 return;
739 }
740
741 // bmcweb has no way to store or decode a private key challenge
742 // password, which will likely cause bmcweb to crash on startup
743 // if this is not set on a post so not allowing the user to set
744 // value
745 if (!optChallengePassword->empty())
746 {
747 messages::actionParameterNotSupported(asyncResp->res, "GenerateCSR",
748 "ChallengePassword");
749 return;
750 }
751
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800752 std::string objectPath;
753 std::string service;
Ed Tanous253f11b2024-05-16 09:38:31 -0700754 if (certURI.starts_with(std::format(
755 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates",
756 BMCWEB_REDFISH_MANAGER_URI_NAME)))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800757 {
758 objectPath = certs::httpsObjectPath;
759 service = certs::httpsServiceName;
760 }
761 else if (certURI.starts_with(
762 "/redfish/v1/AccountService/LDAP/Certificates"))
763 {
764 objectPath = certs::ldapObjectPath;
765 service = certs::ldapServiceName;
766 }
767 else
768 {
769 messages::actionParameterNotSupported(
770 asyncResp->res, "CertificateCollection", "GenerateCSR");
771 return;
772 }
773
774 // supporting only EC and RSA algorithm
775 if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
776 {
777 messages::actionParameterNotSupported(
778 asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
779 return;
780 }
781
782 // supporting only 2048 key bit length for RSA algorithm due to
783 // time consumed in generating private key
784 if (*optKeyPairAlgorithm == "RSA" && *optKeyBitLength != rsaKeyBitLength)
785 {
Ed Tanouse2616cc2022-06-27 12:45:55 -0700786 messages::propertyValueNotInList(asyncResp->res, *optKeyBitLength,
787 "KeyBitLength");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800788 return;
789 }
790
791 // validate KeyUsage supporting only 1 type based on URL
Ed Tanous253f11b2024-05-16 09:38:31 -0700792 if (certURI.starts_with(std::format(
793 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates",
794 BMCWEB_REDFISH_MANAGER_URI_NAME)))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800795 {
796 if (optKeyUsage->empty())
797 {
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500798 optKeyUsage->emplace_back("ServerAuthentication");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800799 }
800 else if (optKeyUsage->size() == 1)
801 {
802 if ((*optKeyUsage)[0] != "ServerAuthentication")
803 {
804 messages::propertyValueNotInList(asyncResp->res,
805 (*optKeyUsage)[0], "KeyUsage");
806 return;
807 }
808 }
809 else
810 {
811 messages::actionParameterNotSupported(asyncResp->res, "KeyUsage",
812 "GenerateCSR");
813 return;
814 }
815 }
816 else if (certURI.starts_with(
817 "/redfish/v1/AccountService/LDAP/Certificates"))
818 {
819 if (optKeyUsage->empty())
820 {
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500821 optKeyUsage->emplace_back("ClientAuthentication");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800822 }
823 else if (optKeyUsage->size() == 1)
824 {
825 if ((*optKeyUsage)[0] != "ClientAuthentication")
826 {
827 messages::propertyValueNotInList(asyncResp->res,
828 (*optKeyUsage)[0], "KeyUsage");
829 return;
830 }
831 }
832 else
833 {
834 messages::actionParameterNotSupported(asyncResp->res, "KeyUsage",
835 "GenerateCSR");
836 return;
837 }
838 }
839
840 // Only allow one CSR matcher at a time so setting retry
841 // time-out and timer expiry to 10 seconds for now.
842 static const int timeOut = 10;
843 if (csrMatcher)
844 {
845 messages::serviceTemporarilyUnavailable(asyncResp->res,
846 std::to_string(timeOut));
847 return;
848 }
849
Ed Tanous8e8245d2024-04-11 22:21:38 -0700850 if (req.ioService == nullptr)
851 {
852 messages::internalError(asyncResp->res);
853 return;
854 }
855
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800856 // Make this static so it survives outside this method
857 static boost::asio::steady_timer timeout(*req.ioService);
858 timeout.expires_after(std::chrono::seconds(timeOut));
859 timeout.async_wait([asyncResp](const boost::system::error_code& ec) {
860 csrMatcher = nullptr;
861 if (ec)
862 {
863 // operation_aborted is expected if timer is canceled
864 // before completion.
865 if (ec != boost::asio::error::operation_aborted)
866 {
Ed Tanous62598e32023-07-17 17:06:25 -0700867 BMCWEB_LOG_ERROR("Async_wait failed {}", ec);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800868 }
869 return;
870 }
Ed Tanous62598e32023-07-17 17:06:25 -0700871 BMCWEB_LOG_ERROR("Timed out waiting for Generating CSR");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800872 messages::internalError(asyncResp->res);
873 });
874
875 // create a matcher to wait on CSR object
Ed Tanous62598e32023-07-17 17:06:25 -0700876 BMCWEB_LOG_DEBUG("create matcher with path {}", objectPath);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800877 std::string match("type='signal',"
878 "interface='org.freedesktop.DBus.ObjectManager',"
879 "path='" +
880 objectPath +
881 "',"
882 "member='InterfacesAdded'");
883 csrMatcher = std::make_unique<sdbusplus::bus::match_t>(
884 *crow::connections::systemBus, match,
885 [asyncResp, service, objectPath, certURI](sdbusplus::message_t& m) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400886 timeout.cancel();
887 if (m.is_method_error())
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800888 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400889 BMCWEB_LOG_ERROR("Dbus method error!!!");
890 messages::internalError(asyncResp->res);
891 return;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800892 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400893
894 dbus::utility::DBusInterfacesMap interfacesProperties;
895
896 sdbusplus::message::object_path csrObjectPath;
897 m.read(csrObjectPath, interfacesProperties);
898 BMCWEB_LOG_DEBUG("CSR object added{}", csrObjectPath.str);
899 for (const auto& interface : interfacesProperties)
900 {
901 if (interface.first == "xyz.openbmc_project.Certs.CSR")
902 {
903 getCSR(asyncResp, certURI, service, objectPath,
904 csrObjectPath.str);
905 break;
906 }
907 }
908 });
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800909 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800910 [asyncResp](const boost::system::error_code& ec, const std::string&) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400911 if (ec)
912 {
913 BMCWEB_LOG_ERROR("DBUS response error: {}", ec.message());
914 messages::internalError(asyncResp->res);
915 return;
916 }
917 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800918 service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
919 "GenerateCSR", *optAlternativeNames, *optChallengePassword, city,
920 commonName, *optContactPerson, country, *optEmail, *optGivenName,
921 *optInitials, *optKeyBitLength, *optKeyCurveId, *optKeyPairAlgorithm,
922 *optKeyUsage, organization, organizationalUnit, state, *optSurname,
923 *optUnstructuredName);
924}
925
926inline void requestRoutesCertificateService(App& app)
927{
928 BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/")
929 .privileges(redfish::privileges::getCertificateService)
930 .methods(boost::beast::http::verb::get)(
931 std::bind_front(handleCertificateServiceGet, std::ref(app)));
932
933 BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/CertificateLocations/")
934 .privileges(redfish::privileges::getCertificateLocations)
935 .methods(boost::beast::http::verb::get)(
936 std::bind_front(handleCertificateLocationsGet, std::ref(app)));
937
George Liu0fda0f12021-11-16 10:06:17 +0800938 BMCWEB_ROUTE(
939 app,
940 "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate/")
Ed Tanoused398212021-06-09 17:05:54 -0700941 .privileges(redfish::privileges::postCertificateService)
Ed Tanous002d39b2022-05-31 08:59:27 -0700942 .methods(boost::beast::http::verb::post)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800943 std::bind_front(handleReplaceCertificateAction, std::ref(app)));
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600944
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800945 BMCWEB_ROUTE(
946 app,
947 "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR/")
948 .privileges(redfish::privileges::postCertificateService)
949 .methods(boost::beast::http::verb::post)(
950 std::bind_front(handleGenerateCSRAction, std::ref(app)));
951} // requestRoutesCertificateService
952
953inline void handleHTTPSCertificateCollectionGet(
954 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -0700955 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
956 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800957{
958 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
959 {
960 return;
961 }
962
Ed Tanous253f11b2024-05-16 09:38:31 -0700963 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
964 {
965 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
966 return;
967 }
968
969 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
970 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates",
971 BMCWEB_REDFISH_MANAGER_URI_NAME);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800972 asyncResp->res.jsonValue["@odata.type"] =
973 "#CertificateCollection.CertificateCollection";
974 asyncResp->res.jsonValue["Name"] = "HTTPS Certificates Collection";
975 asyncResp->res.jsonValue["Description"] =
976 "A Collection of HTTPS certificate instances";
977
978 getCertificateList(asyncResp, certs::httpsObjectPath,
979 "/Members"_json_pointer,
980 "/Members@odata.count"_json_pointer);
981}
982
983inline void handleHTTPSCertificateCollectionPost(
984 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -0700985 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
986 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800987{
988 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
989 {
990 return;
991 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700992
993 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
994 {
995 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
996 return;
997 }
998
Ed Tanous62598e32023-07-17 17:06:25 -0700999 BMCWEB_LOG_DEBUG("HTTPSCertificateCollection::doPost");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001000
1001 asyncResp->res.jsonValue["Name"] = "HTTPS Certificate";
1002 asyncResp->res.jsonValue["Description"] = "HTTPS Certificate";
1003
Ed Tanousb2896142024-01-31 15:25:47 -08001004 std::string certHttpBody = getCertificateFromReqBody(asyncResp, req);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001005
Ed Tanousb2896142024-01-31 15:25:47 -08001006 if (certHttpBody.empty())
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001007 {
Ed Tanous62598e32023-07-17 17:06:25 -07001008 BMCWEB_LOG_ERROR("Cannot get certificate from request body.");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001009 messages::unrecognizedRequestBody(asyncResp->res);
1010 return;
1011 }
1012
1013 std::shared_ptr<CertificateFile> certFile =
Ed Tanousb2896142024-01-31 15:25:47 -08001014 std::make_shared<CertificateFile>(certHttpBody);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001015
1016 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001017 [asyncResp, certFile](const boost::system::error_code& ec,
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001018 const std::string& objectPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001019 if (ec)
1020 {
1021 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
1022 messages::internalError(asyncResp->res);
1023 return;
1024 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001025
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001026 sdbusplus::message::object_path path(objectPath);
1027 std::string certId = path.filename();
1028 const boost::urls::url certURL = boost::urls::format(
1029 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
1030 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
1031 getCertificateProperties(asyncResp, objectPath,
1032 certs::httpsServiceName, certId, certURL,
1033 "HTTPS Certificate");
1034 BMCWEB_LOG_DEBUG("HTTPS certificate install file={}",
1035 certFile->getCertFilePath());
1036 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001037 certs::httpsServiceName, certs::httpsObjectPath, certs::certInstallIntf,
1038 "Install", certFile->getCertFilePath());
1039}
Ed Tanous002d39b2022-05-31 08:59:27 -07001040
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001041inline void handleHTTPSCertificateGet(
1042 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001043 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1044 const std::string& managerId, const std::string& certId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001045{
1046 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1047 {
1048 return;
1049 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001050
Ed Tanous253f11b2024-05-16 09:38:31 -07001051 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1052 {
1053 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1054 return;
1055 }
1056
1057 BMCWEB_LOG_DEBUG("HTTPS Certificate ID={}", certId);
Ed Tanousef4c65b2023-04-24 15:28:50 -07001058 const boost::urls::url certURL = boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -07001059 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
1060 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001061 std::string objPath =
Ed Tanous253f11b2024-05-16 09:38:31 -07001062 sdbusplus::message::object_path(certs::httpsObjectPath) / certId;
1063 getCertificateProperties(asyncResp, objPath, certs::httpsServiceName,
1064 certId, certURL, "HTTPS Certificate");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001065}
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001066
1067inline void requestRoutesHTTPSCertificate(App& app)
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001068{
Ed Tanous253f11b2024-05-16 09:38:31 -07001069 BMCWEB_ROUTE(
1070 app, "/redfish/v1/Managers/<str>/NetworkProtocol/HTTPS/Certificates/")
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001071 .privileges(redfish::privileges::getCertificateCollection)
1072 .methods(boost::beast::http::verb::get)(std::bind_front(
1073 handleHTTPSCertificateCollectionGet, std::ref(app)));
1074
Ed Tanous253f11b2024-05-16 09:38:31 -07001075 BMCWEB_ROUTE(
1076 app, "/redfish/v1/Managers/<str>/NetworkProtocol/HTTPS/Certificates/")
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001077 .privileges(redfish::privileges::postCertificateCollection)
1078 .methods(boost::beast::http::verb::post)(std::bind_front(
1079 handleHTTPSCertificateCollectionPost, std::ref(app)));
1080
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001081 BMCWEB_ROUTE(
1082 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001083 "/redfish/v1/Managers/<str>/NetworkProtocol/HTTPS/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001084 .privileges(redfish::privileges::getCertificate)
Jiaqing Zhao1e312592022-06-14 12:58:09 +08001085 .methods(boost::beast::http::verb::get)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001086 std::bind_front(handleHTTPSCertificateGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001087}
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001088
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001089inline void handleLDAPCertificateCollectionGet(
1090 App& app, const crow::Request& req,
1091 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001092{
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001093 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1094 {
1095 return;
1096 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001097
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001098 asyncResp->res.jsonValue["@odata.id"] =
1099 "/redfish/v1/AccountService/LDAP/Certificates";
1100 asyncResp->res.jsonValue["@odata.type"] =
1101 "#CertificateCollection.CertificateCollection";
1102 asyncResp->res.jsonValue["Name"] = "LDAP Certificates Collection";
1103 asyncResp->res.jsonValue["Description"] =
1104 "A Collection of LDAP certificate instances";
Ed Tanous002d39b2022-05-31 08:59:27 -07001105
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001106 getCertificateList(asyncResp, certs::ldapObjectPath,
1107 "/Members"_json_pointer,
1108 "/Members@odata.count"_json_pointer);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001109}
Marri Devender Rao37cce912019-02-20 01:05:22 -06001110
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001111inline void handleLDAPCertificateCollectionPost(
1112 App& app, const crow::Request& req,
1113 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Marri Devender Rao37cce912019-02-20 01:05:22 -06001114{
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001115 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1116 {
1117 return;
1118 }
Ed Tanousb2896142024-01-31 15:25:47 -08001119 std::string certHttpBody = getCertificateFromReqBody(asyncResp, req);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001120
Ed Tanousb2896142024-01-31 15:25:47 -08001121 if (certHttpBody.empty())
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001122 {
Ed Tanous62598e32023-07-17 17:06:25 -07001123 BMCWEB_LOG_ERROR("Cannot get certificate from request body.");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001124 messages::unrecognizedRequestBody(asyncResp->res);
1125 return;
1126 }
1127
1128 std::shared_ptr<CertificateFile> certFile =
Ed Tanousb2896142024-01-31 15:25:47 -08001129 std::make_shared<CertificateFile>(certHttpBody);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001130
1131 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001132 [asyncResp, certFile](const boost::system::error_code& ec,
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001133 const std::string& objectPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001134 if (ec)
1135 {
1136 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
1137 messages::internalError(asyncResp->res);
1138 return;
1139 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001140
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001141 sdbusplus::message::object_path path(objectPath);
1142 std::string certId = path.filename();
1143 const boost::urls::url certURL = boost::urls::format(
1144 "/redfish/v1/AccountService/LDAP/Certificates/{}", certId);
1145 getCertificateProperties(asyncResp, objectPath,
1146 certs::ldapServiceName, certId, certURL,
1147 "LDAP Certificate");
1148 BMCWEB_LOG_DEBUG("LDAP certificate install file={}",
1149 certFile->getCertFilePath());
1150 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001151 certs::ldapServiceName, certs::ldapObjectPath, certs::certInstallIntf,
1152 "Install", certFile->getCertFilePath());
1153}
Ed Tanous002d39b2022-05-31 08:59:27 -07001154
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001155inline void handleLDAPCertificateGet(
1156 App& app, const crow::Request& req,
1157 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
1158{
1159 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1160 {
1161 return;
1162 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001163
Ed Tanous62598e32023-07-17 17:06:25 -07001164 BMCWEB_LOG_DEBUG("LDAP Certificate ID={}", id);
Ed Tanousef4c65b2023-04-24 15:28:50 -07001165 const boost::urls::url certURL = boost::urls::format(
1166 "/redfish/v1/AccountService/LDAP/Certificates/{}", id);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001167 std::string objPath =
1168 sdbusplus::message::object_path(certs::ldapObjectPath) / id;
1169 getCertificateProperties(asyncResp, objPath, certs::ldapServiceName, id,
1170 certURL, "LDAP Certificate");
1171}
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001172
Jiaqing Zhao99612242022-09-29 15:31:09 +08001173inline void handleLDAPCertificateDelete(
1174 App& app, const crow::Request& req,
1175 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
1176{
1177 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1178 {
1179 return;
1180 }
1181
Ed Tanous62598e32023-07-17 17:06:25 -07001182 BMCWEB_LOG_DEBUG("Delete LDAP Certificate ID={}", id);
Jiaqing Zhao99612242022-09-29 15:31:09 +08001183 std::string objPath =
1184 sdbusplus::message::object_path(certs::ldapObjectPath) / id;
1185
1186 deleteCertificate(asyncResp, certs::ldapServiceName, objPath);
1187}
1188
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001189inline void requestRoutesLDAPCertificate(App& app)
Marri Devender Rao37cce912019-02-20 01:05:22 -06001190{
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001191 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
1192 .privileges(redfish::privileges::getCertificateCollection)
1193 .methods(boost::beast::http::verb::get)(
1194 std::bind_front(handleLDAPCertificateCollectionGet, std::ref(app)));
1195
1196 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
1197 .privileges(redfish::privileges::postCertificateCollection)
1198 .methods(boost::beast::http::verb::post)(std::bind_front(
1199 handleLDAPCertificateCollectionPost, std::ref(app)));
1200
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001201 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001202 .privileges(redfish::privileges::getCertificate)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001203 .methods(boost::beast::http::verb::get)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001204 std::bind_front(handleLDAPCertificateGet, std::ref(app)));
Jiaqing Zhao99612242022-09-29 15:31:09 +08001205
1206 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
1207 .privileges(redfish::privileges::deleteCertificate)
1208 .methods(boost::beast::http::verb::delete_)(
1209 std::bind_front(handleLDAPCertificateDelete, std::ref(app)));
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001210} // requestRoutesLDAPCertificate
1211
1212inline void handleTrustStoreCertificateCollectionGet(
1213 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001214 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1215 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001216{
1217 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1218 {
1219 return;
1220 }
1221
Ed Tanous253f11b2024-05-16 09:38:31 -07001222 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1223 {
1224 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1225 return;
1226 }
1227
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001228 asyncResp->res.jsonValue["@odata.id"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07001229 boost::urls::format("/redfish/v1/Managers/{}/Truststore/Certificates/",
1230 BMCWEB_REDFISH_MANAGER_URI_NAME);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001231 asyncResp->res.jsonValue["@odata.type"] =
1232 "#CertificateCollection.CertificateCollection";
1233 asyncResp->res.jsonValue["Name"] = "TrustStore Certificates Collection";
1234 asyncResp->res.jsonValue["Description"] =
1235 "A Collection of TrustStore certificate instances";
1236
1237 getCertificateList(asyncResp, certs::authorityObjectPath,
1238 "/Members"_json_pointer,
1239 "/Members@odata.count"_json_pointer);
1240}
1241
1242inline void handleTrustStoreCertificateCollectionPost(
1243 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001244 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1245 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001246{
1247 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1248 {
1249 return;
1250 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001251
1252 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1253 {
1254 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1255 return;
1256 }
1257
Ed Tanousb2896142024-01-31 15:25:47 -08001258 std::string certHttpBody = getCertificateFromReqBody(asyncResp, req);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001259
Ed Tanousb2896142024-01-31 15:25:47 -08001260 if (certHttpBody.empty())
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001261 {
Ed Tanous62598e32023-07-17 17:06:25 -07001262 BMCWEB_LOG_ERROR("Cannot get certificate from request body.");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001263 messages::unrecognizedRequestBody(asyncResp->res);
1264 return;
1265 }
1266
1267 std::shared_ptr<CertificateFile> certFile =
Ed Tanousb2896142024-01-31 15:25:47 -08001268 std::make_shared<CertificateFile>(certHttpBody);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001269 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001270 [asyncResp, certFile](const boost::system::error_code& ec,
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001271 const std::string& objectPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001272 if (ec)
1273 {
1274 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
1275 messages::internalError(asyncResp->res);
1276 return;
1277 }
Jiaqing Zhao717b9802022-06-06 20:24:04 +08001278
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001279 sdbusplus::message::object_path path(objectPath);
1280 std::string certId = path.filename();
1281 const boost::urls::url certURL = boost::urls::format(
1282 "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
1283 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
1284 getCertificateProperties(asyncResp, objectPath,
1285 certs::authorityServiceName, certId,
1286 certURL, "TrustStore Certificate");
1287 BMCWEB_LOG_DEBUG("TrustStore certificate install file={}",
1288 certFile->getCertFilePath());
1289 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001290 certs::authorityServiceName, certs::authorityObjectPath,
1291 certs::certInstallIntf, "Install", certFile->getCertFilePath());
1292}
1293
1294inline void handleTrustStoreCertificateGet(
1295 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001296 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1297 const std::string& managerId, const std::string& certId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001298{
1299 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1300 {
1301 return;
1302 }
1303
Ed Tanous253f11b2024-05-16 09:38:31 -07001304 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1305 {
1306 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1307 return;
1308 }
1309
1310 BMCWEB_LOG_DEBUG("Truststore Certificate ID={}", certId);
Ed Tanousef4c65b2023-04-24 15:28:50 -07001311 const boost::urls::url certURL = boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -07001312 "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
1313 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001314 std::string objPath =
Ed Tanous253f11b2024-05-16 09:38:31 -07001315 sdbusplus::message::object_path(certs::authorityObjectPath) / certId;
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001316 getCertificateProperties(asyncResp, objPath, certs::authorityServiceName,
Ed Tanous253f11b2024-05-16 09:38:31 -07001317 certId, certURL, "TrustStore Certificate");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001318}
1319
1320inline void handleTrustStoreCertificateDelete(
1321 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001322 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1323 const std::string& managerId, const std::string& certId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001324{
1325 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1326 {
1327 return;
1328 }
1329
Ed Tanous253f11b2024-05-16 09:38:31 -07001330 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1331 {
1332 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1333 return;
1334 }
1335
1336 BMCWEB_LOG_DEBUG("Delete TrustStore Certificate ID={}", certId);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001337 std::string objPath =
Ed Tanous253f11b2024-05-16 09:38:31 -07001338 sdbusplus::message::object_path(certs::authorityObjectPath) / certId;
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001339
Jiaqing Zhao7a3a8f72022-09-29 15:15:58 +08001340 deleteCertificate(asyncResp, certs::authorityServiceName, objPath);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001341}
1342
1343inline void requestRoutesTrustStoreCertificate(App& app)
Marri Devender Raocfcd5f62019-05-17 08:34:37 -05001344{
Ed Tanous253f11b2024-05-16 09:38:31 -07001345 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/Truststore/Certificates/")
Ed Tanoused398212021-06-09 17:05:54 -07001346 .privileges(redfish::privileges::getCertificate)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001347 .methods(boost::beast::http::verb::get)(std::bind_front(
1348 handleTrustStoreCertificateCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001349
Ed Tanous253f11b2024-05-16 09:38:31 -07001350 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/Truststore/Certificates/")
Ed Tanoused398212021-06-09 17:05:54 -07001351 .privileges(redfish::privileges::postCertificateCollection)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001352 .methods(boost::beast::http::verb::post)(std::bind_front(
1353 handleTrustStoreCertificateCollectionPost, std::ref(app)));
Ed Tanous002d39b2022-05-31 08:59:27 -07001354
Ed Tanous253f11b2024-05-16 09:38:31 -07001355 BMCWEB_ROUTE(app,
1356 "/redfish/v1/Managers/<str>/Truststore/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001357 .privileges(redfish::privileges::getCertificate)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001358 .methods(boost::beast::http::verb::get)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001359 std::bind_front(handleTrustStoreCertificateGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001360
Ed Tanous253f11b2024-05-16 09:38:31 -07001361 BMCWEB_ROUTE(app,
1362 "/redfish/v1/Managers/<str>/Truststore/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001363 .privileges(redfish::privileges::deleteCertificate)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001364 .methods(boost::beast::http::verb::delete_)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001365 std::bind_front(handleTrustStoreCertificateDelete, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001366} // requestRoutesTrustStoreCertificate
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001367} // namespace redfish