blob: aea3ce62b24b943cc55fa93b09c36cb1346aba59 [file] [log] [blame]
Marri Devender Rao6ceec402019-02-01 03:15:19 -06001#pragma once
2
Marri Devender Raoffad1ef2019-06-03 04:54:12 -05003#include "watch.hpp"
4
Marri Devender Rao6ceec402019-02-01 03:15:19 -06005#include <openssl/x509.h>
6
7#include <filesystem>
8#include <phosphor-logging/elog.hpp>
Marri Devender Raoedd11312019-02-27 08:45:10 -06009#include <xyz/openbmc_project/Certs/Certificate/server.hpp>
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050010#include <xyz/openbmc_project/Certs/Replace/server.hpp>
Marri Devender Rao6ceec402019-02-01 03:15:19 -060011
12namespace phosphor
13{
14namespace certs
15{
Marri Devender Raoedd11312019-02-27 08:45:10 -060016using CertificateIface = sdbusplus::server::object::object<
17 sdbusplus::xyz::openbmc_project::Certs::server::Certificate>;
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050018using ReplaceIface = sdbusplus::xyz::openbmc_project::Certs::server::Replace;
Marri Devender Raoedd11312019-02-27 08:45:10 -060019using CertIfaces =
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050020 sdbusplus::server::object::object<CertificateIface, ReplaceIface>;
Marri Devender Raoedd11312019-02-27 08:45:10 -060021
Marri Devender Rao6ceec402019-02-01 03:15:19 -060022using CertificateType = std::string;
23using UnitsToRestart = std::string;
24using CertInstallPath = std::string;
25using CertUploadPath = std::string;
26using InputType = std::string;
27using InstallFunc = std::function<void(const std::string&)>;
Marri Devender Raocd30c492019-06-12 01:40:17 -050028using AppendPrivKeyFunc = std::function<void(const std::string&)>;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050029using CertWatchPtr = std::unique_ptr<Watch>;
Marri Devender Rao6ceec402019-02-01 03:15:19 -060030using namespace phosphor::logging;
31
32// for placeholders
33using namespace std::placeholders;
34namespace fs = std::filesystem;
35
36// Supported Types.
37static constexpr auto SERVER = "server";
38static constexpr auto CLIENT = "client";
39static constexpr auto AUTHORITY = "authority";
40
41// RAII support for openSSL functions.
42using X509_Ptr = std::unique_ptr<X509, decltype(&::X509_free)>;
43
44/** @class Certificate
45 * @brief OpenBMC Certificate entry implementation.
46 * @details A concrete implementation for the
47 * xyz.openbmc_project.Certs.Certificate DBus API
48 * xyz.openbmc_project.Certs.Instal DBus API
49 */
Marri Devender Raoedd11312019-02-27 08:45:10 -060050class Certificate : public CertIfaces
Marri Devender Rao6ceec402019-02-01 03:15:19 -060051{
52 public:
53 Certificate() = delete;
54 Certificate(const Certificate&) = delete;
55 Certificate& operator=(const Certificate&) = delete;
56 Certificate(Certificate&&) = delete;
57 Certificate& operator=(Certificate&&) = delete;
58 virtual ~Certificate();
59
60 /** @brief Constructor for the Certificate Object
61 * @param[in] bus - Bus to attach to.
62 * @param[in] objPath - Object path to attach to
63 * @param[in] type - Type of the certificate
64 * @param[in] unit - Units to restart after a certificate is installed
65 * @param[in] installPath - Path of the certificate to install
66 * @param[in] uploadPath - Path of the certificate file to upload
Marri Devender Rao8f80c352019-05-13 00:53:01 -050067 * @param[in] isSkipUnitReload - If true do not restart units
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050068 * @param[in] watchPtr - watch on self signed certificate pointer
Marri Devender Rao6ceec402019-02-01 03:15:19 -060069 */
70 Certificate(sdbusplus::bus::bus& bus, const std::string& objPath,
71 const CertificateType& type, const UnitsToRestart& unit,
72 const CertInstallPath& installPath,
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050073 const CertUploadPath& uploadPath, bool isSkipUnitReload,
74 const CertWatchPtr& watchPtr);
Marri Devender Rao6ceec402019-02-01 03:15:19 -060075
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050076 /** @brief Validate certificate and replace the existing certificate
77 * @param[in] filePath - Certificate file path.
78 */
79 void replace(const std::string filePath) override;
80
Marri Devender Raoffad1ef2019-06-03 04:54:12 -050081 /** @brief Populate certificate properties by parsing certificate file
82 * @return void
83 */
84 void populateProperties();
85
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050086 private:
87 /** @brief Validate and Replace/Install the certificate file
88 * Install/Replace the existing certificate file with another
Marri Devender Rao6ceec402019-02-01 03:15:19 -060089 * (possibly CA signed) Certificate file.
90 * @param[in] filePath - Certificate file path.
Marri Devender Rao8f80c352019-05-13 00:53:01 -050091 * @param[in] isSkipUnitReload - If true do not restart units
Marri Devender Rao6ceec402019-02-01 03:15:19 -060092 */
Marri Devender Rao8f80c352019-05-13 00:53:01 -050093 void install(const std::string& filePath, bool isSkipUnitReload);
Marri Devender Rao6ceec402019-02-01 03:15:19 -060094
Marri Devender Rao6ceec402019-02-01 03:15:19 -060095 /** @brief Load Certificate file into the X509 structre.
Marri Devender Raocd30c492019-06-12 01:40:17 -050096 * @param[in] filePath - Certificate and key full file path.
Marri Devender Rao6ceec402019-02-01 03:15:19 -060097 * @return pointer to the X509 structure.
98 */
99 X509_Ptr loadCert(const std::string& filePath);
100
Marri Devender Raocd30c492019-06-12 01:40:17 -0500101 /** @brief Check and append private key to the certificate file
102 * If private key is not present in the certificate file append the
103 * certificate file with private key existing in the system.
104 * @param[in] filePath - Certificate and key full file path.
105 * @return void.
106 */
107 void checkAndAppendPrivateKey(const std::string& filePath);
108
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600109 /** @brief Public/Private key compare function.
110 * Comparing private key against certificate public key
111 * from input .pem file.
Marri Devender Raocd30c492019-06-12 01:40:17 -0500112 * @param[in] filePath - Certificate and key full file path.
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600113 * @return Return true if Key compare is successful,
114 * false if not
115 */
116 bool compareKeys(const std::string& filePath);
Marri Devender Raocd30c492019-06-12 01:40:17 -0500117
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600118 /** @brief systemd unit reload or reset helper function
119 * Reload if the unit supports it and use a restart otherwise.
120 * @param[in] unit - service need to reload.
121 */
122 void reloadOrReset(const UnitsToRestart& unit);
123
124 /** @brief Type specific function pointer map **/
125 std::unordered_map<InputType, InstallFunc> typeFuncMap;
126
127 /** @brief sdbusplus handler */
128 sdbusplus::bus::bus& bus;
129
130 /** @brief object path */
131 std::string objectPath;
132
133 /** @brief Type of the certificate **/
134 CertificateType certType;
135
136 /** @brief Unit name associated to the service **/
137 UnitsToRestart unitToRestart;
138
139 /** @brief Certificate file installation path **/
140 CertInstallPath certInstallPath;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500141
Marri Devender Raocd30c492019-06-12 01:40:17 -0500142 /** @brief Type specific function pointer map for appending private key */
143 std::unordered_map<InputType, AppendPrivKeyFunc> appendKeyMap;
144
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500145 /** @brief Certificate file create/update watch */
146 const CertWatchPtr& certWatchPtr;
Marri Devender Rao6ceec402019-02-01 03:15:19 -0600147};
148
149} // namespace certs
150} // namespace phosphor