blob: 9a0c9173ca31fcb35503548d94b0241e67b0b00a [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;
Marri Devender Rao6ceec402019-02-01 03:15:19 -060025using CertInstallPath = std::string;
26using CertUploadPath = std::string;
27using InputType = std::string;
28using InstallFunc = std::function<void(const std::string&)>;
Marri Devender Raocd30c492019-06-12 01:40:17 -050029using AppendPrivKeyFunc = std::function<void(const std::string&)>;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050030using CertWatchPtr = std::unique_ptr<Watch>;
Marri Devender Rao6ceec402019-02-01 03:15:19 -060031using namespace phosphor::logging;
32
33// for placeholders
34using namespace std::placeholders;
35namespace fs = std::filesystem;
36
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020037class Manager; // Forward declaration for Certificate Manager.
38
Marri Devender Rao6ceec402019-02-01 03:15:19 -060039// Supported Types.
40static constexpr auto SERVER = "server";
41static constexpr auto CLIENT = "client";
42static constexpr auto AUTHORITY = "authority";
43
44// RAII support for openSSL functions.
45using X509_Ptr = std::unique_ptr<X509, decltype(&::X509_free)>;
Kowalski, Kamildb029c92019-07-08 17:09:39 +020046using X509_STORE_CTX_Ptr =
47 std::unique_ptr<X509_STORE_CTX, decltype(&::X509_STORE_CTX_free)>;
Marri Devender Rao6ceec402019-02-01 03:15:19 -060048
49/** @class Certificate
50 * @brief OpenBMC Certificate entry implementation.
51 * @details A concrete implementation for the
52 * xyz.openbmc_project.Certs.Certificate DBus API
53 * xyz.openbmc_project.Certs.Instal DBus API
54 */
Marri Devender Raoedd11312019-02-27 08:45:10 -060055class Certificate : public CertIfaces
Marri Devender Rao6ceec402019-02-01 03:15:19 -060056{
57 public:
58 Certificate() = delete;
59 Certificate(const Certificate&) = delete;
60 Certificate& operator=(const Certificate&) = delete;
61 Certificate(Certificate&&) = delete;
62 Certificate& operator=(Certificate&&) = delete;
63 virtual ~Certificate();
64
65 /** @brief Constructor for the Certificate Object
66 * @param[in] bus - Bus to attach to.
67 * @param[in] objPath - Object path to attach to
68 * @param[in] type - Type of the certificate
Marri Devender Rao6ceec402019-02-01 03:15:19 -060069 * @param[in] installPath - Path of the certificate to install
70 * @param[in] uploadPath - Path of the certificate file to upload
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050071 * @param[in] watchPtr - watch on self signed certificate pointer
Marri Devender Rao6ceec402019-02-01 03:15:19 -060072 */
73 Certificate(sdbusplus::bus::bus& bus, const std::string& objPath,
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010074 const CertificateType& type, const CertInstallPath& installPath,
75 const CertUploadPath& uploadPath, const CertWatchPtr& watchPtr,
76 Manager& parent);
77
78 /** @brief Validate and Replace/Install the certificate file
79 * Install/Replace the existing certificate file with another
80 * (possibly CA signed) Certificate file.
81 * @param[in] filePath - Certificate file path.
82 */
83 void install(const std::string& filePath);
Marri Devender Rao6ceec402019-02-01 03:15:19 -060084
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050085 /** @brief Validate certificate and replace the existing certificate
86 * @param[in] filePath - Certificate file path.
87 */
88 void replace(const std::string filePath) override;
89
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050090 /** @brief Populate certificate properties by parsing certificate file
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050091 */
92 void populateProperties();
93
Kowalski, Kamildb029c92019-07-08 17:09:39 +020094 /**
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010095 * @brief Obtain certificate ID.
Kowalski, Kamildb029c92019-07-08 17:09:39 +020096 *
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010097 * @return Certificate ID.
Kowalski, Kamildb029c92019-07-08 17:09:39 +020098 */
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010099 std::string getCertId() const;
100
101 /**
102 * @brief Check if provied certificate is the same as the current one.
103 *
104 * @param[in] certPath - File path for certificate to check.
105 *
106 * @return Checking result. Return true if certificates are the same,
107 * false if not.
108 */
109 bool isSame(const std::string& certPath);
110
111 /**
112 * @brief Update certificate storage.
113 */
114 void storageUpdate();
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200115
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +0200116 /**
117 * @brief Delete the certificate
118 */
119 void delete_() override;
120
Marri Devender Rao13bf74e2019-03-26 01:52:17 -0500121 private:
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200122 /**
Marri Devender Raoc4522d22020-03-12 06:50:17 -0500123 * @brief Return error if ceritificate expiry date is gt 2038
124 *
125 * Parse the certificate and return error if certificate expiry date
126 * is gt 2038.
127 *
128 * @param[in] cert Reference to certificate object uploaded
129 *
130 * @return void
131 */
132 void validateCertificateExpiryDate(const X509_Ptr& cert);
133
134 /**
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200135 * @brief Populate certificate properties by parsing given certificate file
136 *
137 * @param[in] certPath Path to certificate that should be parsed
138 *
139 * @return void
140 */
141 void populateProperties(const std::string& certPath);
142
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100143 /** @brief Load Certificate file into the X509 structure.
Marri Devender Raocd30c492019-06-12 01:40:17 -0500144 * @param[in] filePath - Certificate and key full file path.
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600145 * @return pointer to the X509 structure.
146 */
147 X509_Ptr loadCert(const std::string& filePath);
148
Marri Devender Raocd30c492019-06-12 01:40:17 -0500149 /** @brief Check and append private key to the certificate file
150 * If private key is not present in the certificate file append the
151 * certificate file with private key existing in the system.
152 * @param[in] filePath - Certificate and key full file path.
153 * @return void.
154 */
155 void checkAndAppendPrivateKey(const std::string& filePath);
156
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600157 /** @brief Public/Private key compare function.
158 * Comparing private key against certificate public key
159 * from input .pem file.
Marri Devender Raocd30c492019-06-12 01:40:17 -0500160 * @param[in] filePath - Certificate and key full file path.
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600161 * @return Return true if Key compare is successful,
162 * false if not
163 */
164 bool compareKeys(const std::string& filePath);
Marri Devender Raocd30c492019-06-12 01:40:17 -0500165
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100166 /**
167 * @brief Generate certificate ID based on provided certificate file.
168 *
169 * @param[in] certPath - Certificate file path.
170 *
171 * @return Certificate ID as formatted string.
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600172 */
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100173 std::string generateCertId(const std::string& certPath);
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600174
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200175 /**
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100176 * @brief Generate file name which is unique in the provided directory.
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200177 *
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100178 * @param[in] directoryPath - Directory path.
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200179 *
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100180 * @return File path.
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200181 */
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100182 std::string generateUniqueFilePath(const std::string& directoryPath);
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200183
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100184 /**
185 * @brief Generate authority certificate file path corresponding with
186 * OpenSSL requirements.
187 *
188 * Prepare authority certificate file path for provied certificate.
189 * OpenSSL puts some restrictions on the certificate file name pattern.
190 * Certificate full file name needs to consists of basic file name which
191 * is certificate subject name hash and file name extension which is an
192 * integer. More over, certificates files names extensions must be
193 * consecutive integer numbers in case many certificates with the same
194 * subject name.
195 * https://www.boost.org/doc/libs/1_69_0/doc/html/boost_asio/reference/ssl__context/add_verify_path.html
196 * https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_load_verify_locations.html
197 *
198 * @param[in] certSrcFilePath - Certificate source file path.
199 * @param[in] certDstDirPath - Certificate destination directory path.
200 *
201 * @return Authority certificate file path.
202 */
203 std::string generateAuthCertFileX509Path(const std::string& certSrcFilePath,
204 const std::string& certDstDirPath);
205
206 /**
207 * @brief Generate authority certificate file path based on provided
208 * certificate source file path.
209 *
210 * @param[in] certSrcFilePath - Certificate source file path.
211 *
212 * @return Authority certificate file path.
213 */
214 std::string generateAuthCertFilePath(const std::string& certSrcFilePath);
215
216 /**
217 * @brief Generate certificate file path based on provided certificate
218 * source file path.
219 *
220 * @param[in] certSrcFilePath - Certificate source file path.
221 *
222 * @return Certificate file path.
223 */
224 std::string generateCertFilePath(const std::string& certSrcFilePath);
225
226 /** @brief Type specific function pointer map */
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600227 std::unordered_map<InputType, InstallFunc> typeFuncMap;
228
229 /** @brief sdbusplus handler */
230 sdbusplus::bus::bus& bus;
231
232 /** @brief object path */
233 std::string objectPath;
234
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100235 /** @brief Type of the certificate */
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600236 CertificateType certType;
237
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100238 /** @brief Stores certificate ID */
239 std::string certId;
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600240
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100241 /** @brief Stores certificate file path */
242 std::string certFilePath;
243
244 /** @brief Certificate file installation path */
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600245 CertInstallPath certInstallPath;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500246
Marri Devender Raocd30c492019-06-12 01:40:17 -0500247 /** @brief Type specific function pointer map for appending private key */
248 std::unordered_map<InputType, AppendPrivKeyFunc> appendKeyMap;
249
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500250 /** @brief Certificate file create/update watch */
251 const CertWatchPtr& certWatchPtr;
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200252
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +0200253 /** @brief Reference to Certificate Manager */
254 Manager& manager;
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600255};
256
257} // namespace certs
258} // namespace phosphor