blob: 2be0759c3ff9e274429b1de131bf2755e5449e5e [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
8#include <sdeventplus/source/child.hpp>
9#include <sdeventplus/source/event.hpp>
10#include <xyz/openbmc_project/Certs/CSR/Create/server.hpp>
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050011#include <xyz/openbmc_project/Certs/Install/server.hpp>
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020012#include <xyz/openbmc_project/Collection/DeleteAll/server.hpp>
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050013
Nan Zhoue1289ad2021-12-28 11:02:56 -080014namespace phosphor::certs
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050015{
Marri Devender Raof4682712019-03-19 05:00:28 -050016using Install = sdbusplus::xyz::openbmc_project::Certs::server::Install;
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020017using DeleteAll =
18 sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll;
Marri Devender Raof4682712019-03-19 05:00:28 -050019using CSRCreate = sdbusplus::xyz::openbmc_project::Certs::CSR::server::Create;
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020020using Ifaces = sdbusplus::server::object::object<Install, CSRCreate, DeleteAll>;
Marri Devender Raof4682712019-03-19 05:00:28 -050021
22using X509_REQ_Ptr = std::unique_ptr<X509_REQ, decltype(&::X509_REQ_free)>;
23using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050024using CertificatePtr = std::unique_ptr<Certificate>;
Jayanth Othayothb50789c2018-10-09 07:13:54 -050025
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010026using UnitsToRestart = std::string;
27
Deepak Kodihalliae70b3d2018-09-30 05:42:00 -050028class Manager : public Ifaces
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050029{
30 public:
31 /* Define all of the basic class operations:
32 * Not allowed:
33 * - Default constructor is not possible due to member
34 * reference
35 * - Move operations due to 'this' being registered as the
36 * 'context' with sdbus.
37 * Allowed:
38 * - copy
39 * - Destructor.
40 */
41 Manager() = delete;
42 Manager(const Manager&) = default;
43 Manager& operator=(const Manager&) = delete;
44 Manager(Manager&&) = delete;
45 Manager& operator=(Manager&&) = delete;
46 virtual ~Manager() = default;
47
48 /** @brief Constructor to put object onto bus at a dbus path.
49 * @param[in] bus - Bus to attach to.
Marri Devender Raof4682712019-03-19 05:00:28 -050050 * @param[in] event - sd event handler.
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050051 * @param[in] path - Path to attach at.
52 * @param[in] type - Type of the certificate.
53 * @param[in] unit - Unit consumed by this certificate.
Marri Devender Rao6ceec402019-02-01 03:15:19 -060054 * @param[in] installPath - Certificate installation path.
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050055 */
Marri Devender Raof4682712019-03-19 05:00:28 -050056 Manager(sdbusplus::bus::bus& bus, sdeventplus::Event& event,
57 const char* path, const CertificateType& type,
58 UnitsToRestart&& unit, CertInstallPath&& installPath);
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050059
60 /** @brief Implementation for Install
61 * Replace the existing certificate key file with another
62 * (possibly CA signed) Certificate key file.
63 *
Marri Devender Rao6ceec402019-02-01 03:15:19 -060064 * @param[in] filePath - Certificate key file path.
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010065 *
66 * @return Certificate object path.
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050067 */
Zbigniew Kurzynski06a69d72019-09-27 10:57:38 +020068 std::string install(const std::string filePath) override;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -050069
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020070 /** @brief Implementation for DeleteAll
71 * Delete all objects in the collection.
Deepak Kodihalliae70b3d2018-09-30 05:42:00 -050072 */
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020073 void deleteAll() override;
74
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010075 /** @brief Delete the certificate.
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +020076 */
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +010077 void deleteCertificate(const Certificate* const certificate);
78
79 /** @brief Replace the certificate.
80 */
81 void replaceCertificate(Certificate* const certificate,
82 const std::string& filePath);
Deepak Kodihalliae70b3d2018-09-30 05:42:00 -050083
Marri Devender Raof4682712019-03-19 05:00:28 -050084 /** @brief Generate Private key and CSR file
85 * Generates the Private key file and CSR file based on the input
86 * parameters. Validation of the parameters is callers responsibility.
87 * At present supports only RSA algorithm type
88 *
89 * @param[in] alternativeNames - Additional hostnames of the component that
90 * is being secured.
91 * @param[in] challengePassword - The challenge password to be applied to
92 * the certificate for revocation requests.
93 * @param[in] city - The city or locality of the organization making the
94 * request. For Example Austin
95 * @param[in] commonName - The fully qualified domain name of the component
96 * that is being secured.
97 * @param[in] contactPerson - The name of the user making the request.
98 * @param[in] country - The country of the organization making the request.
99 * @param[in] email - The email address of the contact within the
100 * organization making the request.
101 * @param[in] givenName - The given name of the user making the request.
102 * @param[in] initials - The initials of the user making the request.
103 * @param[in] keyBitLength - The length of the key in bits, if needed based
104 * on the value of the KeyPairAlgorithm parameter.
105 * @param[in] keyCurveId - The curve ID to be used with the key, if needed
106 * based on the value of the KeyPairAlgorithm parameter.
107 * @param[in] keyPairAlgorithm - The type of key pair for use with signing
108 * algorithms. Valid built-in algorithm names for private key
109 * generation are: RSA, DSA, DH and EC.
110 * @param[in] keyUsage - Key usage extensions define the purpose of the
111 * public key contained in a certificate. Valid Key usage extensions
112 * and its usage description.
113 * - ClientAuthentication: The public key is used for TLS WWW client
114 * authentication.
115 * - CodeSigning: The public key is used for the signing of executable
116 * code
117 * - CRLSigning: The public key is used for verifying signatures on
118 * certificate revocation lists (CLRs).
119 * - DataEncipherment: The public key is used for directly enciphering
120 * raw user data without the use of an intermediate symmetric
121 * cipher.
122 * - DecipherOnly: The public key could be used for deciphering data
123 * while performing key agreement.
124 * - DigitalSignature: The public key is used for verifying digital
125 * signatures, other than signatures on certificatesand CRLs.
126 * - EmailProtection: The public key is used for email protection.
127 * - EncipherOnly: Thepublic key could be used for enciphering data
128 * while performing key agreement.
129 * - KeyCertSign: The public key is used for verifying signatures on
130 * public key certificates.
131 * - KeyEncipherment: The public key is used for enciphering private or
132 * secret keys.
133 * - NonRepudiation: The public key is used to verify digital
134 * signatures, other than signatures on certificates and CRLs, and
135 * used to provide a non-repudiation service that protects against
136 * the signing entity falsely denying some action.
137 * - OCSPSigning: The public key is used for signing OCSP responses.
138 * - ServerAuthentication: The public key is used for TLS WWW server
139 * authentication.
140 * - Timestamping: The public key is used for binding the hash of an
141 * object to a time.
142 * @param[in] organization - The legal name of the organization. This
143 * should not be abbreviated and should include suffixes such as Inc,
144 * Corp, or LLC.For example, IBM Corp.
145 * @param[in] organizationalUnit - The name of the unit or division of the
146 * organization making the request.
147 * @param[in] state - The state or province where the organization is
148 * located. This should not be abbreviated. For example, Texas.
149 * @param[in] surname - The surname of the user making the request.
150 * @param[in] unstructuredName - The unstructured name of the subject.
151 *
152 * @return path[std::string] - The object path of the D-Bus object
153 * representing CSR string. Note: For new CSR request will overwrite
154 * the existing CSR in the system.
155 */
156 std::string generateCSR(
157 std::vector<std::string> alternativeNames,
158 std::string challengePassword, std::string city, std::string commonName,
159 std::string contactPerson, std::string country, std::string email,
160 std::string givenName, std::string initials, int64_t keyBitLength,
161 std::string keyCurveId, std::string keyPairAlgorithm,
162 std::vector<std::string> keyUsage, std::string organization,
163 std::string organizationalUnit, std::string state, std::string surname,
164 std::string unstructuredName) override;
165
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200166 /** @brief Get reference to certificates' collection
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500167 *
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200168 * @return Reference to certificates' collection
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500169 */
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200170 std::vector<std::unique_ptr<Certificate>>& getCertificates();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500171
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500172 private:
Marri Devender Raof4682712019-03-19 05:00:28 -0500173 void generateCSRHelper(std::vector<std::string> alternativeNames,
174 std::string challengePassword, std::string city,
175 std::string commonName, std::string contactPerson,
176 std::string country, std::string email,
177 std::string givenName, std::string initials,
178 int64_t keyBitLength, std::string keyCurveId,
179 std::string keyPairAlgorithm,
180 std::vector<std::string> keyUsage,
181 std::string organization,
182 std::string organizationalUnit, std::string state,
183 std::string surname, std::string unstructuredName);
184
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500185 /** @brief Generate RSA Key pair and get private key from key pair
186 * @param[in] keyBitLength - KeyBit length.
187 * @return Pointer to RSA private key
188 */
189 EVP_PKEY_Ptr generateRSAKeyPair(const int64_t keyBitLength);
190
191 /** @brief Generate EC Key pair and get private key from key pair
192 * @param[in] p_KeyCurveId - Curve ID
193 * @return Pointer to EC private key
194 */
195 EVP_PKEY_Ptr generateECKeyPair(const std::string& p_KeyCurveId);
196
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 */
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500202 void writePrivateKey(const EVP_PKEY_Ptr& pKey,
203 const std::string& privKeyFileName);
Marri Devender Raof4682712019-03-19 05:00:28 -0500204
205 /** @brief Add the specified CSR field with the data
206 * @param[in] x509Name - Structure used in setting certificate properties
207 * @param[in] field - field name
208 * @param[in] bytes - field value in bytes
209 */
210 void addEntry(X509_NAME* x509Name, const char* field,
211 const std::string& bytes);
212
Marri Devender Rao76411052019-08-07 01:25:07 -0500213 /** @brief Check if usage is extended key usage
214 * @param[in] usage - key usage value
215 * @return true if part of extended key usage
216 */
217 bool isExtendedKeyUsage(const std::string& usage);
218
Marri Devender Raof4682712019-03-19 05:00:28 -0500219 /** @brief Create CSR D-Bus object by reading the data in the CSR file
Nan Zhoubf3cf752021-12-28 11:02:07 -0800220 * @param[in] statis - SUCCESS/FAILURE In CSR generation.
Marri Devender Raof4682712019-03-19 05:00:28 -0500221 */
222 void createCSRObject(const Status& status);
223
224 /** @brief Write generated CSR data to file
225 *
226 * @param[in] filePath - CSR file path.
227 * @param[in] x509Req - OpenSSL Request Pointer.
228 */
229 void writeCSR(const std::string& filePath, const X509_REQ_Ptr& x509Req);
230
Nan Zhoubf3cf752021-12-28 11:02:07 -0800231 /** @brief Load certificate
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500232 * Load certificate and create certificate object
233 */
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200234 void createCertificates();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500235
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500236 /** @brief Create RSA private key file
237 * Create RSA private key file by generating rsa key if not created
238 */
239 void createRSAPrivateKeyFile();
240
241 /** @brief Getting RSA private key
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100242 * Getting RSA private key from generated file
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500243 * @param[in] keyBitLength - Key bit length
244 * @return Pointer to RSA key
245 */
246 EVP_PKEY_Ptr getRSAKeyPair(const int64_t keyBitLength);
247
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100248 /** @brief Update certificate storage (remove outdated files, recreate
249 * symbolic links, etc.).
250 */
251 void storageUpdate();
252
253 /** @brief Systemd unit reload or reset helper function
254 * Reload if the unit supports it and use a restart otherwise.
255 * @param[in] unit - service need to reload.
256 */
257 void reloadOrReset(const UnitsToRestart& unit);
258
259 /** @brief Check if provided certificate is unique across all certificates
260 * on the internal list.
261 * @param[in] certFilePath - Path to the file with certificate for
262 * uniqueness check.
263 * @param[in] certToDrop - Pointer to the certificate from the internal
264 * list which should be not taken into account while uniqueness check.
265 * @return Checking result. True if certificate is unique, false if
266 * not.
267 */
268 bool isCertificateUnique(const std::string& certFilePath,
269 const Certificate* const certToDrop = nullptr);
270
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500271 /** @brief sdbusplus handler */
272 sdbusplus::bus::bus& bus;
273
Marri Devender Raof4682712019-03-19 05:00:28 -0500274 // sdevent Event handle
275 sdeventplus::Event& event;
276
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500277 /** @brief object path */
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600278 std::string objectPath;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500279
280 /** @brief Type of the certificate **/
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600281 CertificateType certType;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500282
283 /** @brief Unit name associated to the service **/
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600284 UnitsToRestart unitToRestart;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500285
286 /** @brief Certificate file installation path **/
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600287 CertInstallPath certInstallPath;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500288
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200289 /** @brief Collection of pointers to certificate */
290 std::vector<std::unique_ptr<Certificate>> installedCerts;
Jayanth Othayothcfbc8dc2018-09-03 07:22:27 -0500291
Marri Devender Raof4682712019-03-19 05:00:28 -0500292 /** @brief pointer to CSR */
293 std::unique_ptr<CSR> csrPtr = nullptr;
294
295 /** @brief SDEventPlus child pointer added to event loop */
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500296 std::unique_ptr<sdeventplus::source::Child> childPtr = nullptr;
297
298 /** @brief Watch on self signed certificates */
299 std::unique_ptr<Watch> certWatchPtr = nullptr;
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500300
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100301 /** @brief Parent path i.e certificate directory path */
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500302 fs::path certParentInstallPath;
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200303
304 /** @brief Certificate ID pool */
305 uint64_t certIdCounter = 1;
Marri Devender Raof4682712019-03-19 05:00:28 -0500306};
Nan Zhoue1289ad2021-12-28 11:02:56 -0800307} // namespace phosphor::certs