1 #pragma once 2 #include "config.h" 3 4 #include "certificate.hpp" 5 #include "csr.hpp" 6 #include "watch.hpp" 7 8 #include <filesystem> 9 #include <sdeventplus/source/child.hpp> 10 #include <sdeventplus/source/event.hpp> 11 #include <xyz/openbmc_project/Certs/CSR/Create/server.hpp> 12 #include <xyz/openbmc_project/Certs/Install/server.hpp> 13 #include <xyz/openbmc_project/Collection/DeleteAll/server.hpp> 14 15 namespace phosphor::certs 16 { 17 18 namespace internal 19 { 20 using 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 } 25 26 class Manager : public internal::ManagerInterface 27 { 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; 40 Manager(const Manager&) = delete; 41 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. 48 * @param[in] event - sd event handler. 49 * @param[in] path - Path to attach at. 50 * @param[in] type - Type of the certificate. 51 * @param[in] unit - Unit consumed by this certificate. 52 * @param[in] installPath - Certificate installation path. 53 */ 54 Manager(sdbusplus::bus::bus& bus, sdeventplus::Event& event, 55 const char* path, CertificateType type, const std::string& unit, 56 const std::string& installPath); 57 58 /** @brief Implementation for Install 59 * Replace the existing certificate key file with another 60 * (possibly CA signed) Certificate key file. 61 * 62 * @param[in] filePath - Certificate key file path. 63 * 64 * @return Certificate object path. 65 */ 66 std::string install(const std::string filePath) override; 67 68 /** @brief Implementation for DeleteAll 69 * Delete all objects in the collection. 70 */ 71 void deleteAll() override; 72 73 /** @brief Delete the certificate. 74 */ 75 void deleteCertificate(const Certificate* const certificate); 76 77 /** @brief Replace the certificate. 78 */ 79 void replaceCertificate(Certificate* const certificate, 80 const std::string& filePath); 81 82 /** @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 164 /** @brief Get reference to certificates' collection 165 * 166 * @return Reference to certificates' collection 167 */ 168 std::vector<std::unique_ptr<Certificate>>& getCertificates(); 169 170 private: 171 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 183 /** @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 */ 187 std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)> 188 generateRSAKeyPair(const int64_t keyBitLength); 189 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 */ 194 std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)> 195 generateECKeyPair(const std::string& p_KeyCurveId); 196 197 /** @brief Write private key data to file 198 * 199 * @param[in] pKey - pointer to private key 200 * @param[in] privKeyFileName - private key filename 201 */ 202 void writePrivateKey( 203 const std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>& pKey, 204 const std::string& privKeyFileName); 205 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 214 /** @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 220 /** @brief Create CSR D-Bus object by reading the data in the CSR file 221 * @param[in] statis - SUCCESS/FAILURE In CSR generation. 222 */ 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 */ 230 void writeCSR( 231 const std::string& filePath, 232 const std::unique_ptr<X509_REQ, decltype(&::X509_REQ_free)>& x509Req); 233 234 /** @brief Load certificate 235 * Load certificate and create certificate object 236 */ 237 void createCertificates(); 238 239 /** @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 245 * Getting RSA private key from generated file 246 * @param[in] keyBitLength - Key bit length 247 * @return Pointer to RSA key 248 */ 249 std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)> 250 getRSAKeyPair(const int64_t keyBitLength); 251 252 /** @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 */ 261 void reloadOrReset(const std::string& unit); 262 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 275 /** @brief sdbusplus handler */ 276 sdbusplus::bus::bus& bus; 277 278 // sdevent Event handle 279 sdeventplus::Event& event; 280 281 /** @brief object path */ 282 std::string objectPath; 283 284 /** @brief Type of the certificate **/ 285 CertificateType certType; 286 287 /** @brief Unit name associated to the service **/ 288 std::string unitToRestart; 289 290 /** @brief Certificate file installation path **/ 291 std::string certInstallPath; 292 293 /** @brief Collection of pointers to certificate */ 294 std::vector<std::unique_ptr<Certificate>> installedCerts; 295 296 /** @brief pointer to CSR */ 297 std::unique_ptr<CSR> csrPtr = nullptr; 298 299 /** @brief SDEventPlus child pointer added to event loop */ 300 std::unique_ptr<sdeventplus::source::Child> childPtr = nullptr; 301 302 /** @brief Watch on self signed certificates */ 303 std::unique_ptr<Watch> certWatchPtr = nullptr; 304 305 /** @brief Parent path i.e certificate directory path */ 306 std::filesystem::path certParentInstallPath; 307 308 /** @brief Certificate ID pool */ 309 uint64_t certIdCounter = 1; 310 }; 311 } // namespace phosphor::certs 312