1 #pragma once
2 #include "config.h"
3 
4 #include "certificate.hpp"
5 #include "csr.hpp"
6 #include "watch.hpp"
7 
8 #include <sdeventplus/source/child.hpp>
9 #include <sdeventplus/source/event.hpp>
10 #include <xyz/openbmc_project/Certs/CSR/Create/server.hpp>
11 #include <xyz/openbmc_project/Certs/Install/server.hpp>
12 #include <xyz/openbmc_project/Collection/DeleteAll/server.hpp>
13 
14 namespace phosphor
15 {
16 namespace certs
17 {
18 using Install = sdbusplus::xyz::openbmc_project::Certs::server::Install;
19 using DeleteAll =
20     sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll;
21 using CSRCreate = sdbusplus::xyz::openbmc_project::Certs::CSR::server::Create;
22 using Ifaces = sdbusplus::server::object::object<Install, CSRCreate, DeleteAll>;
23 
24 using X509_REQ_Ptr = std::unique_ptr<X509_REQ, decltype(&::X509_REQ_free)>;
25 using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
26 using CertificatePtr = std::unique_ptr<Certificate>;
27 
28 using UnitsToRestart = std::string;
29 
30 class Manager : public Ifaces
31 {
32   public:
33     /* Define all of the basic class operations:
34      *     Not allowed:
35      *         - Default constructor is not possible due to member
36      *           reference
37      *         - Move operations due to 'this' being registered as the
38      *           'context' with sdbus.
39      *     Allowed:
40      *         - copy
41      *         - Destructor.
42      */
43     Manager() = delete;
44     Manager(const Manager&) = default;
45     Manager& operator=(const Manager&) = delete;
46     Manager(Manager&&) = delete;
47     Manager& operator=(Manager&&) = delete;
48     virtual ~Manager() = default;
49 
50     /** @brief Constructor to put object onto bus at a dbus path.
51      *  @param[in] bus - Bus to attach to.
52      *  @param[in] event - sd event handler.
53      *  @param[in] path - Path to attach at.
54      *  @param[in] type - Type of the certificate.
55      *  @param[in] unit - Unit consumed by this certificate.
56      *  @param[in] installPath - Certificate installation path.
57      */
58     Manager(sdbusplus::bus::bus& bus, sdeventplus::Event& event,
59             const char* path, const CertificateType& type,
60             UnitsToRestart&& unit, CertInstallPath&& installPath);
61 
62     /** @brief Implementation for Install
63      *  Replace the existing certificate key file with another
64      *  (possibly CA signed) Certificate key file.
65      *
66      *  @param[in] filePath - Certificate key file path.
67      *
68      *  @return Certificate object path.
69      */
70     std::string install(const std::string filePath) override;
71 
72     /** @brief Implementation for DeleteAll
73      *  Delete all objects in the collection.
74      */
75     void deleteAll() override;
76 
77     /** @brief Delete the certificate.
78      */
79     void deleteCertificate(const Certificate* const certificate);
80 
81     /** @brief Replace the certificate.
82      */
83     void replaceCertificate(Certificate* const certificate,
84                             const std::string& filePath);
85 
86     /** @brief Generate Private key and CSR file
87      *  Generates the Private key file and CSR file based on the input
88      *  parameters. Validation of the parameters is callers responsibility.
89      *  At present supports only RSA algorithm type
90      *
91      *  @param[in] alternativeNames - Additional hostnames of the component that
92      *      is being secured.
93      *  @param[in] challengePassword - The challenge password to be applied to
94      *      the certificate for revocation requests.
95      *  @param[in] city - The city or locality of the organization making the
96      *      request. For Example Austin
97      *  @param[in] commonName - The fully qualified domain name of the component
98      *      that is being secured.
99      *  @param[in] contactPerson - The name of the user making the request.
100      *  @param[in] country - The country of the organization making the request.
101      *  @param[in] email - The email address of the contact within the
102      *      organization making the request.
103      *  @param[in] givenName - The given name of the user making the request.
104      *  @param[in] initials - The initials of the user making the request.
105      *  @param[in] keyBitLength - The length of the key in bits, if needed based
106      *      on the value of the KeyPairAlgorithm parameter.
107      *  @param[in] keyCurveId - The curve ID to be used with the key, if needed
108      *      based on the value of the KeyPairAlgorithm parameter.
109      *  @param[in] keyPairAlgorithm - The type of key pair for use with signing
110      *      algorithms. Valid built-in algorithm names for private key
111      *      generation are: RSA, DSA, DH and EC.
112      *  @param[in] keyUsage - Key usage extensions define the purpose of the
113      *      public key contained in a certificate. Valid Key usage extensions
114      *      and its usage description.
115      *      - ClientAuthentication: The public key is used for TLS WWW client
116      *      authentication.
117      *      - CodeSigning: The public key is used for the signing of executable
118      *          code
119      *      - CRLSigning: The public key is used for verifying signatures on
120      *          certificate revocation lists (CLRs).
121      *      - DataEncipherment: The public key is used for directly enciphering
122      *          raw user data without the use of an intermediate symmetric
123      *          cipher.
124      *      - DecipherOnly: The public key could be used for deciphering data
125      *          while performing key agreement.
126      *      - DigitalSignature: The public key is used for verifying digital
127      *          signatures, other than signatures on certificatesand CRLs.
128      *      - EmailProtection: The public key is used for email protection.
129      *      - EncipherOnly: Thepublic key could be used for enciphering data
130      *          while performing key agreement.
131      *      - KeyCertSign: The public key is used for verifying signatures on
132      *          public key certificates.
133      *      - KeyEncipherment: The public key is used for enciphering private or
134      *          secret keys.
135      *      - NonRepudiation: The public key is used to verify digital
136      *          signatures, other than signatures on certificates and CRLs, and
137      *          used to provide a non-repudiation service that protects against
138      *          the signing entity falsely denying some action.
139      *      - OCSPSigning: The public key is used for signing OCSP responses.
140      *      - ServerAuthentication: The public key is used for TLS WWW server
141      *          authentication.
142      *      - Timestamping: The public key is used for binding the hash of an
143      *          object to a time.
144      *  @param[in] organization - The legal name of the organization. This
145      *      should not be abbreviated and should include suffixes such as Inc,
146      *      Corp, or LLC.For example, IBM Corp.
147      *  @param[in] organizationalUnit - The name of the unit or division of the
148      *      organization making the request.
149      *  @param[in] state - The state or province where the organization is
150      *      located. This should not be abbreviated. For example, Texas.
151      *  @param[in] surname - The surname of the user making the request.
152      *  @param[in] unstructuredName - The unstructured name of the subject.
153      *
154      *  @return path[std::string] - The object path of the D-Bus object
155      *      representing CSR string. Note: For new CSR request will overwrite
156      * the existing CSR in the system.
157      */
158     std::string generateCSR(
159         std::vector<std::string> alternativeNames,
160         std::string challengePassword, std::string city, std::string commonName,
161         std::string contactPerson, std::string country, std::string email,
162         std::string givenName, std::string initials, int64_t keyBitLength,
163         std::string keyCurveId, std::string keyPairAlgorithm,
164         std::vector<std::string> keyUsage, std::string organization,
165         std::string organizationalUnit, std::string state, std::string surname,
166         std::string unstructuredName) override;
167 
168     /** @brief Get reference to certificates' collection
169      *
170      *  @return Reference to certificates' collection
171      */
172     std::vector<std::unique_ptr<Certificate>>& getCertificates();
173 
174   private:
175     void generateCSRHelper(std::vector<std::string> alternativeNames,
176                            std::string challengePassword, std::string city,
177                            std::string commonName, std::string contactPerson,
178                            std::string country, std::string email,
179                            std::string givenName, std::string initials,
180                            int64_t keyBitLength, std::string keyCurveId,
181                            std::string keyPairAlgorithm,
182                            std::vector<std::string> keyUsage,
183                            std::string organization,
184                            std::string organizationalUnit, std::string state,
185                            std::string surname, std::string unstructuredName);
186 
187     /** @brief Generate RSA Key pair and get private key from key pair
188      *  @param[in]  keyBitLength - KeyBit length.
189      *  @return     Pointer to RSA private key
190      */
191     EVP_PKEY_Ptr generateRSAKeyPair(const int64_t keyBitLength);
192 
193     /** @brief Generate EC Key pair and get private key from key pair
194      *  @param[in]  p_KeyCurveId - Curve ID
195      *  @return     Pointer to EC private key
196      */
197     EVP_PKEY_Ptr generateECKeyPair(const std::string& p_KeyCurveId);
198 
199     /** @brief Write private key data to file
200      *
201      *  @param[in] pKey     - pointer to private key
202      *  @param[in] privKeyFileName - private key filename
203      */
204     void writePrivateKey(const EVP_PKEY_Ptr& pKey,
205                          const std::string& privKeyFileName);
206 
207     /** @brief Add the specified CSR field with the data
208      *  @param[in] x509Name - Structure used in setting certificate properties
209      *  @param[in] field - field name
210      *  @param[in] bytes - field value in bytes
211      */
212     void addEntry(X509_NAME* x509Name, const char* field,
213                   const std::string& bytes);
214 
215     /** @brief Check if usage is extended key usage
216      *  @param[in] usage - key usage value
217      *  @return true if part of extended key usage
218      */
219     bool isExtendedKeyUsage(const std::string& usage);
220 
221     /** @brief Create CSR D-Bus object by reading the data in the CSR file
222      *  @param[in] statis - SUCCESSS/FAILURE In CSR generation.
223      */
224     void createCSRObject(const Status& status);
225 
226     /** @brief Write generated CSR data to file
227      *
228      *  @param[in] filePath - CSR file path.
229      *  @param[in] x509Req - OpenSSL Request Pointer.
230      */
231     void writeCSR(const std::string& filePath, const X509_REQ_Ptr& x509Req);
232 
233     /** @brief Load certifiate
234      *  Load certificate and create certificate object
235      */
236     void createCertificates();
237 
238     /** @brief Create RSA private key file
239      *  Create RSA private key file by generating rsa key if not created
240      */
241     void createRSAPrivateKeyFile();
242 
243     /** @brief Getting RSA private key
244      *  Getting RSA private key from generated file
245      *  @param[in]  keyBitLength - Key bit length
246      *  @return     Pointer to RSA key
247      */
248     EVP_PKEY_Ptr getRSAKeyPair(const int64_t keyBitLength);
249 
250     /** @brief Update certificate storage (remove outdated files, recreate
251      * symbolic links, etc.).
252      */
253     void storageUpdate();
254 
255     /** @brief Systemd unit reload or reset helper function
256      *  Reload if the unit supports it and use a restart otherwise.
257      *  @param[in] unit - service need to reload.
258      */
259     void reloadOrReset(const UnitsToRestart& unit);
260 
261     /** @brief Check if provided certificate is unique across all certificates
262      * on the internal list.
263      *  @param[in] certFilePath - Path to the file with certificate for
264      * uniqueness check.
265      *  @param[in] certToDrop - Pointer to the certificate from the internal
266      * list which should be not taken into account while uniqueness check.
267      *  @return     Checking result. True if certificate is unique, false if
268      * not.
269      */
270     bool isCertificateUnique(const std::string& certFilePath,
271                              const Certificate* const certToDrop = nullptr);
272 
273     /** @brief sdbusplus handler */
274     sdbusplus::bus::bus& bus;
275 
276     // sdevent Event handle
277     sdeventplus::Event& event;
278 
279     /** @brief object path */
280     std::string objectPath;
281 
282     /** @brief Type of the certificate **/
283     CertificateType certType;
284 
285     /** @brief Unit name associated to the service **/
286     UnitsToRestart unitToRestart;
287 
288     /** @brief Certificate file installation path **/
289     CertInstallPath certInstallPath;
290 
291     /** @brief Collection of pointers to certificate */
292     std::vector<std::unique_ptr<Certificate>> installedCerts;
293 
294     /** @brief pointer to CSR */
295     std::unique_ptr<CSR> csrPtr = nullptr;
296 
297     /** @brief SDEventPlus child pointer added to event loop */
298     std::unique_ptr<sdeventplus::source::Child> childPtr = nullptr;
299 
300     /** @brief Watch on self signed certificates */
301     std::unique_ptr<Watch> certWatchPtr = nullptr;
302 
303     /** @brief Parent path i.e certificate directory path */
304     fs::path certParentInstallPath;
305 
306     /** @brief Certificate ID pool */
307     uint64_t certIdCounter = 1;
308 };
309 } // namespace certs
310 } // namespace phosphor
311