blob: 9fa2cdd8debcab0a4a266727d95b68db4a1b7cdd [file] [log] [blame]
Marri Devender Rao6ceec402019-02-01 03:15:19 -06001#pragma once
2
Marri Devender Raoffad1ef2019-06-03 04:54:12 -05003#include "watch.hpp"
4
Marri Devender Rao6ceec402019-02-01 03:15:19 -06005#include <openssl/x509.h>
6
7#include <filesystem>
8#include <phosphor-logging/elog.hpp>
Marri Devender Raoedd11312019-02-27 08:45:10 -06009#include <xyz/openbmc_project/Certs/Certificate/server.hpp>
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050010#include <xyz/openbmc_project/Certs/Replace/server.hpp>
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020011#include <xyz/openbmc_project/Object/Delete/server.hpp>
Marri Devender Rao6ceec402019-02-01 03:15:19 -060012
13namespace phosphor
14{
15namespace certs
16{
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020017using DeleteIface = sdbusplus::xyz::openbmc_project::Object::server::Delete;
Marri Devender Raoedd11312019-02-27 08:45:10 -060018using CertificateIface = sdbusplus::server::object::object<
19 sdbusplus::xyz::openbmc_project::Certs::server::Certificate>;
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050020using ReplaceIface = sdbusplus::xyz::openbmc_project::Certs::server::Replace;
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020021using CertIfaces = sdbusplus::server::object::object<CertificateIface,
22 ReplaceIface, DeleteIface>;
Marri Devender Raoedd11312019-02-27 08:45:10 -060023
Marri Devender Rao6ceec402019-02-01 03:15:19 -060024using CertificateType = std::string;
25using UnitsToRestart = std::string;
26using CertInstallPath = std::string;
27using CertUploadPath = std::string;
28using InputType = std::string;
29using InstallFunc = std::function<void(const std::string&)>;
Marri Devender Raocd30c492019-06-12 01:40:17 -050030using AppendPrivKeyFunc = std::function<void(const std::string&)>;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050031using CertWatchPtr = std::unique_ptr<Watch>;
Marri Devender Rao6ceec402019-02-01 03:15:19 -060032using namespace phosphor::logging;
33
34// for placeholders
35using namespace std::placeholders;
36namespace fs = std::filesystem;
37
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020038class Manager; // Forward declaration for Certificate Manager.
39
Marri Devender Rao6ceec402019-02-01 03:15:19 -060040// Supported Types.
41static constexpr auto SERVER = "server";
42static constexpr auto CLIENT = "client";
43static constexpr auto AUTHORITY = "authority";
44
45// RAII support for openSSL functions.
46using X509_Ptr = std::unique_ptr<X509, decltype(&::X509_free)>;
Kowalski, Kamildb029c92019-07-08 17:09:39 +020047using X509_STORE_CTX_Ptr =
48 std::unique_ptr<X509_STORE_CTX, decltype(&::X509_STORE_CTX_free)>;
Marri Devender Rao6ceec402019-02-01 03:15:19 -060049
50/** @class Certificate
51 * @brief OpenBMC Certificate entry implementation.
52 * @details A concrete implementation for the
53 * xyz.openbmc_project.Certs.Certificate DBus API
54 * xyz.openbmc_project.Certs.Instal DBus API
55 */
Marri Devender Raoedd11312019-02-27 08:45:10 -060056class Certificate : public CertIfaces
Marri Devender Rao6ceec402019-02-01 03:15:19 -060057{
58 public:
59 Certificate() = delete;
60 Certificate(const Certificate&) = delete;
61 Certificate& operator=(const Certificate&) = delete;
62 Certificate(Certificate&&) = delete;
63 Certificate& operator=(Certificate&&) = delete;
64 virtual ~Certificate();
65
66 /** @brief Constructor for the Certificate Object
67 * @param[in] bus - Bus to attach to.
68 * @param[in] objPath - Object path to attach to
69 * @param[in] type - Type of the certificate
70 * @param[in] unit - Units to restart after a certificate is installed
71 * @param[in] installPath - Path of the certificate to install
72 * @param[in] uploadPath - Path of the certificate file to upload
Marri Devender Rao8f80c352019-05-13 00:53:01 -050073 * @param[in] isSkipUnitReload - If true do not restart units
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050074 * @param[in] watchPtr - watch on self signed certificate pointer
Marri Devender Rao6ceec402019-02-01 03:15:19 -060075 */
76 Certificate(sdbusplus::bus::bus& bus, const std::string& objPath,
77 const CertificateType& type, const UnitsToRestart& unit,
78 const CertInstallPath& installPath,
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050079 const CertUploadPath& uploadPath, bool isSkipUnitReload,
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020080 const CertWatchPtr& watchPtr, Manager& parent);
Marri Devender Rao6ceec402019-02-01 03:15:19 -060081
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050082 /** @brief Validate certificate and replace the existing certificate
83 * @param[in] filePath - Certificate file path.
84 */
85 void replace(const std::string filePath) override;
86
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050087 /** @brief Populate certificate properties by parsing certificate file
88 * @return void
89 */
90 void populateProperties();
91
Kowalski, Kamildb029c92019-07-08 17:09:39 +020092 /**
93 * @brief Obtain certificate's subject hash
94 *
95 * @return certificate's subject hash
96 */
97 const std::string& getHash() const;
98
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020099 /**
100 * @brief Delete the certificate
101 */
102 void delete_() override;
103
Marri Devender Rao13bf74e2019-03-26 01:52:17 -0500104 private:
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200105 /**
106 * @brief Populate certificate properties by parsing given certificate file
107 *
108 * @param[in] certPath Path to certificate that should be parsed
109 *
110 * @return void
111 */
112 void populateProperties(const std::string& certPath);
113
Marri Devender Rao13bf74e2019-03-26 01:52:17 -0500114 /** @brief Validate and Replace/Install the certificate file
115 * Install/Replace the existing certificate file with another
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600116 * (possibly CA signed) Certificate file.
117 * @param[in] filePath - Certificate file path.
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500118 * @param[in] isSkipUnitReload - If true do not restart units
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600119 */
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500120 void install(const std::string& filePath, bool isSkipUnitReload);
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600121
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600122 /** @brief Load Certificate file into the X509 structre.
Marri Devender Raocd30c492019-06-12 01:40:17 -0500123 * @param[in] filePath - Certificate and key full file path.
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600124 * @return pointer to the X509 structure.
125 */
126 X509_Ptr loadCert(const std::string& filePath);
127
Marri Devender Raocd30c492019-06-12 01:40:17 -0500128 /** @brief Check and append private key to the certificate file
129 * If private key is not present in the certificate file append the
130 * certificate file with private key existing in the system.
131 * @param[in] filePath - Certificate and key full file path.
132 * @return void.
133 */
134 void checkAndAppendPrivateKey(const std::string& filePath);
135
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600136 /** @brief Public/Private key compare function.
137 * Comparing private key against certificate public key
138 * from input .pem file.
Marri Devender Raocd30c492019-06-12 01:40:17 -0500139 * @param[in] filePath - Certificate and key full file path.
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600140 * @return Return true if Key compare is successful,
141 * false if not
142 */
143 bool compareKeys(const std::string& filePath);
Marri Devender Raocd30c492019-06-12 01:40:17 -0500144
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600145 /** @brief systemd unit reload or reset helper function
146 * Reload if the unit supports it and use a restart otherwise.
147 * @param[in] unit - service need to reload.
148 */
149 void reloadOrReset(const UnitsToRestart& unit);
150
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200151 /**
152 * @brief Extracts subject hash
153 *
154 * @param[in] storeCtx Pointer to X509_STORE_CTX containing certificate
155 *
156 * @return Subject hash as formatted string
157 */
158 static inline std::string
159 getSubjectHash(const X509_STORE_CTX_Ptr& storeCtx);
160
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600161 /** @brief Type specific function pointer map **/
162 std::unordered_map<InputType, InstallFunc> typeFuncMap;
163
164 /** @brief sdbusplus handler */
165 sdbusplus::bus::bus& bus;
166
167 /** @brief object path */
168 std::string objectPath;
169
170 /** @brief Type of the certificate **/
171 CertificateType certType;
172
173 /** @brief Unit name associated to the service **/
174 UnitsToRestart unitToRestart;
175
176 /** @brief Certificate file installation path **/
177 CertInstallPath certInstallPath;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500178
Marri Devender Raocd30c492019-06-12 01:40:17 -0500179 /** @brief Type specific function pointer map for appending private key */
180 std::unordered_map<InputType, AppendPrivKeyFunc> appendKeyMap;
181
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500182 /** @brief Certificate file create/update watch */
183 const CertWatchPtr& certWatchPtr;
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200184
185 /** @brief Stores certificate subject hash */
186 std::string certHash;
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +0200187
188 /** @brief Reference to Certificate Manager */
189 Manager& manager;
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600190};
191
192} // namespace certs
193} // namespace phosphor