blob: 44908d7b6e0f7e72cb8d663d96d9d0ae8c82a917 [file] [log] [blame]
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -05001#pragma once
Marri Devender Raof4682712019-03-19 05:00:28 -05002#include "config.h"
Jayanth Othayothdd74bd22018-09-28 06:13:35 -05003
Marri Devender Raof4682712019-03-19 05:00:28 -05004#include "certificate.hpp"
5#include "csr.hpp"
Marri Devender Raoffad1ef2019-06-03 04:54:12 -05006#include "watch.hpp"
Marri Devender Raof4682712019-03-19 05:00:28 -05007
Nan Zhoucf06ccd2021-12-28 16:25:45 -08008#include <filesystem>
Marri Devender Raof4682712019-03-19 05:00:28 -05009#include <sdeventplus/source/child.hpp>
10#include <sdeventplus/source/event.hpp>
11#include <xyz/openbmc_project/Certs/CSR/Create/server.hpp>
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050012#include <xyz/openbmc_project/Certs/Install/server.hpp>
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020013#include <xyz/openbmc_project/Collection/DeleteAll/server.hpp>
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050014
Nan Zhoue1289ad2021-12-28 11:02:56 -080015namespace phosphor::certs
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050016{
Marri Devender Raof4682712019-03-19 05:00:28 -050017
Nan Zhoucf06ccd2021-12-28 16:25:45 -080018namespace internal
19{
20using ManagerInterface = sdbusplus::server::object_t<
21 sdbusplus::xyz::openbmc_project::Certs::server::Install,
22 sdbusplus::xyz::openbmc_project::Certs::CSR::server::Create,
23 sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll>;
24}
Jayanth Othayothb50789c2018-10-09 07:13:54 -050025
Nan Zhoucf06ccd2021-12-28 16:25:45 -080026class Manager : public internal::ManagerInterface
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050027{
28 public:
29 /* Define all of the basic class operations:
30 * Not allowed:
31 * - Default constructor is not possible due to member
32 * reference
33 * - Move operations due to 'this' being registered as the
34 * 'context' with sdbus.
35 * Allowed:
36 * - copy
37 * - Destructor.
38 */
39 Manager() = delete;
Nan Zhoucf06ccd2021-12-28 16:25:45 -080040 Manager(const Manager&) = delete;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050041 Manager& operator=(const Manager&) = delete;
42 Manager(Manager&&) = delete;
43 Manager& operator=(Manager&&) = delete;
44 virtual ~Manager() = default;
45
46 /** @brief Constructor to put object onto bus at a dbus path.
47 * @param[in] bus - Bus to attach to.
Marri Devender Raof4682712019-03-19 05:00:28 -050048 * @param[in] event - sd event handler.
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050049 * @param[in] path - Path to attach at.
50 * @param[in] type - Type of the certificate.
51 * @param[in] unit - Unit consumed by this certificate.
Marri Devender Rao6ceec402019-02-01 03:15:19 -060052 * @param[in] installPath - Certificate installation path.
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050053 */
Marri Devender Raof4682712019-03-19 05:00:28 -050054 Manager(sdbusplus::bus::bus& bus, sdeventplus::Event& event,
Nan Zhoucf06ccd2021-12-28 16:25:45 -080055 const char* path, CertificateType type, const std::string& unit,
56 const std::string& installPath);
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050057
58 /** @brief Implementation for Install
59 * Replace the existing certificate key file with another
60 * (possibly CA signed) Certificate key file.
61 *
Marri Devender Rao6ceec402019-02-01 03:15:19 -060062 * @param[in] filePath - Certificate key file path.
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010063 *
64 * @return Certificate object path.
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050065 */
Zbigniew Kurzynski06a69d72019-09-27 10:57:38 +020066 std::string install(const std::string filePath) override;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050067
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020068 /** @brief Implementation for DeleteAll
69 * Delete all objects in the collection.
Deepak Kodihalliae70b3d2018-09-30 05:42:00 -050070 */
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020071 void deleteAll() override;
72
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010073 /** @brief Delete the certificate.
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020074 */
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010075 void deleteCertificate(const Certificate* const certificate);
76
77 /** @brief Replace the certificate.
78 */
79 void replaceCertificate(Certificate* const certificate,
80 const std::string& filePath);
Deepak Kodihalliae70b3d2018-09-30 05:42:00 -050081
Marri Devender Raof4682712019-03-19 05:00:28 -050082 /** @brief Generate Private key and CSR file
83 * Generates the Private key file and CSR file based on the input
84 * parameters. Validation of the parameters is callers responsibility.
85 * At present supports only RSA algorithm type
86 *
87 * @param[in] alternativeNames - Additional hostnames of the component that
88 * is being secured.
89 * @param[in] challengePassword - The challenge password to be applied to
90 * the certificate for revocation requests.
91 * @param[in] city - The city or locality of the organization making the
92 * request. For Example Austin
93 * @param[in] commonName - The fully qualified domain name of the component
94 * that is being secured.
95 * @param[in] contactPerson - The name of the user making the request.
96 * @param[in] country - The country of the organization making the request.
97 * @param[in] email - The email address of the contact within the
98 * organization making the request.
99 * @param[in] givenName - The given name of the user making the request.
100 * @param[in] initials - The initials of the user making the request.
101 * @param[in] keyBitLength - The length of the key in bits, if needed based
102 * on the value of the KeyPairAlgorithm parameter.
103 * @param[in] keyCurveId - The curve ID to be used with the key, if needed
104 * based on the value of the KeyPairAlgorithm parameter.
105 * @param[in] keyPairAlgorithm - The type of key pair for use with signing
106 * algorithms. Valid built-in algorithm names for private key
107 * generation are: RSA, DSA, DH and EC.
108 * @param[in] keyUsage - Key usage extensions define the purpose of the
109 * public key contained in a certificate. Valid Key usage extensions
110 * and its usage description.
111 * - ClientAuthentication: The public key is used for TLS WWW client
112 * authentication.
113 * - CodeSigning: The public key is used for the signing of executable
114 * code
115 * - CRLSigning: The public key is used for verifying signatures on
116 * certificate revocation lists (CLRs).
117 * - DataEncipherment: The public key is used for directly enciphering
118 * raw user data without the use of an intermediate symmetric
119 * cipher.
120 * - DecipherOnly: The public key could be used for deciphering data
121 * while performing key agreement.
122 * - DigitalSignature: The public key is used for verifying digital
123 * signatures, other than signatures on certificatesand CRLs.
124 * - EmailProtection: The public key is used for email protection.
125 * - EncipherOnly: Thepublic key could be used for enciphering data
126 * while performing key agreement.
127 * - KeyCertSign: The public key is used for verifying signatures on
128 * public key certificates.
129 * - KeyEncipherment: The public key is used for enciphering private or
130 * secret keys.
131 * - NonRepudiation: The public key is used to verify digital
132 * signatures, other than signatures on certificates and CRLs, and
133 * used to provide a non-repudiation service that protects against
134 * the signing entity falsely denying some action.
135 * - OCSPSigning: The public key is used for signing OCSP responses.
136 * - ServerAuthentication: The public key is used for TLS WWW server
137 * authentication.
138 * - Timestamping: The public key is used for binding the hash of an
139 * object to a time.
140 * @param[in] organization - The legal name of the organization. This
141 * should not be abbreviated and should include suffixes such as Inc,
142 * Corp, or LLC.For example, IBM Corp.
143 * @param[in] organizationalUnit - The name of the unit or division of the
144 * organization making the request.
145 * @param[in] state - The state or province where the organization is
146 * located. This should not be abbreviated. For example, Texas.
147 * @param[in] surname - The surname of the user making the request.
148 * @param[in] unstructuredName - The unstructured name of the subject.
149 *
150 * @return path[std::string] - The object path of the D-Bus object
151 * representing CSR string. Note: For new CSR request will overwrite
152 * the existing CSR in the system.
153 */
154 std::string generateCSR(
155 std::vector<std::string> alternativeNames,
156 std::string challengePassword, std::string city, std::string commonName,
157 std::string contactPerson, std::string country, std::string email,
158 std::string givenName, std::string initials, int64_t keyBitLength,
159 std::string keyCurveId, std::string keyPairAlgorithm,
160 std::vector<std::string> keyUsage, std::string organization,
161 std::string organizationalUnit, std::string state, std::string surname,
162 std::string unstructuredName) override;
163
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200164 /** @brief Get reference to certificates' collection
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500165 *
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200166 * @return Reference to certificates' collection
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500167 */
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200168 std::vector<std::unique_ptr<Certificate>>& getCertificates();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500169
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500170 private:
Marri Devender Raof4682712019-03-19 05:00:28 -0500171 void generateCSRHelper(std::vector<std::string> alternativeNames,
172 std::string challengePassword, std::string city,
173 std::string commonName, std::string contactPerson,
174 std::string country, std::string email,
175 std::string givenName, std::string initials,
176 int64_t keyBitLength, std::string keyCurveId,
177 std::string keyPairAlgorithm,
178 std::vector<std::string> keyUsage,
179 std::string organization,
180 std::string organizationalUnit, std::string state,
181 std::string surname, std::string unstructuredName);
182
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500183 /** @brief Generate RSA Key pair and get private key from key pair
184 * @param[in] keyBitLength - KeyBit length.
185 * @return Pointer to RSA private key
186 */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800187 std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>
188 generateRSAKeyPair(const int64_t keyBitLength);
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500189
190 /** @brief Generate EC Key pair and get private key from key pair
191 * @param[in] p_KeyCurveId - Curve ID
192 * @return Pointer to EC private key
193 */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800194 std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>
195 generateECKeyPair(const std::string& p_KeyCurveId);
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500196
Marri Devender Raof4682712019-03-19 05:00:28 -0500197 /** @brief Write private key data to file
198 *
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500199 * @param[in] pKey - pointer to private key
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500200 * @param[in] privKeyFileName - private key filename
Marri Devender Raof4682712019-03-19 05:00:28 -0500201 */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800202 void writePrivateKey(
203 const std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>& pKey,
204 const std::string& privKeyFileName);
Marri Devender Raof4682712019-03-19 05:00:28 -0500205
206 /** @brief Add the specified CSR field with the data
207 * @param[in] x509Name - Structure used in setting certificate properties
208 * @param[in] field - field name
209 * @param[in] bytes - field value in bytes
210 */
211 void addEntry(X509_NAME* x509Name, const char* field,
212 const std::string& bytes);
213
Marri Devender Rao76411052019-08-07 01:25:07 -0500214 /** @brief Check if usage is extended key usage
215 * @param[in] usage - key usage value
216 * @return true if part of extended key usage
217 */
218 bool isExtendedKeyUsage(const std::string& usage);
219
Marri Devender Raof4682712019-03-19 05:00:28 -0500220 /** @brief Create CSR D-Bus object by reading the data in the CSR file
Nan Zhoubf3cf752021-12-28 11:02:07 -0800221 * @param[in] statis - SUCCESS/FAILURE In CSR generation.
Marri Devender Raof4682712019-03-19 05:00:28 -0500222 */
223 void createCSRObject(const Status& status);
224
225 /** @brief Write generated CSR data to file
226 *
227 * @param[in] filePath - CSR file path.
228 * @param[in] x509Req - OpenSSL Request Pointer.
229 */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800230 void writeCSR(
231 const std::string& filePath,
232 const std::unique_ptr<X509_REQ, decltype(&::X509_REQ_free)>& x509Req);
Marri Devender Raof4682712019-03-19 05:00:28 -0500233
Nan Zhoubf3cf752021-12-28 11:02:07 -0800234 /** @brief Load certificate
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500235 * Load certificate and create certificate object
236 */
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200237 void createCertificates();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500238
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500239 /** @brief Create RSA private key file
240 * Create RSA private key file by generating rsa key if not created
241 */
242 void createRSAPrivateKeyFile();
243
244 /** @brief Getting RSA private key
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100245 * Getting RSA private key from generated file
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500246 * @param[in] keyBitLength - Key bit length
247 * @return Pointer to RSA key
248 */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800249 std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>
250 getRSAKeyPair(const int64_t keyBitLength);
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500251
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100252 /** @brief Update certificate storage (remove outdated files, recreate
253 * symbolic links, etc.).
254 */
255 void storageUpdate();
256
257 /** @brief Systemd unit reload or reset helper function
258 * Reload if the unit supports it and use a restart otherwise.
259 * @param[in] unit - service need to reload.
260 */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800261 void reloadOrReset(const std::string& unit);
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100262
263 /** @brief Check if provided certificate is unique across all certificates
264 * on the internal list.
265 * @param[in] certFilePath - Path to the file with certificate for
266 * uniqueness check.
267 * @param[in] certToDrop - Pointer to the certificate from the internal
268 * list which should be not taken into account while uniqueness check.
269 * @return Checking result. True if certificate is unique, false if
270 * not.
271 */
272 bool isCertificateUnique(const std::string& certFilePath,
273 const Certificate* const certToDrop = nullptr);
274
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500275 /** @brief sdbusplus handler */
276 sdbusplus::bus::bus& bus;
277
Marri Devender Raof4682712019-03-19 05:00:28 -0500278 // sdevent Event handle
279 sdeventplus::Event& event;
280
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500281 /** @brief object path */
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600282 std::string objectPath;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500283
284 /** @brief Type of the certificate **/
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600285 CertificateType certType;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500286
287 /** @brief Unit name associated to the service **/
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800288 std::string unitToRestart;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500289
290 /** @brief Certificate file installation path **/
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800291 std::string certInstallPath;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500292
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200293 /** @brief Collection of pointers to certificate */
294 std::vector<std::unique_ptr<Certificate>> installedCerts;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500295
Marri Devender Raof4682712019-03-19 05:00:28 -0500296 /** @brief pointer to CSR */
297 std::unique_ptr<CSR> csrPtr = nullptr;
298
299 /** @brief SDEventPlus child pointer added to event loop */
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500300 std::unique_ptr<sdeventplus::source::Child> childPtr = nullptr;
301
302 /** @brief Watch on self signed certificates */
303 std::unique_ptr<Watch> certWatchPtr = nullptr;
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500304
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100305 /** @brief Parent path i.e certificate directory path */
Nan Zhoucf06ccd2021-12-28 16:25:45 -0800306 std::filesystem::path certParentInstallPath;
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200307
308 /** @brief Certificate ID pool */
309 uint64_t certIdCounter = 1;
Marri Devender Raof4682712019-03-19 05:00:28 -0500310};
Nan Zhoue1289ad2021-12-28 11:02:56 -0800311} // namespace phosphor::certs