blob: 56256ac1c2fab88de68bcde5ee3b37af94526721 [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>
Marri Devender Rao6ceec402019-02-01 03:15:19 -060011
12namespace phosphor
13{
14namespace certs
15{
Marri Devender Raoedd11312019-02-27 08:45:10 -060016using CertificateIface = sdbusplus::server::object::object<
17 sdbusplus::xyz::openbmc_project::Certs::server::Certificate>;
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050018using ReplaceIface = sdbusplus::xyz::openbmc_project::Certs::server::Replace;
Marri Devender Raoedd11312019-02-27 08:45:10 -060019using CertIfaces =
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050020 sdbusplus::server::object::object<CertificateIface, ReplaceIface>;
Marri Devender Raoedd11312019-02-27 08:45:10 -060021
Marri Devender Rao6ceec402019-02-01 03:15:19 -060022using CertificateType = std::string;
23using UnitsToRestart = std::string;
24using CertInstallPath = std::string;
25using CertUploadPath = std::string;
26using InputType = std::string;
27using InstallFunc = std::function<void(const std::string&)>;
Marri Devender Raocd30c492019-06-12 01:40:17 -050028using AppendPrivKeyFunc = std::function<void(const std::string&)>;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050029using CertWatchPtr = std::unique_ptr<Watch>;
Marri Devender Rao6ceec402019-02-01 03:15:19 -060030using namespace phosphor::logging;
31
32// for placeholders
33using namespace std::placeholders;
34namespace fs = std::filesystem;
35
36// Supported Types.
37static constexpr auto SERVER = "server";
38static constexpr auto CLIENT = "client";
39static constexpr auto AUTHORITY = "authority";
40
41// RAII support for openSSL functions.
42using X509_Ptr = std::unique_ptr<X509, decltype(&::X509_free)>;
Kowalski, Kamildb029c92019-07-08 17:09:39 +020043using X509_STORE_CTX_Ptr =
44 std::unique_ptr<X509_STORE_CTX, decltype(&::X509_STORE_CTX_free)>;
Marri Devender Rao6ceec402019-02-01 03:15:19 -060045
46/** @class Certificate
47 * @brief OpenBMC Certificate entry implementation.
48 * @details A concrete implementation for the
49 * xyz.openbmc_project.Certs.Certificate DBus API
50 * xyz.openbmc_project.Certs.Instal DBus API
51 */
Marri Devender Raoedd11312019-02-27 08:45:10 -060052class Certificate : public CertIfaces
Marri Devender Rao6ceec402019-02-01 03:15:19 -060053{
54 public:
55 Certificate() = delete;
56 Certificate(const Certificate&) = delete;
57 Certificate& operator=(const Certificate&) = delete;
58 Certificate(Certificate&&) = delete;
59 Certificate& operator=(Certificate&&) = delete;
60 virtual ~Certificate();
61
62 /** @brief Constructor for the Certificate Object
63 * @param[in] bus - Bus to attach to.
64 * @param[in] objPath - Object path to attach to
65 * @param[in] type - Type of the certificate
66 * @param[in] unit - Units to restart after a certificate is installed
67 * @param[in] installPath - Path of the certificate to install
68 * @param[in] uploadPath - Path of the certificate file to upload
Marri Devender Rao8f80c352019-05-13 00:53:01 -050069 * @param[in] isSkipUnitReload - If true do not restart units
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050070 * @param[in] watchPtr - watch on self signed certificate pointer
Marri Devender Rao6ceec402019-02-01 03:15:19 -060071 */
72 Certificate(sdbusplus::bus::bus& bus, const std::string& objPath,
73 const CertificateType& type, const UnitsToRestart& unit,
74 const CertInstallPath& installPath,
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050075 const CertUploadPath& uploadPath, bool isSkipUnitReload,
76 const CertWatchPtr& watchPtr);
Marri Devender Rao6ceec402019-02-01 03:15:19 -060077
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050078 /** @brief Validate certificate and replace the existing certificate
79 * @param[in] filePath - Certificate file path.
80 */
81 void replace(const std::string filePath) override;
82
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050083 /** @brief Populate certificate properties by parsing certificate file
84 * @return void
85 */
86 void populateProperties();
87
Kowalski, Kamildb029c92019-07-08 17:09:39 +020088 /**
89 * @brief Obtain certificate's subject hash
90 *
91 * @return certificate's subject hash
92 */
93 const std::string& getHash() const;
94
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050095 private:
Kowalski, Kamildb029c92019-07-08 17:09:39 +020096 /**
97 * @brief Populate certificate properties by parsing given certificate file
98 *
99 * @param[in] certPath Path to certificate that should be parsed
100 *
101 * @return void
102 */
103 void populateProperties(const std::string& certPath);
104
Marri Devender Rao13bf74e2019-03-26 01:52:17 -0500105 /** @brief Validate and Replace/Install the certificate file
106 * Install/Replace the existing certificate file with another
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600107 * (possibly CA signed) Certificate file.
108 * @param[in] filePath - Certificate file path.
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500109 * @param[in] isSkipUnitReload - If true do not restart units
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600110 */
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500111 void install(const std::string& filePath, bool isSkipUnitReload);
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600112
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600113 /** @brief Load Certificate file into the X509 structre.
Marri Devender Raocd30c492019-06-12 01:40:17 -0500114 * @param[in] filePath - Certificate and key full file path.
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600115 * @return pointer to the X509 structure.
116 */
117 X509_Ptr loadCert(const std::string& filePath);
118
Marri Devender Raocd30c492019-06-12 01:40:17 -0500119 /** @brief Check and append private key to the certificate file
120 * If private key is not present in the certificate file append the
121 * certificate file with private key existing in the system.
122 * @param[in] filePath - Certificate and key full file path.
123 * @return void.
124 */
125 void checkAndAppendPrivateKey(const std::string& filePath);
126
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600127 /** @brief Public/Private key compare function.
128 * Comparing private key against certificate public key
129 * from input .pem file.
Marri Devender Raocd30c492019-06-12 01:40:17 -0500130 * @param[in] filePath - Certificate and key full file path.
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600131 * @return Return true if Key compare is successful,
132 * false if not
133 */
134 bool compareKeys(const std::string& filePath);
Marri Devender Raocd30c492019-06-12 01:40:17 -0500135
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600136 /** @brief systemd unit reload or reset helper function
137 * Reload if the unit supports it and use a restart otherwise.
138 * @param[in] unit - service need to reload.
139 */
140 void reloadOrReset(const UnitsToRestart& unit);
141
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200142 /**
143 * @brief Extracts subject hash
144 *
145 * @param[in] storeCtx Pointer to X509_STORE_CTX containing certificate
146 *
147 * @return Subject hash as formatted string
148 */
149 static inline std::string
150 getSubjectHash(const X509_STORE_CTX_Ptr& storeCtx);
151
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600152 /** @brief Type specific function pointer map **/
153 std::unordered_map<InputType, InstallFunc> typeFuncMap;
154
155 /** @brief sdbusplus handler */
156 sdbusplus::bus::bus& bus;
157
158 /** @brief object path */
159 std::string objectPath;
160
161 /** @brief Type of the certificate **/
162 CertificateType certType;
163
164 /** @brief Unit name associated to the service **/
165 UnitsToRestart unitToRestart;
166
167 /** @brief Certificate file installation path **/
168 CertInstallPath certInstallPath;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500169
Marri Devender Raocd30c492019-06-12 01:40:17 -0500170 /** @brief Type specific function pointer map for appending private key */
171 std::unordered_map<InputType, AppendPrivKeyFunc> appendKeyMap;
172
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500173 /** @brief Certificate file create/update watch */
174 const CertWatchPtr& certWatchPtr;
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200175
176 /** @brief Stores certificate subject hash */
177 std::string certHash;
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600178};
179
180} // namespace certs
181} // namespace phosphor