1 #pragma once
2 #include <openssl/x509.h>
3 
4 #include <cstring>
5 #include <sdbusplus/bus.hpp>
6 #include <sdbusplus/server/object.hpp>
7 #include <unordered_map>
8 #include <xyz/openbmc_project/Certs/Install/server.hpp>
9 
10 namespace phosphor
11 {
12 namespace certs
13 {
14 // RAII support for openSSL functions.
15 using X509_Ptr = std::unique_ptr<X509, decltype(&::X509_free)>;
16 
17 // Supported Types.
18 static constexpr auto SERVER = "server";
19 static constexpr auto CLIENT = "client";
20 
21 using CreateIface = sdbusplus::server::object::object<
22     sdbusplus::xyz::openbmc_project::Certs::server::Install>;
23 using InstallFunc = std::function<void()>;
24 using InputType = std::string;
25 
26 class Manager : public CreateIface
27 {
28   public:
29     /* Define all of the basic class operations:
30      *     Not allowed:
31      *         - Default constructor is not possible due to member
32      *           reference
33      *         - Move operations due to 'this' being registered as the
34      *           'context' with sdbus.
35      *     Allowed:
36      *         - copy
37      *         - Destructor.
38      */
39     Manager() = delete;
40     Manager(const Manager&) = default;
41     Manager& operator=(const Manager&) = delete;
42     Manager(Manager&&) = delete;
43     Manager& operator=(Manager&&) = delete;
44     virtual ~Manager() = default;
45 
46     /** @brief Constructor to put object onto bus at a dbus path.
47      *  @param[in] bus - Bus to attach to.
48      *  @param[in] path - Path to attach at.
49      *  @param[in] type - Type of the certificate.
50      *  @param[in] unit - Unit consumed by this certificate.
51      *  @param[in] certpath - Certificate installation path.
52      */
53     Manager(sdbusplus::bus::bus& bus, const char* path, const std::string& type,
54             std::string&& unit, std::string&& certPath) :
55         CreateIface(bus, path),
56         bus(bus), path(path), type(type), unit(std::move(unit)),
57         certPath(std::move(certPath))
58     {
59         typeFuncMap[SERVER] =
60             std::bind(&phosphor::certs::Manager::serverInstall, this);
61         typeFuncMap[CLIENT] =
62             std::bind(&phosphor::certs::Manager::clientInstall, this);
63     }
64 
65     /** @brief Implementation for Install
66      *  Replace the existing certificate key file with another
67      *  (possibly CA signed) Certificate key file.
68      *
69      *  @param[in] path - Certificate key file path.
70      */
71     void install(const std::string path) override;
72 
73   private:
74     /** @brief Client certificate Installation helper function **/
75     virtual void clientInstall();
76 
77     /** @brief Server certificate Installation helper function **/
78     virtual void serverInstall();
79 
80     /** @brief systemd unit reload or reset helper function
81      *  Reload if the unit supports it and use a restart otherwise.
82      *  @param[in] unit - service need to reload.
83      */
84     void reloadOrReset(const std::string& unit);
85 
86     /** @brief helper function to copy the file.
87      *  @param[in] src - Source file path to copy
88      *  @param[in] dst - Destination path to copy
89      */
90     void copy(const std::string& src, const std::string& dst);
91 
92     /** @brief Certificate verification function
93      *        Certificate file specific validation using openssl
94      *        verify function also includes expiry date check
95      *  @param[in] fileName - Certificate and key full file path.
96      *  @return error code from open ssl verify function.
97      */
98     int32_t verifyCert(const std::string& filePath);
99 
100     /** @brief Load Certificate file into the X509 structre.
101      *  @param[in] fileName - Certificate and key full file path.
102      *  @return pointer to the X509 structure.
103      */
104     X509_Ptr loadCert(const std::string& filePath);
105 
106     /** @brief Public/Private key compare function.
107      *         Comparing private key against certificate public key
108      *         from input .pem file.
109      *  @param[in] fileName - Certificate and key full file path.
110      *  @return Return true if Key compare is successful,
111      *          false if not
112      */
113     bool compareKeys(const std::string& filePath);
114 
115     /** @brief sdbusplus handler */
116     sdbusplus::bus::bus& bus;
117 
118     /** @brief object path */
119     std::string path;
120 
121     /** @brief Type of the certificate **/
122     InputType type;
123 
124     /** @brief Unit name associated to the service **/
125     std::string unit;
126 
127     /** @brief Certificate file installation path **/
128     std::string certPath;
129 
130     /** @brief Type specific function pointer map **/
131     std::unordered_map<InputType, InstallFunc> typeFuncMap;
132 };
133 
134 } // namespace certs
135 } // namespace phosphor
136