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