1 #pragma once 2 3 #include "watch.hpp" 4 5 #include <openssl/x509.h> 6 7 #include <filesystem> 8 #include <phosphor-logging/elog.hpp> 9 #include <xyz/openbmc_project/Certs/Certificate/server.hpp> 10 #include <xyz/openbmc_project/Certs/Replace/server.hpp> 11 #include <xyz/openbmc_project/Object/Delete/server.hpp> 12 13 namespace phosphor 14 { 15 namespace certs 16 { 17 using DeleteIface = sdbusplus::xyz::openbmc_project::Object::server::Delete; 18 using CertificateIface = 19 sdbusplus::xyz::openbmc_project::Certs::server::Certificate; 20 using ReplaceIface = sdbusplus::xyz::openbmc_project::Certs::server::Replace; 21 using CertIfaces = sdbusplus::server::object::object<CertificateIface, 22 ReplaceIface, DeleteIface>; 23 24 using CertificateType = std::string; 25 using CertInstallPath = std::string; 26 using CertUploadPath = std::string; 27 using InputType = std::string; 28 using InstallFunc = std::function<void(const std::string&)>; 29 using AppendPrivKeyFunc = std::function<void(const std::string&)>; 30 using CertWatchPtr = std::unique_ptr<Watch>; 31 using namespace phosphor::logging; 32 33 // for placeholders 34 using namespace std::placeholders; 35 namespace fs = std::filesystem; 36 37 class Manager; // Forward declaration for Certificate Manager. 38 39 // Supported Types. 40 static constexpr auto SERVER = "server"; 41 static constexpr auto CLIENT = "client"; 42 static constexpr auto AUTHORITY = "authority"; 43 44 // RAII support for openSSL functions. 45 using X509_Ptr = std::unique_ptr<X509, decltype(&::X509_free)>; 46 using X509_STORE_CTX_Ptr = 47 std::unique_ptr<X509_STORE_CTX, decltype(&::X509_STORE_CTX_free)>; 48 49 /** @class Certificate 50 * @brief OpenBMC Certificate entry implementation. 51 * @details A concrete implementation for the 52 * xyz.openbmc_project.Certs.Certificate DBus API 53 * xyz.openbmc_project.Certs.Instal DBus API 54 */ 55 class Certificate : public CertIfaces 56 { 57 public: 58 Certificate() = delete; 59 Certificate(const Certificate&) = delete; 60 Certificate& operator=(const Certificate&) = delete; 61 Certificate(Certificate&&) = delete; 62 Certificate& operator=(Certificate&&) = delete; 63 virtual ~Certificate(); 64 65 /** @brief Constructor for the Certificate Object 66 * @param[in] bus - Bus to attach to. 67 * @param[in] objPath - Object path to attach to 68 * @param[in] type - Type of the certificate 69 * @param[in] installPath - Path of the certificate to install 70 * @param[in] uploadPath - Path of the certificate file to upload 71 * @param[in] watchPtr - watch on self signed certificate pointer 72 */ 73 Certificate(sdbusplus::bus::bus& bus, const std::string& objPath, 74 const CertificateType& type, const CertInstallPath& installPath, 75 const CertUploadPath& uploadPath, const CertWatchPtr& watchPtr, 76 Manager& parent); 77 78 /** @brief Validate and Replace/Install the certificate file 79 * Install/Replace the existing certificate file with another 80 * (possibly CA signed) Certificate file. 81 * @param[in] filePath - Certificate file path. 82 */ 83 void install(const std::string& filePath); 84 85 /** @brief Validate certificate and replace the existing certificate 86 * @param[in] filePath - Certificate file path. 87 */ 88 void replace(const std::string filePath) override; 89 90 /** @brief Populate certificate properties by parsing certificate file 91 */ 92 void populateProperties(); 93 94 /** 95 * @brief Obtain certificate ID. 96 * 97 * @return Certificate ID. 98 */ 99 std::string getCertId() const; 100 101 /** 102 * @brief Check if provied certificate is the same as the current one. 103 * 104 * @param[in] certPath - File path for certificate to check. 105 * 106 * @return Checking result. Return true if certificates are the same, 107 * false if not. 108 */ 109 bool isSame(const std::string& certPath); 110 111 /** 112 * @brief Update certificate storage. 113 */ 114 void storageUpdate(); 115 116 /** 117 * @brief Delete the certificate 118 */ 119 void delete_() override; 120 121 private: 122 /** 123 * @brief Return error if ceritificate expiry date is gt 2038 124 * 125 * Parse the certificate and return error if certificate expiry date 126 * is gt 2038. 127 * 128 * @param[in] cert Reference to certificate object uploaded 129 * 130 * @return void 131 */ 132 void validateCertificateExpiryDate(const X509_Ptr& cert); 133 134 /** 135 * @brief Populate certificate properties by parsing given certificate file 136 * 137 * @param[in] certPath Path to certificate that should be parsed 138 * 139 * @return void 140 */ 141 void populateProperties(const std::string& certPath); 142 143 /** @brief Load Certificate file into the X509 structure. 144 * @param[in] filePath - Certificate and key full file path. 145 * @return pointer to the X509 structure. 146 */ 147 X509_Ptr loadCert(const std::string& filePath); 148 149 /** @brief Check and append private key to the certificate file 150 * If private key is not present in the certificate file append the 151 * certificate file with private key existing in the system. 152 * @param[in] filePath - Certificate and key full file path. 153 * @return void. 154 */ 155 void checkAndAppendPrivateKey(const std::string& filePath); 156 157 /** @brief Public/Private key compare function. 158 * Comparing private key against certificate public key 159 * from input .pem file. 160 * @param[in] filePath - Certificate and key full file path. 161 * @return Return true if Key compare is successful, 162 * false if not 163 */ 164 bool compareKeys(const std::string& filePath); 165 166 /** 167 * @brief Generate certificate ID based on provided certificate file. 168 * 169 * @param[in] certPath - Certificate file path. 170 * 171 * @return Certificate ID as formatted string. 172 */ 173 std::string generateCertId(const std::string& certPath); 174 175 /** 176 * @brief Generate file name which is unique in the provided directory. 177 * 178 * @param[in] directoryPath - Directory path. 179 * 180 * @return File path. 181 */ 182 std::string generateUniqueFilePath(const std::string& directoryPath); 183 184 /** 185 * @brief Generate authority certificate file path corresponding with 186 * OpenSSL requirements. 187 * 188 * Prepare authority certificate file path for provied certificate. 189 * OpenSSL puts some restrictions on the certificate file name pattern. 190 * Certificate full file name needs to consists of basic file name which 191 * is certificate subject name hash and file name extension which is an 192 * integer. More over, certificates files names extensions must be 193 * consecutive integer numbers in case many certificates with the same 194 * subject name. 195 * https://www.boost.org/doc/libs/1_69_0/doc/html/boost_asio/reference/ssl__context/add_verify_path.html 196 * https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_load_verify_locations.html 197 * 198 * @param[in] certSrcFilePath - Certificate source file path. 199 * @param[in] certDstDirPath - Certificate destination directory path. 200 * 201 * @return Authority certificate file path. 202 */ 203 std::string generateAuthCertFileX509Path(const std::string& certSrcFilePath, 204 const std::string& certDstDirPath); 205 206 /** 207 * @brief Generate authority certificate file path based on provided 208 * certificate source file path. 209 * 210 * @param[in] certSrcFilePath - Certificate source file path. 211 * 212 * @return Authority certificate file path. 213 */ 214 std::string generateAuthCertFilePath(const std::string& certSrcFilePath); 215 216 /** 217 * @brief Generate certificate file path based on provided certificate 218 * source file path. 219 * 220 * @param[in] certSrcFilePath - Certificate source file path. 221 * 222 * @return Certificate file path. 223 */ 224 std::string generateCertFilePath(const std::string& certSrcFilePath); 225 226 /** @brief Type specific function pointer map */ 227 std::unordered_map<InputType, InstallFunc> typeFuncMap; 228 229 /** @brief sdbusplus handler */ 230 sdbusplus::bus::bus& bus; 231 232 /** @brief object path */ 233 std::string objectPath; 234 235 /** @brief Type of the certificate */ 236 CertificateType certType; 237 238 /** @brief Stores certificate ID */ 239 std::string certId; 240 241 /** @brief Stores certificate file path */ 242 std::string certFilePath; 243 244 /** @brief Certificate file installation path */ 245 CertInstallPath certInstallPath; 246 247 /** @brief Type specific function pointer map for appending private key */ 248 std::unordered_map<InputType, AppendPrivKeyFunc> appendKeyMap; 249 250 /** @brief Certificate file create/update watch */ 251 const CertWatchPtr& certWatchPtr; 252 253 /** @brief Reference to Certificate Manager */ 254 Manager& manager; 255 }; 256 257 } // namespace certs 258 } // namespace phosphor 259