blob: 89887f722bc3a0bf3e8bb2222de7f1a949a2a487 [file] [log] [blame]
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -05001#pragma once
Jayanth Othayothdd74bd22018-09-28 06:13:35 -05002
Marri Devender Raof4682712019-03-19 05:00:28 -05003#include "certificate.hpp"
4#include "csr.hpp"
Marri Devender Raoffad1ef2019-06-03 04:54:12 -05005#include "watch.hpp"
Marri Devender Raof4682712019-03-19 05:00:28 -05006
Nan Zhou014be0b2021-12-28 18:00:14 -08007#include <openssl/evp.h>
8#include <openssl/ossl_typ.h>
9#include <openssl/x509.h>
10
11#include <cstdint>
Nan Zhoucf06ccd2021-12-28 16:25:45 -080012#include <filesystem>
Nan Zhou014be0b2021-12-28 18:00:14 -080013#include <memory>
14#include <sdbusplus/server/object.hpp>
Marri Devender Raof4682712019-03-19 05:00:28 -050015#include <sdeventplus/source/child.hpp>
16#include <sdeventplus/source/event.hpp>
Nan Zhou014be0b2021-12-28 18:00:14 -080017#include <string>
18#include <vector>
Marri Devender Raof4682712019-03-19 05:00:28 -050019#include <xyz/openbmc_project/Certs/CSR/Create/server.hpp>
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050020#include <xyz/openbmc_project/Certs/Install/server.hpp>
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020021#include <xyz/openbmc_project/Collection/DeleteAll/server.hpp>
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050022
Nan Zhoue1289ad2021-12-28 11:02:56 -080023namespace phosphor::certs
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050024{
Marri Devender Raof4682712019-03-19 05:00:28 -050025
Nan Zhoucf06ccd2021-12-28 16:25:45 -080026namespace internal
27{
28using ManagerInterface = sdbusplus::server::object_t<
29 sdbusplus::xyz::openbmc_project::Certs::server::Install,
30 sdbusplus::xyz::openbmc_project::Certs::CSR::server::Create,
31 sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll>;
32}
Jayanth Othayothb50789c2018-10-09 07:13:54 -050033
Nan Zhoucf06ccd2021-12-28 16:25:45 -080034class Manager : public internal::ManagerInterface
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050035{
36 public:
37 /* Define all of the basic class operations:
38 * Not allowed:
39 * - Default constructor is not possible due to member
40 * reference
41 * - Move operations due to 'this' being registered as the
42 * 'context' with sdbus.
43 * Allowed:
44 * - copy
45 * - Destructor.
46 */
47 Manager() = delete;
Nan Zhoucf06ccd2021-12-28 16:25:45 -080048 Manager(const Manager&) = delete;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050049 Manager& operator=(const Manager&) = delete;
50 Manager(Manager&&) = delete;
51 Manager& operator=(Manager&&) = delete;
52 virtual ~Manager() = default;
53
54 /** @brief Constructor to put object onto bus at a dbus path.
55 * @param[in] bus - Bus to attach to.
Marri Devender Raof4682712019-03-19 05:00:28 -050056 * @param[in] event - sd event handler.
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050057 * @param[in] path - Path to attach at.
58 * @param[in] type - Type of the certificate.
59 * @param[in] unit - Unit consumed by this certificate.
Marri Devender Rao6ceec402019-02-01 03:15:19 -060060 * @param[in] installPath - Certificate installation path.
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050061 */
Marri Devender Raof4682712019-03-19 05:00:28 -050062 Manager(sdbusplus::bus::bus& bus, sdeventplus::Event& event,
Nan Zhoucf06ccd2021-12-28 16:25:45 -080063 const char* path, CertificateType type, const std::string& unit,
64 const std::string& installPath);
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050065
66 /** @brief Implementation for Install
67 * Replace the existing certificate key file with another
68 * (possibly CA signed) Certificate key file.
69 *
Marri Devender Rao6ceec402019-02-01 03:15:19 -060070 * @param[in] filePath - Certificate key file path.
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010071 *
72 * @return Certificate object path.
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050073 */
Zbigniew Kurzynski06a69d72019-09-27 10:57:38 +020074 std::string install(const std::string filePath) override;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050075
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020076 /** @brief Implementation for DeleteAll
77 * Delete all objects in the collection.
Deepak Kodihalliae70b3d2018-09-30 05:42:00 -050078 */
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020079 void deleteAll() override;
80
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010081 /** @brief Delete the certificate.
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020082 */
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010083 void deleteCertificate(const Certificate* const certificate);
84
85 /** @brief Replace the certificate.
86 */
87 void replaceCertificate(Certificate* const certificate,
88 const std::string& filePath);
Deepak Kodihalliae70b3d2018-09-30 05:42:00 -050089
Marri Devender Raof4682712019-03-19 05:00:28 -050090 /** @brief Generate Private key and CSR file
91 * Generates the Private key file and CSR file based on the input
92 * parameters. Validation of the parameters is callers responsibility.
93 * At present supports only RSA algorithm type
94 *
95 * @param[in] alternativeNames - Additional hostnames of the component that
96 * is being secured.
97 * @param[in] challengePassword - The challenge password to be applied to
98 * the certificate for revocation requests.
99 * @param[in] city - The city or locality of the organization making the
100 * request. For Example Austin
101 * @param[in] commonName - The fully qualified domain name of the component
102 * that is being secured.
103 * @param[in] contactPerson - The name of the user making the request.
104 * @param[in] country - The country of the organization making the request.
105 * @param[in] email - The email address of the contact within the
106 * organization making the request.
107 * @param[in] givenName - The given name of the user making the request.
108 * @param[in] initials - The initials of the user making the request.
109 * @param[in] keyBitLength - The length of the key in bits, if needed based
110 * on the value of the KeyPairAlgorithm parameter.
111 * @param[in] keyCurveId - The curve ID to be used with the key, if needed
112 * based on the value of the KeyPairAlgorithm parameter.
113 * @param[in] keyPairAlgorithm - The type of key pair for use with signing
114 * algorithms. Valid built-in algorithm names for private key
115 * generation are: RSA, DSA, DH and EC.
116 * @param[in] keyUsage - Key usage extensions define the purpose of the
117 * public key contained in a certificate. Valid Key usage extensions
118 * and its usage description.
119 * - ClientAuthentication: The public key is used for TLS WWW client
120 * authentication.
121 * - CodeSigning: The public key is used for the signing of executable
122 * code
123 * - CRLSigning: The public key is used for verifying signatures on
124 * certificate revocation lists (CLRs).
125 * - DataEncipherment: The public key is used for directly enciphering
126 * raw user data without the use of an intermediate symmetric
127 * cipher.
128 * - DecipherOnly: The public key could be used for deciphering data
129 * while performing key agreement.
130 * - DigitalSignature: The public key is used for verifying digital
131 * signatures, other than signatures on certificatesand CRLs.
132 * - EmailProtection: The public key is used for email protection.
133 * - EncipherOnly: Thepublic key could be used for enciphering data
134 * while performing key agreement.
135 * - KeyCertSign: The public key is used for verifying signatures on
136 * public key certificates.
137 * - KeyEncipherment: The public key is used for enciphering private or
138 * secret keys.
139 * - NonRepudiation: The public key is used to verify digital
140 * signatures, other than signatures on certificates and CRLs, and
141 * used to provide a non-repudiation service that protects against
142 * the signing entity falsely denying some action.
143 * - OCSPSigning: The public key is used for signing OCSP responses.
144 * - ServerAuthentication: The public key is used for TLS WWW server
145 * authentication.
146 * - Timestamping: The public key is used for binding the hash of an
147 * object to a time.
148 * @param[in] organization - The legal name of the organization. This
149 * should not be abbreviated and should include suffixes such as Inc,
150 * Corp, or LLC.For example, IBM Corp.
151 * @param[in] organizationalUnit - The name of the unit or division of the
152 * organization making the request.
153 * @param[in] state - The state or province where the organization is
154 * located. This should not be abbreviated. For example, Texas.
155 * @param[in] surname - The surname of the user making the request.
156 * @param[in] unstructuredName - The unstructured name of the subject.
157 *
158 * @return path[std::string] - The object path of the D-Bus object
159 * representing CSR string. Note: For new CSR request will overwrite
160 * the existing CSR in the system.
161 */
162 std::string generateCSR(
163 std::vector<std::string> alternativeNames,
164 std::string challengePassword, std::string city, std::string commonName,
165 std::string contactPerson, std::string country, std::string email,
166 std::string givenName, std::string initials, int64_t keyBitLength,
167 std::string keyCurveId, std::string keyPairAlgorithm,
168 std::vector<std::string> keyUsage, std::string organization,
169 std::string organizationalUnit, std::string state, std::string surname,
170 std::string unstructuredName) override;
171
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200172 /** @brief Get reference to certificates' collection
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500173 *
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200174 * @return Reference to certificates' collection
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500175 */
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200176 std::vector<std::unique_ptr<Certificate>>& getCertificates();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500177
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500178 private:
Marri Devender Raof4682712019-03-19 05:00:28 -0500179 void generateCSRHelper(std::vector<std::string> alternativeNames,
180 std::string challengePassword, std::string city,
181 std::string commonName, std::string contactPerson,
182 std::string country, std::string email,
183 std::string givenName, std::string initials,
184 int64_t keyBitLength, std::string keyCurveId,
185 std::string keyPairAlgorithm,
186 std::vector<std::string> keyUsage,
187 std::string organization,
188 std::string organizationalUnit, std::string state,
189 std::string surname, std::string unstructuredName);
190
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500191 /** @brief Generate RSA Key pair and get private key from key pair
192 * @param[in] keyBitLength - KeyBit length.
193 * @return Pointer to RSA private key
194 */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800195 std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>
196 generateRSAKeyPair(const int64_t keyBitLength);
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500197
198 /** @brief Generate EC Key pair and get private key from key pair
199 * @param[in] p_KeyCurveId - Curve ID
200 * @return Pointer to EC private key
201 */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800202 std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>
203 generateECKeyPair(const std::string& p_KeyCurveId);
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500204
Marri Devender Raof4682712019-03-19 05:00:28 -0500205 /** @brief Write private key data to file
206 *
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500207 * @param[in] pKey - pointer to private key
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500208 * @param[in] privKeyFileName - private key filename
Marri Devender Raof4682712019-03-19 05:00:28 -0500209 */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800210 void writePrivateKey(
211 const std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>& pKey,
212 const std::string& privKeyFileName);
Marri Devender Raof4682712019-03-19 05:00:28 -0500213
214 /** @brief Add the specified CSR field with the data
215 * @param[in] x509Name - Structure used in setting certificate properties
216 * @param[in] field - field name
217 * @param[in] bytes - field value in bytes
218 */
219 void addEntry(X509_NAME* x509Name, const char* field,
220 const std::string& bytes);
221
Marri Devender Rao76411052019-08-07 01:25:07 -0500222 /** @brief Check if usage is extended key usage
223 * @param[in] usage - key usage value
224 * @return true if part of extended key usage
225 */
226 bool isExtendedKeyUsage(const std::string& usage);
227
Marri Devender Raof4682712019-03-19 05:00:28 -0500228 /** @brief Create CSR D-Bus object by reading the data in the CSR file
Nan Zhoubf3cf752021-12-28 11:02:07 -0800229 * @param[in] statis - SUCCESS/FAILURE In CSR generation.
Marri Devender Raof4682712019-03-19 05:00:28 -0500230 */
231 void createCSRObject(const Status& status);
232
233 /** @brief Write generated CSR data to file
234 *
235 * @param[in] filePath - CSR file path.
236 * @param[in] x509Req - OpenSSL Request Pointer.
237 */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800238 void writeCSR(
239 const std::string& filePath,
240 const std::unique_ptr<X509_REQ, decltype(&::X509_REQ_free)>& x509Req);
Marri Devender Raof4682712019-03-19 05:00:28 -0500241
Nan Zhoubf3cf752021-12-28 11:02:07 -0800242 /** @brief Load certificate
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500243 * Load certificate and create certificate object
244 */
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200245 void createCertificates();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500246
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500247 /** @brief Create RSA private key file
248 * Create RSA private key file by generating rsa key if not created
249 */
250 void createRSAPrivateKeyFile();
251
252 /** @brief Getting RSA private key
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100253 * Getting RSA private key from generated file
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500254 * @param[in] keyBitLength - Key bit length
255 * @return Pointer to RSA key
256 */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800257 std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>
258 getRSAKeyPair(const int64_t keyBitLength);
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500259
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100260 /** @brief Update certificate storage (remove outdated files, recreate
261 * symbolic links, etc.).
262 */
263 void storageUpdate();
264
265 /** @brief Systemd unit reload or reset helper function
266 * Reload if the unit supports it and use a restart otherwise.
267 * @param[in] unit - service need to reload.
268 */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800269 void reloadOrReset(const std::string& unit);
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100270
271 /** @brief Check if provided certificate is unique across all certificates
272 * on the internal list.
273 * @param[in] certFilePath - Path to the file with certificate for
274 * uniqueness check.
275 * @param[in] certToDrop - Pointer to the certificate from the internal
276 * list which should be not taken into account while uniqueness check.
277 * @return Checking result. True if certificate is unique, false if
278 * not.
279 */
280 bool isCertificateUnique(const std::string& certFilePath,
281 const Certificate* const certToDrop = nullptr);
282
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500283 /** @brief sdbusplus handler */
284 sdbusplus::bus::bus& bus;
285
Marri Devender Raof4682712019-03-19 05:00:28 -0500286 // sdevent Event handle
287 sdeventplus::Event& event;
288
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500289 /** @brief object path */
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600290 std::string objectPath;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500291
292 /** @brief Type of the certificate **/
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600293 CertificateType certType;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500294
295 /** @brief Unit name associated to the service **/
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800296 std::string unitToRestart;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500297
298 /** @brief Certificate file installation path **/
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800299 std::string certInstallPath;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500300
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200301 /** @brief Collection of pointers to certificate */
302 std::vector<std::unique_ptr<Certificate>> installedCerts;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500303
Marri Devender Raof4682712019-03-19 05:00:28 -0500304 /** @brief pointer to CSR */
305 std::unique_ptr<CSR> csrPtr = nullptr;
306
307 /** @brief SDEventPlus child pointer added to event loop */
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500308 std::unique_ptr<sdeventplus::source::Child> childPtr = nullptr;
309
310 /** @brief Watch on self signed certificates */
311 std::unique_ptr<Watch> certWatchPtr = nullptr;
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500312
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100313 /** @brief Parent path i.e certificate directory path */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800314 std::filesystem::path certParentInstallPath;
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200315
316 /** @brief Certificate ID pool */
317 uint64_t certIdCounter = 1;
Marri Devender Raof4682712019-03-19 05:00:28 -0500318};
Nan Zhoue1289ad2021-12-28 11:02:56 -0800319} // namespace phosphor::certs