blob: fdc283b5b07a3f14a57008c15bfb1a0a24d2ca8a [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#include <systemd/sd-bus.h>
25
26#include <boost/asio/error.hpp>
27#include <boost/asio/steady_timer.hpp>
28#include <boost/beast/http/field.hpp>
29#include <boost/beast/http/status.hpp>
30#include <boost/beast/http/verb.hpp>
31#include <boost/system/result.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070032#include <boost/url/format.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080033#include <boost/url/parse.hpp>
34#include <boost/url/url.hpp>
35#include <nlohmann/json.hpp>
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080036#include <sdbusplus/bus/match.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080037#include <sdbusplus/message.hpp>
38#include <sdbusplus/message/native_types.hpp>
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +020039#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050040
George Liu7a1dbc42022-12-07 16:03:22 +080041#include <array>
Ed Tanousd7857202025-01-28 15:32:26 -080042#include <chrono>
43#include <cstddef>
44#include <cstdint>
45#include <cstdlib>
46#include <filesystem>
47#include <format>
48#include <fstream>
49#include <functional>
50#include <iterator>
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080051#include <memory>
Ed Tanousd7857202025-01-28 15:32:26 -080052#include <optional>
53#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080054#include <string_view>
Ed Tanousd7857202025-01-28 15:32:26 -080055#include <system_error>
56#include <utility>
57#include <vector>
George Liu7a1dbc42022-12-07 16:03:22 +080058
Marri Devender Rao5968cae2019-01-21 10:27:12 -060059namespace redfish
60{
61namespace certs
62{
Patrick Williams89492a12023-05-10 07:51:34 -050063constexpr const char* certInstallIntf = "xyz.openbmc_project.Certs.Install";
64constexpr const char* certReplaceIntf = "xyz.openbmc_project.Certs.Replace";
65constexpr const char* objDeleteIntf = "xyz.openbmc_project.Object.Delete";
66constexpr const char* certPropIntf = "xyz.openbmc_project.Certs.Certificate";
67constexpr const char* dbusPropIntf = "org.freedesktop.DBus.Properties";
68constexpr const char* dbusObjManagerIntf = "org.freedesktop.DBus.ObjectManager";
69constexpr const char* httpsServiceName =
Marri Devender Rao37cce912019-02-20 01:05:22 -060070 "xyz.openbmc_project.Certs.Manager.Server.Https";
Patrick Williams89492a12023-05-10 07:51:34 -050071constexpr const char* ldapServiceName =
Marri Devender Rao37cce912019-02-20 01:05:22 -060072 "xyz.openbmc_project.Certs.Manager.Client.Ldap";
Patrick Williams89492a12023-05-10 07:51:34 -050073constexpr const char* authorityServiceName =
Michal Orzelb2254cc2023-07-27 14:08:32 +020074 "xyz.openbmc_project.Certs.Manager.Authority.Truststore";
Patrick Williams89492a12023-05-10 07:51:34 -050075constexpr const char* baseObjectPath = "/xyz/openbmc_project/certs";
76constexpr const char* httpsObjectPath =
Jiaqing Zhaoc6a8dfb2022-06-03 10:44:23 +080077 "/xyz/openbmc_project/certs/server/https";
Patrick Williams89492a12023-05-10 07:51:34 -050078constexpr const char* ldapObjectPath = "/xyz/openbmc_project/certs/client/ldap";
79constexpr const char* authorityObjectPath =
Michal Orzelb2254cc2023-07-27 14:08:32 +020080 "/xyz/openbmc_project/certs/authority/truststore";
Marri Devender Rao5968cae2019-01-21 10:27:12 -060081} // namespace certs
82
83/**
84 * The Certificate schema defines a Certificate Service which represents the
85 * actions available to manage certificates and links to where certificates
86 * are installed.
87 */
Marri Devender Rao5968cae2019-01-21 10:27:12 -060088
zhanghch058d1b46d2021-04-01 11:18:24 +080089inline std::string getCertificateFromReqBody(
90 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
91 const crow::Request& req)
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020092{
Ed Tanous1aa0c2b2022-02-08 12:24:30 +010093 nlohmann::json reqJson;
94 JsonParseResult ret = parseRequestAsJson(req, reqJson);
95 if (ret != JsonParseResult::Success)
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020096 {
97 // We did not receive JSON request, proceed as it is RAW data
Ed Tanous33c6b582023-02-14 15:05:48 -080098 return req.body();
Kowalski, Kamil58eb2382019-08-12 11:54:31 +020099 }
100
101 std::string certificate;
102 std::optional<std::string> certificateType = "PEM";
103
Myung Baeafc474a2024-10-09 00:53:29 -0700104 if (!json_util::readJsonPatch( //
105 req, asyncResp->res, //
106 "CertificateString", certificate, //
107 "CertificateType", certificateType //
108 ))
Kowalski, Kamil58eb2382019-08-12 11:54:31 +0200109 {
Ed Tanous62598e32023-07-17 17:06:25 -0700110 BMCWEB_LOG_ERROR("Required parameters are missing");
Kowalski, Kamil58eb2382019-08-12 11:54:31 +0200111 messages::internalError(asyncResp->res);
Ed Tanousabb93cd2021-09-02 14:34:57 -0700112 return {};
Kowalski, Kamil58eb2382019-08-12 11:54:31 +0200113 }
114
115 if (*certificateType != "PEM")
116 {
117 messages::propertyValueNotInList(asyncResp->res, *certificateType,
118 "CertificateType");
Ed Tanousabb93cd2021-09-02 14:34:57 -0700119 return {};
Kowalski, Kamil58eb2382019-08-12 11:54:31 +0200120 }
121
122 return certificate;
123}
124
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600125/**
126 * Class to create a temporary certificate file for uploading to system
127 */
128class CertificateFile
129{
130 public:
131 CertificateFile() = delete;
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500132 CertificateFile(const CertificateFile&) = delete;
133 CertificateFile& operator=(const CertificateFile&) = delete;
134 CertificateFile(CertificateFile&&) = delete;
135 CertificateFile& operator=(CertificateFile&&) = delete;
Ed Tanous4e23a442022-06-06 09:57:26 -0700136 explicit CertificateFile(const std::string& certString)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600137 {
Ed Tanous72d52d22020-10-12 07:46:27 -0700138 std::array<char, 18> dirTemplate = {'/', 't', 'm', 'p', '/', 'C',
Ed Tanous52074382020-09-28 19:16:18 -0700139 'e', 'r', 't', 's', '.', 'X',
140 'X', 'X', 'X', 'X', 'X', '\0'};
Myung Bae92e11bf2025-01-31 09:22:23 -0500141 // NOLINTNEXTLINE(misc-include-cleaner)
Ed Tanous52074382020-09-28 19:16:18 -0700142 char* tempDirectory = mkdtemp(dirTemplate.data());
Ed Tanouse662eae2022-01-25 10:39:19 -0800143 if (tempDirectory != nullptr)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600144 {
145 certDirectory = tempDirectory;
146 certificateFile = certDirectory / "cert.pem";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400147 std::ofstream out(certificateFile,
148 std::ofstream::out | std::ofstream::binary |
149 std::ofstream::trunc);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600150 out << certString;
151 out.close();
Ed Tanous62598e32023-07-17 17:06:25 -0700152 BMCWEB_LOG_DEBUG("Creating certificate file{}",
153 certificateFile.string());
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600154 }
155 }
156 ~CertificateFile()
157 {
158 if (std::filesystem::exists(certDirectory))
159 {
Ed Tanous62598e32023-07-17 17:06:25 -0700160 BMCWEB_LOG_DEBUG("Removing certificate file{}",
161 certificateFile.string());
Ed Tanous23a21a12020-07-25 04:45:05 +0000162 std::error_code ec;
163 std::filesystem::remove_all(certDirectory, ec);
164 if (ec)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600165 {
Ed Tanous62598e32023-07-17 17:06:25 -0700166 BMCWEB_LOG_ERROR("Failed to remove temp directory{}",
167 certDirectory.string());
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600168 }
169 }
170 }
171 std::string getCertFilePath()
172 {
173 return certificateFile;
174 }
175
176 private:
177 std::filesystem::path certificateFile;
178 std::filesystem::path certDirectory;
179};
180
181/**
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500182 * @brief Parse and update Certificate Issue/Subject property
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600183 *
184 * @param[in] asyncResp Shared pointer to the response message
185 * @param[in] str Issuer/Subject value in key=value pairs
186 * @param[in] type Issuer/Subject
187 * @return None
188 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700189inline void updateCertIssuerOrSubject(nlohmann::json& out,
Ed Tanous26ccae32023-02-16 10:28:44 -0800190 std::string_view value)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600191{
192 // example: O=openbmc-project.xyz,CN=localhost
193 std::string_view::iterator i = value.begin();
194 while (i != value.end())
195 {
196 std::string_view::iterator tokenBegin = i;
197 while (i != value.end() && *i != '=')
198 {
Patrick Williams6da47ba2023-05-11 11:53:56 -0500199 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600200 }
201 if (i == value.end())
202 {
203 break;
204 }
Ed Tanous26ccae32023-02-16 10:28:44 -0800205 std::string_view key(tokenBegin, static_cast<size_t>(i - tokenBegin));
Patrick Williams6da47ba2023-05-11 11:53:56 -0500206 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600207 tokenBegin = i;
208 while (i != value.end() && *i != ',')
209 {
Patrick Williams6da47ba2023-05-11 11:53:56 -0500210 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600211 }
Ed Tanous26ccae32023-02-16 10:28:44 -0800212 std::string_view val(tokenBegin, static_cast<size_t>(i - tokenBegin));
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600213 if (key == "L")
214 {
215 out["City"] = val;
216 }
217 else if (key == "CN")
218 {
219 out["CommonName"] = val;
220 }
221 else if (key == "C")
222 {
223 out["Country"] = val;
224 }
225 else if (key == "O")
226 {
227 out["Organization"] = val;
228 }
229 else if (key == "OU")
230 {
231 out["OrganizationalUnit"] = val;
232 }
233 else if (key == "ST")
234 {
235 out["State"] = val;
236 }
237 // skip comma character
238 if (i != value.end())
239 {
Patrick Williams6da47ba2023-05-11 11:53:56 -0500240 std::advance(i, 1);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600241 }
242 }
243}
244
245/**
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800246 * @brief Retrieve the installed certificate list
247 *
248 * @param[in] asyncResp Shared pointer to the response message
249 * @param[in] basePath DBus object path to search
250 * @param[in] listPtr Json pointer to the list in asyncResp
251 * @param[in] countPtr Json pointer to the count in asyncResp
252 * @return None
253 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700254inline void getCertificateList(
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400255 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
256 const std::string& basePath, const nlohmann::json::json_pointer& listPtr,
257 const nlohmann::json::json_pointer& countPtr)
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800258{
George Liu7a1dbc42022-12-07 16:03:22 +0800259 constexpr std::array<std::string_view, 1> interfaces = {
260 certs::certPropIntf};
261 dbus::utility::getSubTreePaths(
262 basePath, 0, interfaces,
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800263 [asyncResp, listPtr, countPtr](
George Liu7a1dbc42022-12-07 16:03:22 +0800264 const boost::system::error_code& ec,
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800265 const dbus::utility::MapperGetSubTreePathsResponse& certPaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400266 if (ec)
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800267 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400268 BMCWEB_LOG_ERROR("Certificate collection query failed: {}", ec);
269 messages::internalError(asyncResp->res);
270 return;
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800271 }
272
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400273 nlohmann::json& links = asyncResp->res.jsonValue[listPtr];
274 links = nlohmann::json::array();
275 for (const auto& certPath : certPaths)
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800276 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400277 sdbusplus::message::object_path objPath(certPath);
278 std::string certId = objPath.filename();
279 if (certId.empty())
280 {
281 BMCWEB_LOG_ERROR("Invalid certificate objPath {}",
282 certPath);
283 continue;
284 }
285
286 boost::urls::url certURL;
287 if (objPath.parent_path() == certs::httpsObjectPath)
288 {
289 certURL = boost::urls::format(
290 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
291 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
292 }
293 else if (objPath.parent_path() == certs::ldapObjectPath)
294 {
295 certURL = boost::urls::format(
296 "/redfish/v1/AccountService/LDAP/Certificates/{}",
297 certId);
298 }
299 else if (objPath.parent_path() == certs::authorityObjectPath)
300 {
301 certURL = boost::urls::format(
302 "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
303 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
304 }
305 else
306 {
307 continue;
308 }
309
310 nlohmann::json::object_t link;
311 link["@odata.id"] = certURL;
312 links.emplace_back(std::move(link));
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800313 }
314
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400315 asyncResp->res.jsonValue[countPtr] = links.size();
316 });
Jiaqing Zhaod3f92ce2022-06-03 11:46:12 +0800317}
318
319/**
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600320 * @brief Retrieve the certificates properties and append to the response
321 * message
322 *
323 * @param[in] asyncResp Shared pointer to the response message
324 * @param[in] objectPath Path of the D-Bus service object
325 * @param[in] certId Id of the certificate
326 * @param[in] certURL URL of the certificate object
327 * @param[in] name name of the certificate
328 * @return None
329 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700330inline void getCertificateProperties(
zhanghch058d1b46d2021-04-01 11:18:24 +0800331 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhaoe19e97e2022-06-06 19:43:39 +0800332 const std::string& objectPath, const std::string& service,
Jiaqing Zhao1e312592022-06-14 12:58:09 +0800333 const std::string& certId, const boost::urls::url& certURL,
Jiaqing Zhaoe19e97e2022-06-06 19:43:39 +0800334 const std::string& name)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600335{
Ed Tanous62598e32023-07-17 17:06:25 -0700336 BMCWEB_LOG_DEBUG("getCertificateProperties Path={} certId={} certURl={}",
337 objectPath, certId, certURL);
Ed Tanousdeae6a72024-11-11 21:58:57 -0800338 dbus::utility::getAllProperties(
339 service, objectPath, certs::certPropIntf,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800340 [asyncResp, certURL, certId,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800341 name](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800342 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400343 if (ec)
344 {
345 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
346 messages::resourceNotFound(asyncResp->res, "Certificate",
347 certId);
348 return;
349 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200350
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400351 const std::string* certificateString = nullptr;
352 const std::vector<std::string>* keyUsage = nullptr;
353 const std::string* issuer = nullptr;
354 const std::string* subject = nullptr;
355 const uint64_t* validNotAfter = nullptr;
356 const uint64_t* validNotBefore = nullptr;
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200357
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400358 const bool success = sdbusplus::unpackPropertiesNoThrow(
359 dbus_utils::UnpackErrorPrinter(), properties,
360 "CertificateString", certificateString, "KeyUsage", keyUsage,
361 "Issuer", issuer, "Subject", subject, "ValidNotAfter",
362 validNotAfter, "ValidNotBefore", validNotBefore);
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200363
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400364 if (!success)
365 {
366 messages::internalError(asyncResp->res);
367 return;
368 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200369
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400370 asyncResp->res.jsonValue["@odata.id"] = certURL;
371 asyncResp->res.jsonValue["@odata.type"] =
372 "#Certificate.v1_0_0.Certificate";
373 asyncResp->res.jsonValue["Id"] = certId;
374 asyncResp->res.jsonValue["Name"] = name;
375 asyncResp->res.jsonValue["Description"] = name;
376 asyncResp->res.jsonValue["CertificateString"] = "";
377 asyncResp->res.jsonValue["KeyUsage"] = nlohmann::json::array();
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200378
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400379 if (certificateString != nullptr)
380 {
381 asyncResp->res.jsonValue["CertificateString"] =
382 *certificateString;
383 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200384
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400385 if (keyUsage != nullptr)
386 {
387 asyncResp->res.jsonValue["KeyUsage"] = *keyUsage;
388 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200389
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400390 if (issuer != nullptr)
391 {
392 updateCertIssuerOrSubject(asyncResp->res.jsonValue["Issuer"],
393 *issuer);
394 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200395
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400396 if (subject != nullptr)
397 {
398 updateCertIssuerOrSubject(asyncResp->res.jsonValue["Subject"],
399 *subject);
400 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200401
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400402 if (validNotAfter != nullptr)
403 {
404 asyncResp->res.jsonValue["ValidNotAfter"] =
405 redfish::time_utils::getDateTimeUint(*validNotAfter);
406 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200407
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400408 if (validNotBefore != nullptr)
409 {
410 asyncResp->res.jsonValue["ValidNotBefore"] =
411 redfish::time_utils::getDateTimeUint(*validNotBefore);
412 }
Krzysztof Grobelny9b12d1f2022-08-11 09:52:56 +0200413
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400414 asyncResp->res.addHeader(
415 boost::beast::http::field::location,
416 std::string_view(certURL.data(), certURL.size()));
417 });
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600418}
419
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700420inline void
Jiaqing Zhao7a3a8f72022-09-29 15:15:58 +0800421 deleteCertificate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
422 const std::string& service,
423 const sdbusplus::message::object_path& objectPath)
424{
425 crow::connections::systemBus->async_method_call(
426 [asyncResp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800427 id{objectPath.filename()}](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400428 if (ec)
429 {
430 messages::resourceNotFound(asyncResp->res, "Certificate", id);
431 return;
432 }
433 BMCWEB_LOG_INFO("Certificate deleted");
434 asyncResp->res.result(boost::beast::http::status::no_content);
435 },
Jiaqing Zhao7a3a8f72022-09-29 15:15:58 +0800436 service, objectPath, certs::objDeleteIntf, "Delete");
437}
438
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800439inline void handleCertificateServiceGet(
440 App& app, const crow::Request& req,
441 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600442{
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800443 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
444 {
445 return;
446 }
447
Ninad Palsule3e72c202023-03-27 17:19:55 -0500448 if (req.session == nullptr)
449 {
450 messages::internalError(asyncResp->res);
451 return;
452 }
453
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800454 asyncResp->res.jsonValue["@odata.type"] =
455 "#CertificateService.v1_0_0.CertificateService";
456 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/CertificateService";
457 asyncResp->res.jsonValue["Id"] = "CertificateService";
458 asyncResp->res.jsonValue["Name"] = "Certificate Service";
459 asyncResp->res.jsonValue["Description"] =
460 "Actions available to manage certificates";
461 // /redfish/v1/CertificateService/CertificateLocations is something
462 // only ConfigureManager can access then only display when the user
463 // has permissions ConfigureManager
464 Privileges effectiveUserPrivileges =
Ninad Palsule3e72c202023-03-27 17:19:55 -0500465 redfish::getUserPrivileges(*req.session);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800466 if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
467 effectiveUserPrivileges))
468 {
469 asyncResp->res.jsonValue["CertificateLocations"]["@odata.id"] =
470 "/redfish/v1/CertificateService/CertificateLocations";
471 }
472 nlohmann::json& actions = asyncResp->res.jsonValue["Actions"];
473 nlohmann::json& replace = actions["#CertificateService.ReplaceCertificate"];
474 replace["target"] =
475 "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate";
476 nlohmann::json::array_t allowed;
Patrick Williamsad539542023-05-12 10:10:08 -0500477 allowed.emplace_back("PEM");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800478 replace["CertificateType@Redfish.AllowableValues"] = std::move(allowed);
479 actions["#CertificateService.GenerateCSR"]["target"] =
480 "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR";
481}
482
483inline void handleCertificateLocationsGet(
484 App& app, const crow::Request& req,
485 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
486{
487 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
488 {
489 return;
490 }
491 asyncResp->res.jsonValue["@odata.id"] =
492 "/redfish/v1/CertificateService/CertificateLocations";
493 asyncResp->res.jsonValue["@odata.type"] =
494 "#CertificateLocations.v1_0_0.CertificateLocations";
495 asyncResp->res.jsonValue["Name"] = "Certificate Locations";
496 asyncResp->res.jsonValue["Id"] = "CertificateLocations";
497 asyncResp->res.jsonValue["Description"] =
498 "Defines a resource that an administrator can use in order to "
499 "locate all certificates installed on a given service";
500
501 getCertificateList(asyncResp, certs::baseObjectPath,
502 "/Links/Certificates"_json_pointer,
503 "/Links/Certificates@odata.count"_json_pointer);
504}
505
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530506inline void handleError(const std::string_view dbusErrorName,
507 const std::string& id, const std::string& certificate,
508 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
509{
510 if (dbusErrorName == "org.freedesktop.DBus.Error.UnknownObject")
511 {
512 messages::resourceNotFound(asyncResp->res, "Certificate", id);
513 }
514 else if (dbusErrorName ==
515 "xyz.openbmc_project.Certs.Error.InvalidCertificate")
516 {
517 messages::propertyValueIncorrect(asyncResp->res, "Certificate",
518 certificate);
519 }
520 else
521 {
522 messages::internalError(asyncResp->res);
523 }
524}
525
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800526inline void handleReplaceCertificateAction(
527 App& app, const crow::Request& req,
528 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
529{
530 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
531 {
532 return;
533 }
534 std::string certificate;
Ed Tanous7a31e332024-03-06 12:17:43 -0800535 std::string certURI;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800536 std::optional<std::string> certificateType = "PEM";
537
Myung Baeafc474a2024-10-09 00:53:29 -0700538 if (!json_util::readJsonAction( //
539 req, asyncResp->res, //
540 "CertificateString", certificate, //
541 "CertificateType", certificateType, //
542 "CertificateUri/@odata.id", certURI //
543 ))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800544 {
Ed Tanous62598e32023-07-17 17:06:25 -0700545 BMCWEB_LOG_ERROR("Required parameters are missing");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800546 return;
547 }
548
549 if (!certificateType)
550 {
551 // should never happen, but it never hurts to be paranoid.
552 return;
553 }
554 if (certificateType != "PEM")
555 {
556 messages::actionParameterNotSupported(asyncResp->res, "CertificateType",
557 "ReplaceCertificate");
558 return;
559 }
560
Ed Tanous62598e32023-07-17 17:06:25 -0700561 BMCWEB_LOG_INFO("Certificate URI to replace: {}", certURI);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800562
Ed Tanous6fd29552023-10-04 09:40:14 -0700563 boost::system::result<boost::urls::url> parsedUrl =
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800564 boost::urls::parse_relative_ref(certURI);
565 if (!parsedUrl)
566 {
567 messages::actionParameterValueFormatError(
568 asyncResp->res, certURI, "CertificateUri", "ReplaceCertificate");
569 return;
570 }
571
572 std::string id;
573 sdbusplus::message::object_path objectPath;
574 std::string name;
575 std::string service;
576 if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1", "Managers",
577 "bmc", "NetworkProtocol", "HTTPS",
578 "Certificates", std::ref(id)))
579 {
Patrick Williams89492a12023-05-10 07:51:34 -0500580 objectPath = sdbusplus::message::object_path(certs::httpsObjectPath) /
581 id;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800582 name = "HTTPS certificate";
583 service = certs::httpsServiceName;
584 }
585 else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
586 "AccountService", "LDAP",
587 "Certificates", std::ref(id)))
588 {
Patrick Williams89492a12023-05-10 07:51:34 -0500589 objectPath = sdbusplus::message::object_path(certs::ldapObjectPath) /
590 id;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800591 name = "LDAP certificate";
592 service = certs::ldapServiceName;
593 }
594 else if (crow::utility::readUrlSegments(*parsedUrl, "redfish", "v1",
595 "Managers", "bmc", "Truststore",
596 "Certificates", std::ref(id)))
597 {
598 objectPath =
599 sdbusplus::message::object_path(certs::authorityObjectPath) / id;
600 name = "TrustStore certificate";
601 service = certs::authorityServiceName;
602 }
603 else
604 {
605 messages::actionParameterNotSupported(asyncResp->res, "CertificateUri",
606 "ReplaceCertificate");
607 return;
608 }
609
610 std::shared_ptr<CertificateFile> certFile =
611 std::make_shared<CertificateFile>(certificate);
612 crow::connections::systemBus->async_method_call(
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530613 [asyncResp, certFile, objectPath, service, url{*parsedUrl}, id, name,
614 certificate](const boost::system::error_code& ec,
Patrick Williamsd3e08592024-09-27 02:39:55 -0400615 sdbusplus::message_t& m) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400616 if (ec)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800617 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400618 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530619 const sd_bus_error* dbusError = m.get_error();
620 if ((dbusError != nullptr) && (dbusError->name != nullptr))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400621 {
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530622 handleError(dbusError->name, id, certificate, asyncResp);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400623 }
Chandra Harkude26d3b0f2024-09-23 22:02:35 +0530624 else
625 {
626 messages::internalError(asyncResp->res);
627 }
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800628 return;
629 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400630 getCertificateProperties(asyncResp, objectPath, service, id, url,
631 name);
632 BMCWEB_LOG_DEBUG("HTTPS certificate install file={}",
633 certFile->getCertFilePath());
634 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800635 service, objectPath, certs::certReplaceIntf, "Replace",
636 certFile->getCertFilePath());
637}
638
Ed Tanouscf9e4172022-12-21 09:30:16 -0800639// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800640static std::unique_ptr<sdbusplus::bus::match_t> csrMatcher;
641/**
642 * @brief Read data from CSR D-bus object and set to response
643 *
644 * @param[in] asyncResp Shared pointer to the response message
Ed Tanous8ece0e42024-01-02 13:16:50 -0800645 * @param[in] certURI Link to certificate collection URI
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800646 * @param[in] service D-Bus service name
647 * @param[in] certObjPath certificate D-Bus object path
648 * @param[in] csrObjPath CSR D-Bus object path
649 * @return None
650 */
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700651inline void getCSR(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800652 const std::string& certURI, const std::string& service,
653 const std::string& certObjPath,
654 const std::string& csrObjPath)
655{
Ed Tanous62598e32023-07-17 17:06:25 -0700656 BMCWEB_LOG_DEBUG("getCSR CertObjectPath{} CSRObjectPath={} service={}",
657 certObjPath, csrObjPath, service);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800658 crow::connections::systemBus->async_method_call(
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400659 [asyncResp,
660 certURI](const boost::system::error_code& ec, const std::string& csr) {
661 if (ec)
662 {
663 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
664 messages::internalError(asyncResp->res);
665 return;
666 }
667 if (csr.empty())
668 {
669 BMCWEB_LOG_ERROR("CSR read is empty");
670 messages::internalError(asyncResp->res);
671 return;
672 }
673 asyncResp->res.jsonValue["CSRString"] = csr;
674 asyncResp->res.jsonValue["CertificateCollection"]["@odata.id"] =
675 certURI;
676 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800677 service, csrObjPath, "xyz.openbmc_project.Certs.CSR", "CSR");
678}
679
680inline void
681 handleGenerateCSRAction(App& app, const crow::Request& req,
682 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
683{
684 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
685 {
686 return;
687 }
688 static const int rsaKeyBitLength = 2048;
689
690 // Required parameters
691 std::string city;
692 std::string commonName;
693 std::string country;
694 std::string organization;
695 std::string organizationalUnit;
696 std::string state;
Ed Tanous7a31e332024-03-06 12:17:43 -0800697 std::string certURI;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800698
699 // Optional parameters
700 std::optional<std::vector<std::string>> optAlternativeNames =
701 std::vector<std::string>();
702 std::optional<std::string> optContactPerson = "";
703 std::optional<std::string> optChallengePassword = "";
704 std::optional<std::string> optEmail = "";
705 std::optional<std::string> optGivenName = "";
706 std::optional<std::string> optInitials = "";
707 std::optional<int64_t> optKeyBitLength = rsaKeyBitLength;
708 std::optional<std::string> optKeyCurveId = "secp384r1";
709 std::optional<std::string> optKeyPairAlgorithm = "EC";
710 std::optional<std::vector<std::string>> optKeyUsage =
711 std::vector<std::string>();
712 std::optional<std::string> optSurname = "";
713 std::optional<std::string> optUnstructuredName = "";
Myung Baeafc474a2024-10-09 00:53:29 -0700714 if (!json_util::readJsonAction( //
715 req, asyncResp->res, //
716 "AlternativeNames", optAlternativeNames, //
717 "CertificateCollection/@odata.id", certURI, //
718 "ChallengePassword", optChallengePassword, //
719 "City", city, //
720 "CommonName", commonName, //
721 "ContactPerson", optContactPerson, //
722 "Country", country, //
723 "Email", optEmail, //
724 "GivenName", optGivenName, //
725 "Initials", optInitials, //
726 "KeyBitLength", optKeyBitLength, //
727 "KeyCurveId", optKeyCurveId, //
728 "KeyPairAlgorithm", optKeyPairAlgorithm, //
729 "KeyUsage", optKeyUsage, //
730 "Organization", organization, //
731 "OrganizationalUnit", organizationalUnit, //
732 "State", state, //
733 "Surname", optSurname, //
734 "UnstructuredName", optUnstructuredName //
735 ))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800736 {
737 return;
738 }
739
740 // bmcweb has no way to store or decode a private key challenge
741 // password, which will likely cause bmcweb to crash on startup
742 // if this is not set on a post so not allowing the user to set
743 // value
744 if (!optChallengePassword->empty())
745 {
746 messages::actionParameterNotSupported(asyncResp->res, "GenerateCSR",
747 "ChallengePassword");
748 return;
749 }
750
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800751 std::string objectPath;
752 std::string service;
Ed Tanous253f11b2024-05-16 09:38:31 -0700753 if (certURI.starts_with(std::format(
754 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates",
755 BMCWEB_REDFISH_MANAGER_URI_NAME)))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800756 {
757 objectPath = certs::httpsObjectPath;
758 service = certs::httpsServiceName;
759 }
760 else if (certURI.starts_with(
761 "/redfish/v1/AccountService/LDAP/Certificates"))
762 {
763 objectPath = certs::ldapObjectPath;
764 service = certs::ldapServiceName;
765 }
766 else
767 {
768 messages::actionParameterNotSupported(
769 asyncResp->res, "CertificateCollection", "GenerateCSR");
770 return;
771 }
772
773 // supporting only EC and RSA algorithm
774 if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
775 {
776 messages::actionParameterNotSupported(
777 asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
778 return;
779 }
780
781 // supporting only 2048 key bit length for RSA algorithm due to
782 // time consumed in generating private key
783 if (*optKeyPairAlgorithm == "RSA" && *optKeyBitLength != rsaKeyBitLength)
784 {
Ed Tanouse2616cc2022-06-27 12:45:55 -0700785 messages::propertyValueNotInList(asyncResp->res, *optKeyBitLength,
786 "KeyBitLength");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800787 return;
788 }
789
790 // validate KeyUsage supporting only 1 type based on URL
Ed Tanous253f11b2024-05-16 09:38:31 -0700791 if (certURI.starts_with(std::format(
792 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates",
793 BMCWEB_REDFISH_MANAGER_URI_NAME)))
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800794 {
795 if (optKeyUsage->empty())
796 {
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500797 optKeyUsage->emplace_back("ServerAuthentication");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800798 }
799 else if (optKeyUsage->size() == 1)
800 {
801 if ((*optKeyUsage)[0] != "ServerAuthentication")
802 {
803 messages::propertyValueNotInList(asyncResp->res,
804 (*optKeyUsage)[0], "KeyUsage");
805 return;
806 }
807 }
808 else
809 {
810 messages::actionParameterNotSupported(asyncResp->res, "KeyUsage",
811 "GenerateCSR");
812 return;
813 }
814 }
815 else if (certURI.starts_with(
816 "/redfish/v1/AccountService/LDAP/Certificates"))
817 {
818 if (optKeyUsage->empty())
819 {
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500820 optKeyUsage->emplace_back("ClientAuthentication");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800821 }
822 else if (optKeyUsage->size() == 1)
823 {
824 if ((*optKeyUsage)[0] != "ClientAuthentication")
825 {
826 messages::propertyValueNotInList(asyncResp->res,
827 (*optKeyUsage)[0], "KeyUsage");
828 return;
829 }
830 }
831 else
832 {
833 messages::actionParameterNotSupported(asyncResp->res, "KeyUsage",
834 "GenerateCSR");
835 return;
836 }
837 }
838
839 // Only allow one CSR matcher at a time so setting retry
840 // time-out and timer expiry to 10 seconds for now.
841 static const int timeOut = 10;
842 if (csrMatcher)
843 {
844 messages::serviceTemporarilyUnavailable(asyncResp->res,
845 std::to_string(timeOut));
846 return;
847 }
848
Ed Tanous8e8245d2024-04-11 22:21:38 -0700849 if (req.ioService == nullptr)
850 {
851 messages::internalError(asyncResp->res);
852 return;
853 }
854
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800855 // Make this static so it survives outside this method
856 static boost::asio::steady_timer timeout(*req.ioService);
857 timeout.expires_after(std::chrono::seconds(timeOut));
858 timeout.async_wait([asyncResp](const boost::system::error_code& ec) {
859 csrMatcher = nullptr;
860 if (ec)
861 {
862 // operation_aborted is expected if timer is canceled
863 // before completion.
864 if (ec != boost::asio::error::operation_aborted)
865 {
Ed Tanous62598e32023-07-17 17:06:25 -0700866 BMCWEB_LOG_ERROR("Async_wait failed {}", ec);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800867 }
868 return;
869 }
Ed Tanous62598e32023-07-17 17:06:25 -0700870 BMCWEB_LOG_ERROR("Timed out waiting for Generating CSR");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800871 messages::internalError(asyncResp->res);
872 });
873
874 // create a matcher to wait on CSR object
Ed Tanous62598e32023-07-17 17:06:25 -0700875 BMCWEB_LOG_DEBUG("create matcher with path {}", objectPath);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800876 std::string match("type='signal',"
877 "interface='org.freedesktop.DBus.ObjectManager',"
878 "path='" +
879 objectPath +
880 "',"
881 "member='InterfacesAdded'");
882 csrMatcher = std::make_unique<sdbusplus::bus::match_t>(
883 *crow::connections::systemBus, match,
884 [asyncResp, service, objectPath, certURI](sdbusplus::message_t& m) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400885 timeout.cancel();
886 if (m.is_method_error())
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800887 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400888 BMCWEB_LOG_ERROR("Dbus method error!!!");
889 messages::internalError(asyncResp->res);
890 return;
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800891 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400892
893 dbus::utility::DBusInterfacesMap interfacesProperties;
894
895 sdbusplus::message::object_path csrObjectPath;
896 m.read(csrObjectPath, interfacesProperties);
897 BMCWEB_LOG_DEBUG("CSR object added{}", csrObjectPath.str);
898 for (const auto& interface : interfacesProperties)
899 {
900 if (interface.first == "xyz.openbmc_project.Certs.CSR")
901 {
902 getCSR(asyncResp, certURI, service, objectPath,
903 csrObjectPath.str);
904 break;
905 }
906 }
907 });
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800908 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800909 [asyncResp](const boost::system::error_code& ec, const std::string&) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400910 if (ec)
911 {
912 BMCWEB_LOG_ERROR("DBUS response error: {}", ec.message());
913 messages::internalError(asyncResp->res);
914 return;
915 }
916 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800917 service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
918 "GenerateCSR", *optAlternativeNames, *optChallengePassword, city,
919 commonName, *optContactPerson, country, *optEmail, *optGivenName,
920 *optInitials, *optKeyBitLength, *optKeyCurveId, *optKeyPairAlgorithm,
921 *optKeyUsage, organization, organizationalUnit, state, *optSurname,
922 *optUnstructuredName);
923}
924
925inline void requestRoutesCertificateService(App& app)
926{
927 BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/")
928 .privileges(redfish::privileges::getCertificateService)
929 .methods(boost::beast::http::verb::get)(
930 std::bind_front(handleCertificateServiceGet, std::ref(app)));
931
932 BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/CertificateLocations/")
933 .privileges(redfish::privileges::getCertificateLocations)
934 .methods(boost::beast::http::verb::get)(
935 std::bind_front(handleCertificateLocationsGet, std::ref(app)));
936
George Liu0fda0f12021-11-16 10:06:17 +0800937 BMCWEB_ROUTE(
938 app,
939 "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate/")
Ed Tanoused398212021-06-09 17:05:54 -0700940 .privileges(redfish::privileges::postCertificateService)
Ed Tanous002d39b2022-05-31 08:59:27 -0700941 .methods(boost::beast::http::verb::post)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800942 std::bind_front(handleReplaceCertificateAction, std::ref(app)));
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600943
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800944 BMCWEB_ROUTE(
945 app,
946 "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR/")
947 .privileges(redfish::privileges::postCertificateService)
948 .methods(boost::beast::http::verb::post)(
949 std::bind_front(handleGenerateCSRAction, std::ref(app)));
950} // requestRoutesCertificateService
951
952inline void handleHTTPSCertificateCollectionGet(
953 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -0700954 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
955 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800956{
957 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
958 {
959 return;
960 }
961
Ed Tanous253f11b2024-05-16 09:38:31 -0700962 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
963 {
964 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
965 return;
966 }
967
968 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
969 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates",
970 BMCWEB_REDFISH_MANAGER_URI_NAME);
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800971 asyncResp->res.jsonValue["@odata.type"] =
972 "#CertificateCollection.CertificateCollection";
973 asyncResp->res.jsonValue["Name"] = "HTTPS Certificates Collection";
974 asyncResp->res.jsonValue["Description"] =
975 "A Collection of HTTPS certificate instances";
976
977 getCertificateList(asyncResp, certs::httpsObjectPath,
978 "/Members"_json_pointer,
979 "/Members@odata.count"_json_pointer);
980}
981
982inline void handleHTTPSCertificateCollectionPost(
983 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -0700984 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
985 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800986{
987 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
988 {
989 return;
990 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700991
992 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
993 {
994 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
995 return;
996 }
997
Ed Tanous62598e32023-07-17 17:06:25 -0700998 BMCWEB_LOG_DEBUG("HTTPSCertificateCollection::doPost");
Jiaqing Zhao828252d2022-09-30 13:59:19 +0800999
1000 asyncResp->res.jsonValue["Name"] = "HTTPS Certificate";
1001 asyncResp->res.jsonValue["Description"] = "HTTPS Certificate";
1002
Ed Tanousb2896142024-01-31 15:25:47 -08001003 std::string certHttpBody = getCertificateFromReqBody(asyncResp, req);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001004
Ed Tanousb2896142024-01-31 15:25:47 -08001005 if (certHttpBody.empty())
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001006 {
Ed Tanous62598e32023-07-17 17:06:25 -07001007 BMCWEB_LOG_ERROR("Cannot get certificate from request body.");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001008 messages::unrecognizedRequestBody(asyncResp->res);
1009 return;
1010 }
1011
1012 std::shared_ptr<CertificateFile> certFile =
Ed Tanousb2896142024-01-31 15:25:47 -08001013 std::make_shared<CertificateFile>(certHttpBody);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001014
1015 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001016 [asyncResp, certFile](const boost::system::error_code& ec,
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001017 const std::string& objectPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001018 if (ec)
1019 {
1020 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
1021 messages::internalError(asyncResp->res);
1022 return;
1023 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001024
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001025 sdbusplus::message::object_path path(objectPath);
1026 std::string certId = path.filename();
1027 const boost::urls::url certURL = boost::urls::format(
1028 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
1029 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
1030 getCertificateProperties(asyncResp, objectPath,
1031 certs::httpsServiceName, certId, certURL,
1032 "HTTPS Certificate");
1033 BMCWEB_LOG_DEBUG("HTTPS certificate install file={}",
1034 certFile->getCertFilePath());
1035 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001036 certs::httpsServiceName, certs::httpsObjectPath, certs::certInstallIntf,
1037 "Install", certFile->getCertFilePath());
1038}
Ed Tanous002d39b2022-05-31 08:59:27 -07001039
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001040inline void handleHTTPSCertificateGet(
1041 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001042 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1043 const std::string& managerId, const std::string& certId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001044{
1045 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1046 {
1047 return;
1048 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001049
Ed Tanous253f11b2024-05-16 09:38:31 -07001050 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1051 {
1052 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1053 return;
1054 }
1055
1056 BMCWEB_LOG_DEBUG("HTTPS Certificate ID={}", certId);
Ed Tanousef4c65b2023-04-24 15:28:50 -07001057 const boost::urls::url certURL = boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -07001058 "/redfish/v1/Managers/{}/NetworkProtocol/HTTPS/Certificates/{}",
1059 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001060 std::string objPath =
Ed Tanous253f11b2024-05-16 09:38:31 -07001061 sdbusplus::message::object_path(certs::httpsObjectPath) / certId;
1062 getCertificateProperties(asyncResp, objPath, certs::httpsServiceName,
1063 certId, certURL, "HTTPS Certificate");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001064}
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001065
1066inline void requestRoutesHTTPSCertificate(App& app)
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001067{
Ed Tanous253f11b2024-05-16 09:38:31 -07001068 BMCWEB_ROUTE(
1069 app, "/redfish/v1/Managers/<str>/NetworkProtocol/HTTPS/Certificates/")
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001070 .privileges(redfish::privileges::getCertificateCollection)
1071 .methods(boost::beast::http::verb::get)(std::bind_front(
1072 handleHTTPSCertificateCollectionGet, std::ref(app)));
1073
Ed Tanous253f11b2024-05-16 09:38:31 -07001074 BMCWEB_ROUTE(
1075 app, "/redfish/v1/Managers/<str>/NetworkProtocol/HTTPS/Certificates/")
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001076 .privileges(redfish::privileges::postCertificateCollection)
1077 .methods(boost::beast::http::verb::post)(std::bind_front(
1078 handleHTTPSCertificateCollectionPost, std::ref(app)));
1079
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001080 BMCWEB_ROUTE(
1081 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001082 "/redfish/v1/Managers/<str>/NetworkProtocol/HTTPS/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001083 .privileges(redfish::privileges::getCertificate)
Jiaqing Zhao1e312592022-06-14 12:58:09 +08001084 .methods(boost::beast::http::verb::get)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001085 std::bind_front(handleHTTPSCertificateGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001086}
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001087
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001088inline void handleLDAPCertificateCollectionGet(
1089 App& app, const crow::Request& req,
1090 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001091{
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001092 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1093 {
1094 return;
1095 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001096
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001097 asyncResp->res.jsonValue["@odata.id"] =
1098 "/redfish/v1/AccountService/LDAP/Certificates";
1099 asyncResp->res.jsonValue["@odata.type"] =
1100 "#CertificateCollection.CertificateCollection";
1101 asyncResp->res.jsonValue["Name"] = "LDAP Certificates Collection";
1102 asyncResp->res.jsonValue["Description"] =
1103 "A Collection of LDAP certificate instances";
Ed Tanous002d39b2022-05-31 08:59:27 -07001104
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001105 getCertificateList(asyncResp, certs::ldapObjectPath,
1106 "/Members"_json_pointer,
1107 "/Members@odata.count"_json_pointer);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001108}
Marri Devender Rao37cce912019-02-20 01:05:22 -06001109
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001110inline void handleLDAPCertificateCollectionPost(
1111 App& app, const crow::Request& req,
1112 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Marri Devender Rao37cce912019-02-20 01:05:22 -06001113{
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001114 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1115 {
1116 return;
1117 }
Ed Tanousb2896142024-01-31 15:25:47 -08001118 std::string certHttpBody = getCertificateFromReqBody(asyncResp, req);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001119
Ed Tanousb2896142024-01-31 15:25:47 -08001120 if (certHttpBody.empty())
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001121 {
Ed Tanous62598e32023-07-17 17:06:25 -07001122 BMCWEB_LOG_ERROR("Cannot get certificate from request body.");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001123 messages::unrecognizedRequestBody(asyncResp->res);
1124 return;
1125 }
1126
1127 std::shared_ptr<CertificateFile> certFile =
Ed Tanousb2896142024-01-31 15:25:47 -08001128 std::make_shared<CertificateFile>(certHttpBody);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001129
1130 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001131 [asyncResp, certFile](const boost::system::error_code& ec,
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001132 const std::string& objectPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001133 if (ec)
1134 {
1135 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
1136 messages::internalError(asyncResp->res);
1137 return;
1138 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001139
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001140 sdbusplus::message::object_path path(objectPath);
1141 std::string certId = path.filename();
1142 const boost::urls::url certURL = boost::urls::format(
1143 "/redfish/v1/AccountService/LDAP/Certificates/{}", certId);
1144 getCertificateProperties(asyncResp, objectPath,
1145 certs::ldapServiceName, certId, certURL,
1146 "LDAP Certificate");
1147 BMCWEB_LOG_DEBUG("LDAP certificate install file={}",
1148 certFile->getCertFilePath());
1149 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001150 certs::ldapServiceName, certs::ldapObjectPath, certs::certInstallIntf,
1151 "Install", certFile->getCertFilePath());
1152}
Ed Tanous002d39b2022-05-31 08:59:27 -07001153
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001154inline void handleLDAPCertificateGet(
1155 App& app, const crow::Request& req,
1156 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
1157{
1158 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1159 {
1160 return;
1161 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001162
Ed Tanous62598e32023-07-17 17:06:25 -07001163 BMCWEB_LOG_DEBUG("LDAP Certificate ID={}", id);
Ed Tanousef4c65b2023-04-24 15:28:50 -07001164 const boost::urls::url certURL = boost::urls::format(
1165 "/redfish/v1/AccountService/LDAP/Certificates/{}", id);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001166 std::string objPath =
1167 sdbusplus::message::object_path(certs::ldapObjectPath) / id;
1168 getCertificateProperties(asyncResp, objPath, certs::ldapServiceName, id,
1169 certURL, "LDAP Certificate");
1170}
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001171
Jiaqing Zhao99612242022-09-29 15:31:09 +08001172inline void handleLDAPCertificateDelete(
1173 App& app, const crow::Request& req,
1174 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
1175{
1176 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1177 {
1178 return;
1179 }
1180
Ed Tanous62598e32023-07-17 17:06:25 -07001181 BMCWEB_LOG_DEBUG("Delete LDAP Certificate ID={}", id);
Jiaqing Zhao99612242022-09-29 15:31:09 +08001182 std::string objPath =
1183 sdbusplus::message::object_path(certs::ldapObjectPath) / id;
1184
1185 deleteCertificate(asyncResp, certs::ldapServiceName, objPath);
1186}
1187
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001188inline void requestRoutesLDAPCertificate(App& app)
Marri Devender Rao37cce912019-02-20 01:05:22 -06001189{
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001190 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
1191 .privileges(redfish::privileges::getCertificateCollection)
1192 .methods(boost::beast::http::verb::get)(
1193 std::bind_front(handleLDAPCertificateCollectionGet, std::ref(app)));
1194
1195 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
1196 .privileges(redfish::privileges::postCertificateCollection)
1197 .methods(boost::beast::http::verb::post)(std::bind_front(
1198 handleLDAPCertificateCollectionPost, std::ref(app)));
1199
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001200 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001201 .privileges(redfish::privileges::getCertificate)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001202 .methods(boost::beast::http::verb::get)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001203 std::bind_front(handleLDAPCertificateGet, std::ref(app)));
Jiaqing Zhao99612242022-09-29 15:31:09 +08001204
1205 BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
1206 .privileges(redfish::privileges::deleteCertificate)
1207 .methods(boost::beast::http::verb::delete_)(
1208 std::bind_front(handleLDAPCertificateDelete, std::ref(app)));
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001209} // requestRoutesLDAPCertificate
1210
1211inline void handleTrustStoreCertificateCollectionGet(
1212 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001213 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1214 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001215{
1216 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1217 {
1218 return;
1219 }
1220
Ed Tanous253f11b2024-05-16 09:38:31 -07001221 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1222 {
1223 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1224 return;
1225 }
1226
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001227 asyncResp->res.jsonValue["@odata.id"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07001228 boost::urls::format("/redfish/v1/Managers/{}/Truststore/Certificates/",
1229 BMCWEB_REDFISH_MANAGER_URI_NAME);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001230 asyncResp->res.jsonValue["@odata.type"] =
1231 "#CertificateCollection.CertificateCollection";
1232 asyncResp->res.jsonValue["Name"] = "TrustStore Certificates Collection";
1233 asyncResp->res.jsonValue["Description"] =
1234 "A Collection of TrustStore certificate instances";
1235
1236 getCertificateList(asyncResp, certs::authorityObjectPath,
1237 "/Members"_json_pointer,
1238 "/Members@odata.count"_json_pointer);
1239}
1240
1241inline void handleTrustStoreCertificateCollectionPost(
1242 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001243 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1244 const std::string& managerId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001245{
1246 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1247 {
1248 return;
1249 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001250
1251 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1252 {
1253 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1254 return;
1255 }
1256
Ed Tanousb2896142024-01-31 15:25:47 -08001257 std::string certHttpBody = getCertificateFromReqBody(asyncResp, req);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001258
Ed Tanousb2896142024-01-31 15:25:47 -08001259 if (certHttpBody.empty())
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001260 {
Ed Tanous62598e32023-07-17 17:06:25 -07001261 BMCWEB_LOG_ERROR("Cannot get certificate from request body.");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001262 messages::unrecognizedRequestBody(asyncResp->res);
1263 return;
1264 }
1265
1266 std::shared_ptr<CertificateFile> certFile =
Ed Tanousb2896142024-01-31 15:25:47 -08001267 std::make_shared<CertificateFile>(certHttpBody);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001268 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001269 [asyncResp, certFile](const boost::system::error_code& ec,
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001270 const std::string& objectPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001271 if (ec)
1272 {
1273 BMCWEB_LOG_ERROR("DBUS response error: {}", ec);
1274 messages::internalError(asyncResp->res);
1275 return;
1276 }
Jiaqing Zhao717b9802022-06-06 20:24:04 +08001277
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001278 sdbusplus::message::object_path path(objectPath);
1279 std::string certId = path.filename();
1280 const boost::urls::url certURL = boost::urls::format(
1281 "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
1282 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
1283 getCertificateProperties(asyncResp, objectPath,
1284 certs::authorityServiceName, certId,
1285 certURL, "TrustStore Certificate");
1286 BMCWEB_LOG_DEBUG("TrustStore certificate install file={}",
1287 certFile->getCertFilePath());
1288 },
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001289 certs::authorityServiceName, certs::authorityObjectPath,
1290 certs::certInstallIntf, "Install", certFile->getCertFilePath());
1291}
1292
1293inline void handleTrustStoreCertificateGet(
1294 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001295 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1296 const std::string& managerId, const std::string& certId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001297{
1298 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1299 {
1300 return;
1301 }
1302
Ed Tanous253f11b2024-05-16 09:38:31 -07001303 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1304 {
1305 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1306 return;
1307 }
1308
1309 BMCWEB_LOG_DEBUG("Truststore Certificate ID={}", certId);
Ed Tanousef4c65b2023-04-24 15:28:50 -07001310 const boost::urls::url certURL = boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -07001311 "/redfish/v1/Managers/{}/Truststore/Certificates/{}",
1312 BMCWEB_REDFISH_MANAGER_URI_NAME, certId);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001313 std::string objPath =
Ed Tanous253f11b2024-05-16 09:38:31 -07001314 sdbusplus::message::object_path(certs::authorityObjectPath) / certId;
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001315 getCertificateProperties(asyncResp, objPath, certs::authorityServiceName,
Ed Tanous253f11b2024-05-16 09:38:31 -07001316 certId, certURL, "TrustStore Certificate");
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001317}
1318
1319inline void handleTrustStoreCertificateDelete(
1320 App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001321 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1322 const std::string& managerId, const std::string& certId)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001323{
1324 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1325 {
1326 return;
1327 }
1328
Ed Tanous253f11b2024-05-16 09:38:31 -07001329 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1330 {
1331 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1332 return;
1333 }
1334
1335 BMCWEB_LOG_DEBUG("Delete TrustStore Certificate ID={}", certId);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001336 std::string objPath =
Ed Tanous253f11b2024-05-16 09:38:31 -07001337 sdbusplus::message::object_path(certs::authorityObjectPath) / certId;
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001338
Jiaqing Zhao7a3a8f72022-09-29 15:15:58 +08001339 deleteCertificate(asyncResp, certs::authorityServiceName, objPath);
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001340}
1341
1342inline void requestRoutesTrustStoreCertificate(App& app)
Marri Devender Raocfcd5f62019-05-17 08:34:37 -05001343{
Ed Tanous253f11b2024-05-16 09:38:31 -07001344 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/Truststore/Certificates/")
Ed Tanoused398212021-06-09 17:05:54 -07001345 .privileges(redfish::privileges::getCertificate)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001346 .methods(boost::beast::http::verb::get)(std::bind_front(
1347 handleTrustStoreCertificateCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001348
Ed Tanous253f11b2024-05-16 09:38:31 -07001349 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/Truststore/Certificates/")
Ed Tanoused398212021-06-09 17:05:54 -07001350 .privileges(redfish::privileges::postCertificateCollection)
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001351 .methods(boost::beast::http::verb::post)(std::bind_front(
1352 handleTrustStoreCertificateCollectionPost, std::ref(app)));
Ed Tanous002d39b2022-05-31 08:59:27 -07001353
Ed Tanous253f11b2024-05-16 09:38:31 -07001354 BMCWEB_ROUTE(app,
1355 "/redfish/v1/Managers/<str>/Truststore/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001356 .privileges(redfish::privileges::getCertificate)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001357 .methods(boost::beast::http::verb::get)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001358 std::bind_front(handleTrustStoreCertificateGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001359
Ed Tanous253f11b2024-05-16 09:38:31 -07001360 BMCWEB_ROUTE(app,
1361 "/redfish/v1/Managers/<str>/Truststore/Certificates/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001362 .privileges(redfish::privileges::deleteCertificate)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001363 .methods(boost::beast::http::verb::delete_)(
Jiaqing Zhao828252d2022-09-30 13:59:19 +08001364 std::bind_front(handleTrustStoreCertificateDelete, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001365} // requestRoutesTrustStoreCertificate
Marri Devender Rao5968cae2019-01-21 10:27:12 -06001366} // namespace redfish