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