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