forked from ibm-openbmc/phosphor-certificate-manager
-
Notifications
You must be signed in to change notification settings - Fork 0
/
certificate.hpp
320 lines (277 loc) · 10.7 KB
/
certificate.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
#pragma once
#include "watch.hpp"
#include <openssl/ossl_typ.h>
#include <openssl/x509.h>
#include <sdbusplus/server/object.hpp>
#include <xyz/openbmc_project/Certs/Certificate/server.hpp>
#include <xyz/openbmc_project/Certs/Replace/server.hpp>
#include <xyz/openbmc_project/Object/Delete/server.hpp>
#include <functional>
#include <memory>
#include <string>
#include <string_view>
#include <unordered_map>
namespace phosphor::certs
{
// Certificate types
enum class CertificateType
{
authority,
server,
client,
unsupported,
};
inline constexpr const char* certificateTypeToString(CertificateType type)
{
switch (type)
{
case CertificateType::authority:
return "authority";
case CertificateType::server:
return "server";
case CertificateType::client:
return "client";
default:
return "unsupported";
}
}
inline constexpr CertificateType stringToCertificateType(std::string_view type)
{
if (type == "authority")
{
return CertificateType::authority;
}
if (type == "server")
{
return CertificateType::server;
}
if (type == "client")
{
return CertificateType::client;
}
return CertificateType::unsupported;
}
namespace internal
{
using CertificateInterface = sdbusplus::server::object_t<
sdbusplus::xyz::openbmc_project::Certs::server::Certificate,
sdbusplus::xyz::openbmc_project::Certs::server::Replace,
sdbusplus::xyz::openbmc_project::Object::server::Delete>;
using InstallFunc = std::function<void(const std::string&)>;
using AppendPrivKeyFunc = std::function<void(const std::string&)>;
using X509Ptr = std::unique_ptr<X509, decltype(&::X509_free)>;
} // namespace internal
class Manager; // Forward declaration for Certificate Manager.
/** @class Certificate
* @brief OpenBMC Certificate entry implementation.
* @details A concrete implementation for the
* xyz.openbmc_project.Certs.Certificate DBus API
* xyz.openbmc_project.Certs.Install DBus API
*/
class Certificate : public internal::CertificateInterface
{
public:
Certificate() = delete;
Certificate(const Certificate&) = delete;
Certificate& operator=(const Certificate&) = delete;
Certificate(Certificate&&) = delete;
Certificate& operator=(Certificate&&) = delete;
virtual ~Certificate();
/** @brief Constructor for the Certificate Object
* @param[in] bus - Bus to attach to.
* @param[in] objPath - Object path to attach to
* @param[in] type - Type of the certificate
* @param[in] installPath - Path of the certificate to install
* @param[in] uploadPath - Path of the certificate file to upload
* @param[in] watchPtr - watch on self signed certificate
* @param[in] parent - the manager that owns the certificate
* @param[in] restore - the certificate is created in the restore path
*/
Certificate(sdbusplus::bus_t& bus, const std::string& objPath,
CertificateType type, const std::string& installPath,
const std::string& uploadPath, Watch* watch, Manager& parent,
bool restore);
/** @brief Constructor for the Certificate Object; a variant for authorities
* list install
* @param[in] bus - Bus to attach to.
* @param[in] objPath - Object path to attach to
* @param[in] type - Type of the certificate
* @param[in] installPath - Path of the certificate to install
* @param[in] x509Store - an initialized X509 store used for certificate
* validation; Certificate object doesn't own it
* @param[in] pem - Content of the certificate file to upload; it shall be
* a single PEM encoded x509 certificate
* @param[in] watchPtr - watch on self signed certificate
* @param[in] parent - Pointer to the manager which owns the constructed
* Certificate object
* @param[in] restore - the certificate is created in the restore path
*/
Certificate(sdbusplus::bus_t& bus, const std::string& objPath,
const CertificateType& type, const std::string& installPath,
X509_STORE& x509Store, const std::string& pem, Watch* watchPtr,
Manager& parent, bool restore);
/** @brief Validate and Replace/Install the certificate file
* Install/Replace the existing certificate file with another
* (possibly CA signed) Certificate file.
* @param[in] filePath - Certificate file path.
* @param[in] restore - the certificate is created in the restore path
*/
void install(const std::string& filePath, bool restore);
/** @brief Validate and Replace/Install the certificate file
* Install/Replace the existing certificate file with another
* (possibly CA signed) Certificate file.
* @param[in] x509Store - an initialized X509 store used for certificate
* validation; Certificate object doesn't own it
* @param[in] pem - a string buffer which stores a PEM encoded certificate.
* @param[in] restore - the certificate is created in the restore path
*/
void install(X509_STORE& x509Store, const std::string& pem, bool restore);
/** @brief Validate certificate and replace the existing certificate
* @param[in] filePath - Certificate file path.
*/
void replace(const std::string filePath) override;
/** @brief Populate certificate properties by parsing certificate file
*/
void populateProperties();
/**
* @brief Obtain certificate ID.
*
* @return Certificate ID.
*/
std::string getCertId() const;
/**
* @brief Check if provided certificate is the same as the current one.
*
* @param[in] certPath - File path for certificate to check.
*
* @return Checking result. Return true if certificates are the same,
* false if not.
*/
bool isSame(const std::string& certPath);
/**
* @brief Update certificate storage.
*/
void storageUpdate();
/**
* @brief Delete the certificate
*/
void delete_() override;
/**
* @brief Generate file name which is unique in the provided directory.
*
* @param[in] directoryPath - Directory path.
*
* @return File path.
*/
static std::string generateUniqueFilePath(const std::string& directoryPath);
/**
* @brief Copies the certificate from sourceFilePath to installFilePath
*
* @param[in] sourceFilePath - Path to the source file.
* @param[in] certFilePath - Path to the destination file.
*
* @return void
*/
static void copyCertificate(const std::string& certSrcFilePath,
const std::string& certFilePath);
/**
* @brief Returns the associated dbus object path.
*/
std::string getObjectPath();
/**
* @brief Returns the associated cert file path.
*/
std::string getCertFilePath();
/** @brief: Set the data member |certFilePath| to |path|
*/
void setCertFilePath(const std::string& path);
/** @brief: Set the data member |certInstallPath| to |path|
*/
void setCertInstallPath(const std::string& path);
private:
/**
* @brief Populate certificate properties by parsing given certificate
* object
*
* @param[in] cert The given certificate object
*
* @return void
*/
void populateProperties(X509& cert);
/** @brief Check and append private key to the certificate file
* If private key is not present in the certificate file append the
* certificate file with private key existing in the system.
* @param[in] filePath - Certificate and key full file path.
* @return void.
*/
void checkAndAppendPrivateKey(const std::string& filePath);
/** @brief Public/Private key compare function.
* Comparing private key against certificate public key
* from input .pem file.
* @param[in] filePath - Certificate and key full file path.
* @return Return true if Key compare is successful,
* false if not
*/
bool compareKeys(const std::string& filePath);
/**
* @brief Generate authority certificate file path corresponding with
* OpenSSL requirements.
*
* Prepare authority certificate file path for provided certificate.
* OpenSSL puts some restrictions on the certificate file name pattern.
* Certificate full file name needs to consists of basic file name which
* is certificate subject name hash and file name extension which is an
* integer. More over, certificates files names extensions must be
* consecutive integer numbers in case many certificates with the same
* subject name.
* https://www.boost.org/doc/libs/1_69_0/doc/html/boost_asio/reference/ssl__context/add_verify_path.html
* https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_load_verify_locations.html
*
* @param[in] certSrcFilePath - Certificate source file path.
* @param[in] certDstDirPath - Certificate destination directory path.
*
* @return Authority certificate file path.
*/
std::string generateAuthCertFileX509Path(const std::string& certSrcFilePath,
const std::string& certDstDirPath);
/**
* @brief Generate authority certificate file path based on provided
* certificate source file path.
*
* @param[in] certSrcFilePath - Certificate source file path.
*
* @return Authority certificate file path.
*/
std::string generateAuthCertFilePath(const std::string& certSrcFilePath);
/**
* @brief Generate certificate file path based on provided certificate
* source file path.
*
* @param[in] certSrcFilePath - Certificate source file path.
*
* @return Certificate file path.
*/
std::string generateCertFilePath(const std::string& certSrcFilePath);
/** @brief Type specific function pointer map */
std::unordered_map<CertificateType, internal::InstallFunc> typeFuncMap;
/** @brief object path */
std::string objectPath;
/** @brief Type of the certificate */
CertificateType certType;
/** @brief Stores certificate ID */
std::string certId;
/** @brief Stores certificate file path */
std::string certFilePath;
/** @brief Certificate file installation path */
std::string certInstallPath;
/** @brief Type specific function pointer map for appending private key */
std::unordered_map<CertificateType, internal::AppendPrivKeyFunc>
appendKeyMap;
/** @brief Certificate file create/update watch
* Note that Certificate object doesn't own the pointer
*/
Watch* certWatch;
/** @brief Reference to Certificate Manager */
Manager& manager;
};
} // namespace phosphor::certs