16ceec40bSMarri Devender Rao #pragma once
26ceec40bSMarri Devender Rao
3ffad1ef1SMarri Devender Rao #include "watch.hpp"
4ffad1ef1SMarri Devender Rao
5014be0bfSNan Zhou #include <openssl/ossl_typ.h>
66ceec40bSMarri Devender Rao #include <openssl/x509.h>
76ceec40bSMarri Devender Rao
8014be0bfSNan Zhou #include <sdbusplus/server/object.hpp>
9edd1131cSMarri Devender Rao #include <xyz/openbmc_project/Certs/Certificate/server.hpp>
1013bf74e4SMarri Devender Rao #include <xyz/openbmc_project/Certs/Replace/server.hpp>
11a3bb38fbSZbigniew Kurzynski #include <xyz/openbmc_project/Object/Delete/server.hpp>
126ceec40bSMarri Devender Rao
13*223e4604SPatrick Williams #include <functional>
14*223e4604SPatrick Williams #include <memory>
15*223e4604SPatrick Williams #include <string>
16*223e4604SPatrick Williams #include <string_view>
17*223e4604SPatrick Williams #include <unordered_map>
18*223e4604SPatrick Williams
19e1289adfSNan Zhou namespace phosphor::certs
206ceec40bSMarri Devender Rao {
21edd1131cSMarri Devender Rao
22cf06ccdcSNan Zhou // Certificate types
23cf06ccdcSNan Zhou enum class CertificateType
24cf06ccdcSNan Zhou {
25e3d47cd4SNan Zhou authority,
26e3d47cd4SNan Zhou server,
27e3d47cd4SNan Zhou client,
28e3d47cd4SNan Zhou unsupported,
29cf06ccdcSNan Zhou };
30cf06ccdcSNan Zhou
certificateTypeToString(CertificateType type)31cf06ccdcSNan Zhou inline constexpr const char* certificateTypeToString(CertificateType type)
32cf06ccdcSNan Zhou {
33cf06ccdcSNan Zhou switch (type)
34cf06ccdcSNan Zhou {
35e3d47cd4SNan Zhou case CertificateType::authority:
36cf06ccdcSNan Zhou return "authority";
37e3d47cd4SNan Zhou case CertificateType::server:
38cf06ccdcSNan Zhou return "server";
39e3d47cd4SNan Zhou case CertificateType::client:
40cf06ccdcSNan Zhou return "client";
41cf06ccdcSNan Zhou default:
42cf06ccdcSNan Zhou return "unsupported";
43cf06ccdcSNan Zhou }
44cf06ccdcSNan Zhou }
45cf06ccdcSNan Zhou
stringToCertificateType(std::string_view type)46cf06ccdcSNan Zhou inline constexpr CertificateType stringToCertificateType(std::string_view type)
47cf06ccdcSNan Zhou {
48cf06ccdcSNan Zhou if (type == "authority")
49cf06ccdcSNan Zhou {
50e3d47cd4SNan Zhou return CertificateType::authority;
51cf06ccdcSNan Zhou }
52cf06ccdcSNan Zhou if (type == "server")
53cf06ccdcSNan Zhou {
54e3d47cd4SNan Zhou return CertificateType::server;
55cf06ccdcSNan Zhou }
56cf06ccdcSNan Zhou if (type == "client")
57cf06ccdcSNan Zhou {
58e3d47cd4SNan Zhou return CertificateType::client;
59cf06ccdcSNan Zhou }
60e3d47cd4SNan Zhou return CertificateType::unsupported;
61cf06ccdcSNan Zhou }
62cf06ccdcSNan Zhou
63cf06ccdcSNan Zhou namespace internal
64cf06ccdcSNan Zhou {
65cf06ccdcSNan Zhou using CertificateInterface = sdbusplus::server::object_t<
66cf06ccdcSNan Zhou sdbusplus::xyz::openbmc_project::Certs::server::Certificate,
67cf06ccdcSNan Zhou sdbusplus::xyz::openbmc_project::Certs::server::Replace,
68cf06ccdcSNan Zhou sdbusplus::xyz::openbmc_project::Object::server::Delete>;
696ceec40bSMarri Devender Rao using InstallFunc = std::function<void(const std::string&)>;
70cd30c496SMarri Devender Rao using AppendPrivKeyFunc = std::function<void(const std::string&)>;
71cf06ccdcSNan Zhou using X509Ptr = std::unique_ptr<X509, decltype(&::X509_free)>;
72cf06ccdcSNan Zhou } // namespace internal
736ceec40bSMarri Devender Rao
74a3bb38fbSZbigniew Kurzynski class Manager; // Forward declaration for Certificate Manager.
75a3bb38fbSZbigniew Kurzynski
766ceec40bSMarri Devender Rao /** @class Certificate
776ceec40bSMarri Devender Rao * @brief OpenBMC Certificate entry implementation.
786ceec40bSMarri Devender Rao * @details A concrete implementation for the
796ceec40bSMarri Devender Rao * xyz.openbmc_project.Certs.Certificate DBus API
80bf3cf751SNan Zhou * xyz.openbmc_project.Certs.Install DBus API
816ceec40bSMarri Devender Rao */
82cf06ccdcSNan Zhou class Certificate : public internal::CertificateInterface
836ceec40bSMarri Devender Rao {
846ceec40bSMarri Devender Rao public:
856ceec40bSMarri Devender Rao Certificate() = delete;
866ceec40bSMarri Devender Rao Certificate(const Certificate&) = delete;
876ceec40bSMarri Devender Rao Certificate& operator=(const Certificate&) = delete;
886ceec40bSMarri Devender Rao Certificate(Certificate&&) = delete;
896ceec40bSMarri Devender Rao Certificate& operator=(Certificate&&) = delete;
906ceec40bSMarri Devender Rao virtual ~Certificate();
916ceec40bSMarri Devender Rao
926ceec40bSMarri Devender Rao /** @brief Constructor for the Certificate Object
936ceec40bSMarri Devender Rao * @param[in] bus - Bus to attach to.
946ceec40bSMarri Devender Rao * @param[in] objPath - Object path to attach to
956ceec40bSMarri Devender Rao * @param[in] type - Type of the certificate
966ceec40bSMarri Devender Rao * @param[in] installPath - Path of the certificate to install
976ceec40bSMarri Devender Rao * @param[in] uploadPath - Path of the certificate file to upload
98cf06ccdcSNan Zhou * @param[in] watchPtr - watch on self signed certificate
99cf06ccdcSNan Zhou * @param[in] parent - the manager that owns the certificate
100698a5743SWilly Tu * @param[in] restore - the certificate is created in the restore path
1016ceec40bSMarri Devender Rao */
102b3dbfb37SPatrick Williams Certificate(sdbusplus::bus_t& bus, const std::string& objPath,
103cf06ccdcSNan Zhou CertificateType type, const std::string& installPath,
104698a5743SWilly Tu const std::string& uploadPath, Watch* watch, Manager& parent,
105698a5743SWilly Tu bool restore);
1062f3563ccSZbigniew Lukwinski
1076ec13c8fSNan Zhou /** @brief Constructor for the Certificate Object; a variant for authorities
1086ec13c8fSNan Zhou * list install
1096ec13c8fSNan Zhou * @param[in] bus - Bus to attach to.
1106ec13c8fSNan Zhou * @param[in] objPath - Object path to attach to
1116ec13c8fSNan Zhou * @param[in] type - Type of the certificate
1126ec13c8fSNan Zhou * @param[in] installPath - Path of the certificate to install
1136ec13c8fSNan Zhou * @param[in] x509Store - an initialized X509 store used for certificate
1146ec13c8fSNan Zhou * validation; Certificate object doesn't own it
1156ec13c8fSNan Zhou * @param[in] pem - Content of the certificate file to upload; it shall be
1166ec13c8fSNan Zhou * a single PEM encoded x509 certificate
1176ec13c8fSNan Zhou * @param[in] watchPtr - watch on self signed certificate
1186ec13c8fSNan Zhou * @param[in] parent - Pointer to the manager which owns the constructed
1196ec13c8fSNan Zhou * Certificate object
120698a5743SWilly Tu * @param[in] restore - the certificate is created in the restore path
1216ec13c8fSNan Zhou */
122b3dbfb37SPatrick Williams Certificate(sdbusplus::bus_t& bus, const std::string& objPath,
1236ec13c8fSNan Zhou const CertificateType& type, const std::string& installPath,
1246ec13c8fSNan Zhou X509_STORE& x509Store, const std::string& pem, Watch* watchPtr,
125698a5743SWilly Tu Manager& parent, bool restore);
1266ec13c8fSNan Zhou
1272f3563ccSZbigniew Lukwinski /** @brief Validate and Replace/Install the certificate file
1282f3563ccSZbigniew Lukwinski * Install/Replace the existing certificate file with another
1292f3563ccSZbigniew Lukwinski * (possibly CA signed) Certificate file.
1302f3563ccSZbigniew Lukwinski * @param[in] filePath - Certificate file path.
131698a5743SWilly Tu * @param[in] restore - the certificate is created in the restore path
1322f3563ccSZbigniew Lukwinski */
133698a5743SWilly Tu void install(const std::string& filePath, bool restore);
1346ceec40bSMarri Devender Rao
1356ec13c8fSNan Zhou /** @brief Validate and Replace/Install the certificate file
1366ec13c8fSNan Zhou * Install/Replace the existing certificate file with another
1376ec13c8fSNan Zhou * (possibly CA signed) Certificate file.
1386ec13c8fSNan Zhou * @param[in] x509Store - an initialized X509 store used for certificate
1396ec13c8fSNan Zhou * validation; Certificate object doesn't own it
1406ec13c8fSNan Zhou * @param[in] pem - a string buffer which stores a PEM encoded certificate.
141698a5743SWilly Tu * @param[in] restore - the certificate is created in the restore path
1426ec13c8fSNan Zhou */
143698a5743SWilly Tu void install(X509_STORE& x509Store, const std::string& pem, bool restore);
1446ec13c8fSNan Zhou
14513bf74e4SMarri Devender Rao /** @brief Validate certificate and replace the existing certificate
14613bf74e4SMarri Devender Rao * @param[in] filePath - Certificate file path.
14713bf74e4SMarri Devender Rao */
14813bf74e4SMarri Devender Rao void replace(const std::string filePath) override;
14913bf74e4SMarri Devender Rao
150ffad1ef1SMarri Devender Rao /** @brief Populate certificate properties by parsing certificate file
151ffad1ef1SMarri Devender Rao */
152ffad1ef1SMarri Devender Rao void populateProperties();
153ffad1ef1SMarri Devender Rao
154db029c95SKowalski, Kamil /**
1552f3563ccSZbigniew Lukwinski * @brief Obtain certificate ID.
156db029c95SKowalski, Kamil *
1572f3563ccSZbigniew Lukwinski * @return Certificate ID.
158db029c95SKowalski, Kamil */
1592f3563ccSZbigniew Lukwinski std::string getCertId() const;
1602f3563ccSZbigniew Lukwinski
1612f3563ccSZbigniew Lukwinski /**
162bf3cf751SNan Zhou * @brief Check if provided certificate is the same as the current one.
1632f3563ccSZbigniew Lukwinski *
1642f3563ccSZbigniew Lukwinski * @param[in] certPath - File path for certificate to check.
1652f3563ccSZbigniew Lukwinski *
1662f3563ccSZbigniew Lukwinski * @return Checking result. Return true if certificates are the same,
1672f3563ccSZbigniew Lukwinski * false if not.
1682f3563ccSZbigniew Lukwinski */
1692f3563ccSZbigniew Lukwinski bool isSame(const std::string& certPath);
1702f3563ccSZbigniew Lukwinski
1712f3563ccSZbigniew Lukwinski /**
1722f3563ccSZbigniew Lukwinski * @brief Update certificate storage.
1732f3563ccSZbigniew Lukwinski */
1742f3563ccSZbigniew Lukwinski void storageUpdate();
175db029c95SKowalski, Kamil
176a3bb38fbSZbigniew Kurzynski /**
177a3bb38fbSZbigniew Kurzynski * @brief Delete the certificate
178a3bb38fbSZbigniew Kurzynski */
179a3bb38fbSZbigniew Kurzynski void delete_() override;
180a3bb38fbSZbigniew Kurzynski
1816ec13c8fSNan Zhou /**
1826ec13c8fSNan Zhou * @brief Generate file name which is unique in the provided directory.
1836ec13c8fSNan Zhou *
1846ec13c8fSNan Zhou * @param[in] directoryPath - Directory path.
1856ec13c8fSNan Zhou *
1866ec13c8fSNan Zhou * @return File path.
1876ec13c8fSNan Zhou */
1886ec13c8fSNan Zhou static std::string generateUniqueFilePath(const std::string& directoryPath);
1896ec13c8fSNan Zhou
1906ec13c8fSNan Zhou /**
1916ec13c8fSNan Zhou * @brief Copies the certificate from sourceFilePath to installFilePath
1926ec13c8fSNan Zhou *
1936ec13c8fSNan Zhou * @param[in] sourceFilePath - Path to the source file.
1946ec13c8fSNan Zhou * @param[in] certFilePath - Path to the destination file.
1956ec13c8fSNan Zhou *
1966ec13c8fSNan Zhou * @return void
1976ec13c8fSNan Zhou */
1986ec13c8fSNan Zhou static void copyCertificate(const std::string& certSrcFilePath,
1996ec13c8fSNan Zhou const std::string& certFilePath);
2006ec13c8fSNan Zhou
2016ec13c8fSNan Zhou /**
2026ec13c8fSNan Zhou * @brief Returns the associated dbus object path.
2036ec13c8fSNan Zhou */
2046ec13c8fSNan Zhou std::string getObjectPath();
2056ec13c8fSNan Zhou
2066ec13c8fSNan Zhou /**
2076ec13c8fSNan Zhou * @brief Returns the associated cert file path.
2086ec13c8fSNan Zhou */
2096ec13c8fSNan Zhou std::string getCertFilePath();
2106ec13c8fSNan Zhou
2116ec13c8fSNan Zhou /** @brief: Set the data member |certFilePath| to |path|
2126ec13c8fSNan Zhou */
2136ec13c8fSNan Zhou void setCertFilePath(const std::string& path);
2146ec13c8fSNan Zhou
2156ec13c8fSNan Zhou /** @brief: Set the data member |certInstallPath| to |path|
2166ec13c8fSNan Zhou */
2176ec13c8fSNan Zhou void setCertInstallPath(const std::string& path);
2186ec13c8fSNan Zhou
21913bf74e4SMarri Devender Rao private:
220db029c95SKowalski, Kamil /**
221e869bb63SNan Zhou * @brief Populate certificate properties by parsing given certificate
222e869bb63SNan Zhou * object
223c4522d2eSMarri Devender Rao *
224e869bb63SNan Zhou * @param[in] cert The given certificate object
225c4522d2eSMarri Devender Rao *
226c4522d2eSMarri Devender Rao * @return void
227c4522d2eSMarri Devender Rao */
228e869bb63SNan Zhou void populateProperties(X509& cert);
2296ceec40bSMarri Devender Rao
230cd30c496SMarri Devender Rao /** @brief Check and append private key to the certificate file
231cd30c496SMarri Devender Rao * If private key is not present in the certificate file append the
232cd30c496SMarri Devender Rao * certificate file with private key existing in the system.
233cd30c496SMarri Devender Rao * @param[in] filePath - Certificate and key full file path.
234cd30c496SMarri Devender Rao * @return void.
235cd30c496SMarri Devender Rao */
236cd30c496SMarri Devender Rao void checkAndAppendPrivateKey(const std::string& filePath);
237cd30c496SMarri Devender Rao
2386ceec40bSMarri Devender Rao /** @brief Public/Private key compare function.
2396ceec40bSMarri Devender Rao * Comparing private key against certificate public key
2406ceec40bSMarri Devender Rao * from input .pem file.
241cd30c496SMarri Devender Rao * @param[in] filePath - Certificate and key full file path.
2426ceec40bSMarri Devender Rao * @return Return true if Key compare is successful,
2436ceec40bSMarri Devender Rao * false if not
2446ceec40bSMarri Devender Rao */
2456ceec40bSMarri Devender Rao bool compareKeys(const std::string& filePath);
246cd30c496SMarri Devender Rao
2472f3563ccSZbigniew Lukwinski /**
2482f3563ccSZbigniew Lukwinski * @brief Generate authority certificate file path corresponding with
2492f3563ccSZbigniew Lukwinski * OpenSSL requirements.
2502f3563ccSZbigniew Lukwinski *
251bf3cf751SNan Zhou * Prepare authority certificate file path for provided certificate.
2522f3563ccSZbigniew Lukwinski * OpenSSL puts some restrictions on the certificate file name pattern.
2532f3563ccSZbigniew Lukwinski * Certificate full file name needs to consists of basic file name which
2542f3563ccSZbigniew Lukwinski * is certificate subject name hash and file name extension which is an
2552f3563ccSZbigniew Lukwinski * integer. More over, certificates files names extensions must be
2562f3563ccSZbigniew Lukwinski * consecutive integer numbers in case many certificates with the same
2572f3563ccSZbigniew Lukwinski * subject name.
2582f3563ccSZbigniew Lukwinski * https://www.boost.org/doc/libs/1_69_0/doc/html/boost_asio/reference/ssl__context/add_verify_path.html
2592f3563ccSZbigniew Lukwinski * https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_load_verify_locations.html
2602f3563ccSZbigniew Lukwinski *
2612f3563ccSZbigniew Lukwinski * @param[in] certSrcFilePath - Certificate source file path.
2622f3563ccSZbigniew Lukwinski * @param[in] certDstDirPath - Certificate destination directory path.
2632f3563ccSZbigniew Lukwinski *
2642f3563ccSZbigniew Lukwinski * @return Authority certificate file path.
2652f3563ccSZbigniew Lukwinski */
2662f3563ccSZbigniew Lukwinski std::string generateAuthCertFileX509Path(const std::string& certSrcFilePath,
2672f3563ccSZbigniew Lukwinski const std::string& certDstDirPath);
2682f3563ccSZbigniew Lukwinski
2692f3563ccSZbigniew Lukwinski /**
2702f3563ccSZbigniew Lukwinski * @brief Generate authority certificate file path based on provided
2712f3563ccSZbigniew Lukwinski * certificate source file path.
2722f3563ccSZbigniew Lukwinski *
2732f3563ccSZbigniew Lukwinski * @param[in] certSrcFilePath - Certificate source file path.
2742f3563ccSZbigniew Lukwinski *
2752f3563ccSZbigniew Lukwinski * @return Authority certificate file path.
2762f3563ccSZbigniew Lukwinski */
2772f3563ccSZbigniew Lukwinski std::string generateAuthCertFilePath(const std::string& certSrcFilePath);
2782f3563ccSZbigniew Lukwinski
2792f3563ccSZbigniew Lukwinski /**
2802f3563ccSZbigniew Lukwinski * @brief Generate certificate file path based on provided certificate
2812f3563ccSZbigniew Lukwinski * source file path.
2822f3563ccSZbigniew Lukwinski *
2832f3563ccSZbigniew Lukwinski * @param[in] certSrcFilePath - Certificate source file path.
2842f3563ccSZbigniew Lukwinski *
2852f3563ccSZbigniew Lukwinski * @return Certificate file path.
2862f3563ccSZbigniew Lukwinski */
2872f3563ccSZbigniew Lukwinski std::string generateCertFilePath(const std::string& certSrcFilePath);
2882f3563ccSZbigniew Lukwinski
2892f3563ccSZbigniew Lukwinski /** @brief Type specific function pointer map */
290cf06ccdcSNan Zhou std::unordered_map<CertificateType, internal::InstallFunc> typeFuncMap;
2916ceec40bSMarri Devender Rao
2926ceec40bSMarri Devender Rao /** @brief object path */
2936ceec40bSMarri Devender Rao std::string objectPath;
2946ceec40bSMarri Devender Rao
2952f3563ccSZbigniew Lukwinski /** @brief Type of the certificate */
2966ceec40bSMarri Devender Rao CertificateType certType;
2976ceec40bSMarri Devender Rao
2982f3563ccSZbigniew Lukwinski /** @brief Stores certificate ID */
2992f3563ccSZbigniew Lukwinski std::string certId;
3006ceec40bSMarri Devender Rao
3012f3563ccSZbigniew Lukwinski /** @brief Stores certificate file path */
3022f3563ccSZbigniew Lukwinski std::string certFilePath;
3032f3563ccSZbigniew Lukwinski
3042f3563ccSZbigniew Lukwinski /** @brief Certificate file installation path */
305cf06ccdcSNan Zhou std::string certInstallPath;
306ffad1ef1SMarri Devender Rao
307cd30c496SMarri Devender Rao /** @brief Type specific function pointer map for appending private key */
308cf06ccdcSNan Zhou std::unordered_map<CertificateType, internal::AppendPrivKeyFunc>
309cf06ccdcSNan Zhou appendKeyMap;
310cd30c496SMarri Devender Rao
311cf06ccdcSNan Zhou /** @brief Certificate file create/update watch
312cf06ccdcSNan Zhou * Note that Certificate object doesn't own the pointer
313cf06ccdcSNan Zhou */
314cf06ccdcSNan Zhou Watch* certWatch;
315db029c95SKowalski, Kamil
316a3bb38fbSZbigniew Kurzynski /** @brief Reference to Certificate Manager */
317a3bb38fbSZbigniew Kurzynski Manager& manager;
3186ceec40bSMarri Devender Rao };
3196ceec40bSMarri Devender Rao
320e1289adfSNan Zhou } // namespace phosphor::certs
321