blob: 6244359fb48d9eaf5bced03161b0e9340c775972 [file] [log] [blame]
Marri Devender Rao13bf74e2019-03-26 01:52:17 -05001#include "config.h"
2
Marri Devender Rao8841dbd2019-03-04 05:43:55 -06003#include "certificate.hpp"
Marri Devender Rao947258d2018-09-25 10:52:24 -05004#include "certs_manager.hpp"
5
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +01006#include <openssl/bio.h>
7#include <openssl/crypto.h>
8#include <openssl/err.h>
9#include <openssl/evp.h>
10#include <openssl/pem.h>
11#include <openssl/x509v3.h>
12
Marri Devender Rao947258d2018-09-25 10:52:24 -050013#include <algorithm>
Marri Devender Rao8841dbd2019-03-04 05:43:55 -060014#include <filesystem>
Marri Devender Rao947258d2018-09-25 10:52:24 -050015#include <fstream>
16#include <iterator>
Marri Devender Raof4682712019-03-19 05:00:28 -050017#include <sdeventplus/event.hpp>
Marri Devender Rao947258d2018-09-25 10:52:24 -050018#include <string>
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050019#include <xyz/openbmc_project/Certs/error.hpp>
Marri Devender Rao947258d2018-09-25 10:52:24 -050020#include <xyz/openbmc_project/Common/error.hpp>
21
Marri Devender Rao947258d2018-09-25 10:52:24 -050022#include <gtest/gtest.h>
Marri Devender Rao8841dbd2019-03-04 05:43:55 -060023namespace fs = std::filesystem;
Marri Devender Rao947258d2018-09-25 10:52:24 -050024using InternalFailure =
25 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
Marri Devender Raoe6597c52018-10-01 06:36:55 -050026using InvalidCertificate =
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050027 sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -060028using namespace phosphor::certs;
Marri Devender Raoe6597c52018-10-01 06:36:55 -050029
Marri Devender Raoddf64862018-10-03 07:11:02 -050030/**
31 * Class to generate certificate file and test verification of certificate file
32 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -060033class TestCertificates : public ::testing::Test
Marri Devender Rao947258d2018-09-25 10:52:24 -050034{
35 public:
Marri Devender Rao8841dbd2019-03-04 05:43:55 -060036 TestCertificates() : bus(sdbusplus::bus::new_default())
Marri Devender Rao947258d2018-09-25 10:52:24 -050037 {
38 }
39 void SetUp() override
40 {
41 char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
42 auto dirPtr = mkdtemp(dirTemplate);
43 if (dirPtr == NULL)
44 {
45 throw std::bad_alloc();
46 }
Zbigniew Lukwinskife590c42019-12-10 12:33:50 +010047 certDir = std::string(dirPtr) + "/certs";
48 fs::create_directories(certDir);
Kowalski, Kamildb029c92019-07-08 17:09:39 +020049
50 createNewCertificate();
Marri Devender Rao947258d2018-09-25 10:52:24 -050051 }
Kowalski, Kamildb029c92019-07-08 17:09:39 +020052
Marri Devender Rao947258d2018-09-25 10:52:24 -050053 void TearDown() override
54 {
55 fs::remove_all(certDir);
56 fs::remove(certificateFile);
Marri Devender Raof4682712019-03-19 05:00:28 -050057 fs::remove(CSRFile);
58 fs::remove(privateKeyFile);
Marri Devender Rao947258d2018-09-25 10:52:24 -050059 }
60
Kowalski, Kamildb029c92019-07-08 17:09:39 +020061 void createNewCertificate(bool setNewCertId = false)
62 {
63 certificateFile = "cert.pem";
64 CSRFile = "domain.csr";
65 privateKeyFile = "privkey.pem";
66 rsaPrivateKeyFilePath = certDir + "/.rsaprivkey.pem";
67 std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
68 cmd += "-keyout cert.pem -out cert.pem -days 3650 -nodes";
69 cmd += " -subj /O=openbmc-project.xyz/CN=localhost";
70
71 if (setNewCertId)
72 {
73 cmd += std::to_string(certId++);
74 }
75
76 auto val = std::system(cmd.c_str());
77 if (val)
78 {
79 std::cout << "COMMAND Error: " << val << std::endl;
80 }
81 }
82
Marri Devender Rao947258d2018-09-25 10:52:24 -050083 bool compareFiles(const std::string& file1, const std::string& file2)
84 {
85 std::ifstream f1(file1, std::ifstream::binary | std::ifstream::ate);
86 std::ifstream f2(file2, std::ifstream::binary | std::ifstream::ate);
87
88 if (f1.fail() || f2.fail())
89 {
90 return false; // file problem
91 }
92
93 if (f1.tellg() != f2.tellg())
94 {
95 return false; // size mismatch
96 }
97
98 // seek back to beginning and use std::equal to compare contents
99 f1.seekg(0, std::ifstream::beg);
100 f2.seekg(0, std::ifstream::beg);
101 return std::equal(std::istreambuf_iterator<char>(f1.rdbuf()),
102 std::istreambuf_iterator<char>(),
103 std::istreambuf_iterator<char>(f2.rdbuf()));
104 }
105
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100106 std::string getCertSubjectNameHash(const std::string& certFilePath)
107 {
108 std::unique_ptr<X509, decltype(&::X509_free)> cert(X509_new(),
109 ::X509_free);
110 if (!cert)
111 {
112 std::string();
113 }
114
115 std::unique_ptr<BIO, decltype(&::BIO_free)> bioCert(
116 BIO_new_file(certFilePath.c_str(), "rb"), ::BIO_free);
117 if (!bioCert)
118 {
119 std::string();
120 }
121
122 X509* x509 = cert.get();
123 if (!PEM_read_bio_X509(bioCert.get(), &x509, nullptr, nullptr))
124 {
125 std::string();
126 }
127
128 unsigned long hash = X509_subject_name_hash(cert.get());
129 static constexpr auto AUTH_CERT_HASH_LENGTH = 9;
130 char hashBuf[AUTH_CERT_HASH_LENGTH];
131 sprintf(hashBuf, "%08lx", hash);
132 return std::string(hashBuf);
133 }
134
Marri Devender Rao947258d2018-09-25 10:52:24 -0500135 protected:
136 sdbusplus::bus::bus bus;
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -0500137 std::string certificateFile, CSRFile, privateKeyFile, rsaPrivateKeyFilePath;
Marri Devender Rao947258d2018-09-25 10:52:24 -0500138
139 std::string certDir;
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200140 uint64_t certId;
Marri Devender Rao947258d2018-09-25 10:52:24 -0500141};
142
143class MainApp
144{
145 public:
Marri Devender Raof4682712019-03-19 05:00:28 -0500146 MainApp(phosphor::certs::Manager* manager,
147 phosphor::certs::CSR* csr = nullptr) :
148 manager(manager),
Patrick Williamse129be32021-04-30 20:35:19 -0500149 csr_(csr)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500150 {
151 }
152 void install(std::string& path)
153 {
154 manager->install(path);
155 }
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500156 void delete_()
157 {
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +0200158 manager->deleteAll();
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500159 }
Marri Devender Raof4682712019-03-19 05:00:28 -0500160
161 std::string generateCSR(std::vector<std::string> alternativeNames,
162 std::string challengePassword, std::string city,
163 std::string commonName, std::string contactPerson,
164 std::string country, std::string email,
165 std::string givenName, std::string initials,
166 int64_t keyBitLength, std::string keyCurveId,
167 std::string keyPairAlgorithm,
168 std::vector<std::string> keyUsage,
169 std::string organization,
170 std::string organizationalUnit, std::string state,
171 std::string surname, std::string unstructuredName)
172 {
173 return (manager->generateCSR(
174 alternativeNames, challengePassword, city, commonName,
175 contactPerson, country, email, givenName, initials, keyBitLength,
176 keyCurveId, keyPairAlgorithm, keyUsage, organization,
177 organizationalUnit, state, surname, unstructuredName));
178 }
Patrick Williamse129be32021-04-30 20:35:19 -0500179#ifdef SDBUSPP_NEW_CAMELCASE
180 std::string csr()
181 {
182 return (csr_->csr());
183 }
184#else
Marri Devender Raof4682712019-03-19 05:00:28 -0500185 std::string cSR()
186 {
Patrick Williamse129be32021-04-30 20:35:19 -0500187 return (csr_->cSR());
Marri Devender Raof4682712019-03-19 05:00:28 -0500188 }
Patrick Williamse129be32021-04-30 20:35:19 -0500189#endif
Marri Devender Rao947258d2018-09-25 10:52:24 -0500190 phosphor::certs::Manager* manager;
Patrick Williamse129be32021-04-30 20:35:19 -0500191 phosphor::certs::CSR* csr_;
Marri Devender Rao947258d2018-09-25 10:52:24 -0500192};
193
Marri Devender Rao947258d2018-09-25 10:52:24 -0500194/** @brief Check if server install routine is invoked for server setup
195 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600196TEST_F(TestCertificates, InvokeServerInstall)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500197{
198 std::string endpoint("https");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600199 std::string unit("");
Marri Devender Rao947258d2018-09-25 10:52:24 -0500200 std::string type("server");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600201 std::string installPath(certDir + "/" + certificateFile);
202 std::string verifyPath(installPath);
203 UnitsToRestart verifyUnit(unit);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500204 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500205 auto event = sdeventplus::Event::get_default();
206 // Attach the bus to sd_event to service user requests
207 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
208 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
209 std::move(installPath));
210 MainApp mainApp(&manager);
211 mainApp.install(certificateFile);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500212 EXPECT_TRUE(fs::exists(verifyPath));
213}
214
215/** @brief Check if client install routine is invoked for client setup
216 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600217TEST_F(TestCertificates, InvokeClientInstall)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500218{
219 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600220 std::string unit("");
221 std::string type("server");
222 std::string installPath(certDir + "/" + certificateFile);
223 std::string verifyPath(installPath);
224 UnitsToRestart verifyUnit(unit);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500225 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500226 auto event = sdeventplus::Event::get_default();
227 // Attach the bus to sd_event to service user requests
228 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
229 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
230 std::move(installPath));
231 MainApp mainApp(&manager);
232 mainApp.install(certificateFile);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500233 EXPECT_TRUE(fs::exists(verifyPath));
234}
235
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200236/** @brief Check if storage install routine is invoked for storage setup
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500237 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600238TEST_F(TestCertificates, InvokeAuthorityInstall)
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500239{
240 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600241 std::string unit("");
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500242 std::string type("authority");
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200243 std::string verifyDir(certDir);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600244 UnitsToRestart verifyUnit(unit);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500245 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500246 auto event = sdeventplus::Event::get_default();
247 // Attach the bus to sd_event to service user requests
248 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
249 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200250 std::move(certDir));
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500251 MainApp mainApp(&manager);
252 mainApp.install(certificateFile);
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200253
254 std::vector<std::unique_ptr<Certificate>>& certs =
255 manager.getCertificates();
256
257 EXPECT_FALSE(certs.empty());
258
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100259 std::string verifyPath =
260 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200261
262 // Check that certificate has been created at installation directory
263 EXPECT_FALSE(fs::is_empty(verifyDir));
264 EXPECT_TRUE(fs::exists(verifyPath));
265
266 // Check that installed cert is identical to input one
267 EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
268}
269
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100270/** @brief Check if in authority mode user can't install the same
271 * certificate twice.
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200272 */
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100273TEST_F(TestCertificates, InvokeInstallSameCertTwice)
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200274{
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200275 std::string endpoint("ldap");
276 std::string unit("");
277 std::string type("authority");
278 std::string verifyDir(certDir);
279 UnitsToRestart verifyUnit(unit);
280 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
281 auto event = sdeventplus::Event::get_default();
282 // Attach the bus to sd_event to service user requests
283 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
284 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
285 std::move(certDir));
286 MainApp mainApp(&manager);
287 mainApp.install(certificateFile);
288
289 std::vector<std::unique_ptr<Certificate>>& certs =
290 manager.getCertificates();
291
292 EXPECT_FALSE(certs.empty());
293
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200294 // Check that certificate has been created at installation directory
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100295 std::string verifyPath =
296 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200297 EXPECT_FALSE(fs::is_empty(verifyDir));
298 EXPECT_TRUE(fs::exists(verifyPath));
299
300 // Check that installed cert is identical to input one
301 EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
302
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100303 using NotAllowed =
304 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200305 EXPECT_THROW(
306 {
307 try
308 {
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100309 // Try to install the same certificate second time
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200310 mainApp.install(certificateFile);
311 }
312 catch (const NotAllowed& e)
313 {
314 throw;
315 }
316 },
317 NotAllowed);
318
319 // Check that the original certificate has been not removed
320 EXPECT_FALSE(fs::is_empty(verifyDir));
Marri Devender Rao947258d2018-09-25 10:52:24 -0500321 EXPECT_TRUE(fs::exists(verifyPath));
322}
323
Zbigniew Lukwinski73d1fbf2020-01-15 15:31:12 +0100324/** @brief Check if in authority mode user can install a certificate with
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100325 * certain subject hash twice.
326 */
327TEST_F(TestCertificates, InvokeInstallSameSubjectTwice)
328{
329 std::string endpoint("ldap");
330 std::string unit("");
331 std::string type("authority");
332 std::string verifyDir(certDir);
333 UnitsToRestart verifyUnit(unit);
334 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
335 auto event = sdeventplus::Event::get_default();
336 // Attach the bus to sd_event to service user requests
337 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
338 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
339 std::move(certDir));
340 MainApp mainApp(&manager);
341 mainApp.install(certificateFile);
342
343 std::vector<std::unique_ptr<Certificate>>& certs =
344 manager.getCertificates();
345
346 EXPECT_FALSE(certs.empty());
347
348 // Check that certificate has been created at installation directory
349 std::string verifyPath0 =
350 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
351 EXPECT_FALSE(fs::is_empty(verifyDir));
352 EXPECT_TRUE(fs::exists(verifyPath0));
353
354 // Check that installed cert is identical to input one
355 EXPECT_TRUE(compareFiles(certificateFile, verifyPath0));
356
357 // Prepare second certificate with the same subject
358 createNewCertificate();
359
Zbigniew Lukwinski73d1fbf2020-01-15 15:31:12 +0100360 // Install second certificate
361 mainApp.install(certificateFile);
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100362
363 // Expect there are exactly two certificates in the collection
Zbigniew Lukwinski73d1fbf2020-01-15 15:31:12 +0100364 EXPECT_EQ(certs.size(), 2);
365
366 // Check that certificate has been created at installation directory
367 std::string verifyPath1 =
368 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".1";
369 EXPECT_TRUE(fs::exists(verifyPath1));
370
371 // Check that installed cert is identical to input one
372 EXPECT_TRUE(compareFiles(certificateFile, verifyPath1));
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100373
374 // Check that the original/first certificate has been not removed
375 EXPECT_FALSE(fs::is_empty(verifyDir));
376 EXPECT_TRUE(fs::exists(verifyPath0));
377}
378
379/** @brief Check if in authority mode user can't install more than
380 * AUTHORITY_CERTIFICATES_LIMIT certificates.
381 */
382TEST_F(TestCertificates, InvokeInstallAuthCertLimit)
383{
384 std::string endpoint("ldap");
385 std::string unit("");
386 std::string type("authority");
387 std::string verifyDir(certDir);
388 UnitsToRestart verifyUnit(unit);
389 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
390 auto event = sdeventplus::Event::get_default();
391 // Attach the bus to sd_event to service user requests
392 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
393 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
394 std::move(certDir));
395 MainApp mainApp(&manager);
396
397 std::vector<std::unique_ptr<Certificate>>& certs =
398 manager.getCertificates();
399
400 std::vector<std::string> verifyPaths;
401
402 // Prepare maximum number of ceritificates
403 for (std::size_t i = 0; i < AUTHORITY_CERTIFICATES_LIMIT; ++i)
404 {
405 // Prepare new certificatate
406 createNewCertificate(true);
407
408 // Install ceritificate
409 mainApp.install(certificateFile);
410
411 // Check number of certificates in the collection
412 EXPECT_EQ(certs.size(), i + 1);
413
414 // Check that certificate has been created at installation directory
415 std::string verifyPath =
416 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
417 EXPECT_FALSE(fs::is_empty(verifyDir));
418 EXPECT_TRUE(fs::exists(verifyPath));
419
420 // Check that installed cert is identical to input one
421 EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
422
423 // Save current certificate file for later check
424 verifyPaths.push_back(verifyPath);
425 }
426
427 // Prepare new certificatate
428 createNewCertificate(true);
429
430 using NotAllowed =
431 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
432 EXPECT_THROW(
433 {
434 try
435 {
436 // Try to install one more certificate
437 mainApp.install(certificateFile);
438 }
439 catch (const NotAllowed& e)
440 {
441 throw;
442 }
443 },
444 NotAllowed);
445
446 // Check that the original certificate has been not removed
447 EXPECT_FALSE(fs::is_empty(verifyDir));
448 for (int i = 0; i < AUTHORITY_CERTIFICATES_LIMIT; ++i)
449 {
450 EXPECT_TRUE(fs::exists(verifyPaths[i]));
451 }
452}
453
Marri Devender Rao947258d2018-09-25 10:52:24 -0500454/** @brief Compare the installed certificate with the copied certificate
455 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600456TEST_F(TestCertificates, CompareInstalledCertificate)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500457{
458 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600459 std::string unit("");
Marri Devender Rao947258d2018-09-25 10:52:24 -0500460 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600461 std::string installPath(certDir + "/" + certificateFile);
462 std::string verifyPath(installPath);
463 UnitsToRestart verifyUnit(unit);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500464 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500465 auto event = sdeventplus::Event::get_default();
466 // Attach the bus to sd_event to service user requests
467 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
468 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
469 std::move(installPath));
470 MainApp mainApp(&manager);
471 mainApp.install(certificateFile);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500472 EXPECT_TRUE(fs::exists(verifyPath));
473 EXPECT_TRUE(compareFiles(verifyPath, certificateFile));
474}
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500475
476/** @brief Check if install fails if certificate file is not found
477 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600478TEST_F(TestCertificates, TestNoCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500479{
480 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600481 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500482 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600483 std::string installPath(certDir + "/" + certificateFile);
484 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500485 std::string verifyUnit(unit);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500486 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600487 std::string uploadFile = "nofile.pem";
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500488 EXPECT_THROW(
489 {
490 try
491 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500492 auto event = sdeventplus::Event::get_default();
493 // Attach the bus to sd_event to service user requests
494 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
495 Manager manager(bus, event, objPath.c_str(), type,
496 std::move(unit), std::move(installPath));
497 MainApp mainApp(&manager);
498 mainApp.install(uploadFile);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500499 }
500 catch (const InternalFailure& e)
501 {
502 throw;
503 }
504 },
505 InternalFailure);
506 EXPECT_FALSE(fs::exists(verifyPath));
507}
508
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500509/** @brief Test replacing existing certificate
510 */
511TEST_F(TestCertificates, TestReplaceCertificate)
512{
513 std::string endpoint("ldap");
514 std::string unit("");
515 std::string type("server");
516 std::string installPath(certDir + "/" + certificateFile);
517 std::string verifyPath(installPath);
518 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
519 auto event = sdeventplus::Event::get_default();
520 // Attach the bus to sd_event to service user requests
521 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
522 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
523 std::move(installPath));
524 MainApp mainApp(&manager);
525 mainApp.install(certificateFile);
526 EXPECT_TRUE(fs::exists(verifyPath));
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200527 std::vector<std::unique_ptr<Certificate>>& certs =
528 manager.getCertificates();
529 EXPECT_FALSE(certs.empty());
530 EXPECT_NE(certs[0], nullptr);
531 certs[0]->replace(certificateFile);
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500532 EXPECT_TRUE(fs::exists(verifyPath));
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200533}
534
535/** @brief Test replacing existing certificate
536 */
537TEST_F(TestCertificates, TestAuthorityReplaceCertificate)
538{
539 std::string endpoint("ldap");
540 std::string unit("");
541 std::string type("authority");
542 std::string verifyDir(certDir);
543 UnitsToRestart verifyUnit(unit);
544 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
545 auto event = sdeventplus::Event::get_default();
546 // Attach the bus to sd_event to service user requests
547 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
548 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
549 std::move(certDir));
550 MainApp mainApp(&manager);
551 mainApp.install(certificateFile);
552
553 std::vector<std::unique_ptr<Certificate>>& certs =
554 manager.getCertificates();
555 constexpr const unsigned int REPLACE_ITERATIONS = 10;
556
557 for (unsigned int i = 0; i < REPLACE_ITERATIONS; i++)
558 {
559 // Certificate successfully installed
560 EXPECT_FALSE(certs.empty());
561
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100562 std::string verifyPath =
563 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200564
565 // Check that certificate has been created at installation directory
566 EXPECT_FALSE(fs::is_empty(verifyDir));
567 EXPECT_TRUE(fs::exists(verifyPath));
568
569 // Check that installed cert is identical to input one
570 EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
571
572 // Create new certificate
573 createNewCertificate(true);
574
575 certs[0]->replace(certificateFile);
576
577 // Verify that old certificate has been removed
578 EXPECT_FALSE(fs::exists(verifyPath));
579 }
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500580}
581
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +0200582/** @brief Test verifiing if delete function works.
583 */
584TEST_F(TestCertificates, TestStorageDeleteCertificate)
585{
586 std::string endpoint("ldap");
587 std::string unit("");
588 std::string type("authority");
589 std::string verifyDir(certDir);
590 UnitsToRestart verifyUnit(unit);
591 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
592 auto event = sdeventplus::Event::get_default();
593 // Attach the bus to sd_event to service user requests
594 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
595 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
596 std::move(certDir));
597 MainApp mainApp(&manager);
598
599 // Check if certificate placeholder dir is empty
600 EXPECT_TRUE(fs::is_empty(verifyDir));
601 mainApp.install(certificateFile);
602
603 // Create new certificate
604 createNewCertificate(true);
605 mainApp.install(certificateFile);
606
607 createNewCertificate(true);
608 mainApp.install(certificateFile);
609
610 std::vector<std::unique_ptr<Certificate>>& certs =
611 manager.getCertificates();
612
613 // All 3 certificates successfully installed and added to manager
614 EXPECT_EQ(certs.size(), 3);
615
616 // Check if certificate placeholder is not empty, there should be 3
617 // certificates
618 EXPECT_FALSE(fs::is_empty(verifyDir));
619
620 certs[0]->delete_();
621 EXPECT_EQ(certs.size(), 2);
622
623 certs[0]->delete_();
624 EXPECT_EQ(certs.size(), 1);
625
626 certs[0]->delete_();
627 EXPECT_EQ(certs.size(), 0);
628
629 // Check if certificate placeholder is empty.
630 EXPECT_TRUE(fs::is_empty(verifyDir));
631}
632
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500633/** @brief Check if install fails if certificate file is empty
634 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600635TEST_F(TestCertificates, TestEmptyCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500636{
637 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600638 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500639 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600640 std::string installPath(certDir + "/" + certificateFile);
641 std::string verifyPath(installPath);
642 std::string verifyUnit(unit);
643 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500644 std::string emptyFile("emptycert.pem");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500645 std::ofstream ofs;
646 ofs.open(emptyFile, std::ofstream::out);
647 ofs.close();
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500648 EXPECT_THROW(
649 {
650 try
651 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500652 auto event = sdeventplus::Event::get_default();
653 // Attach the bus to sd_event to service user requests
654 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
655 Manager manager(bus, event, objPath.c_str(), type,
656 std::move(unit), std::move(installPath));
657 MainApp mainApp(&manager);
658 mainApp.install(emptyFile);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500659 }
660 catch (const InvalidCertificate& e)
661 {
662 throw;
663 }
664 },
665 InvalidCertificate);
666 EXPECT_FALSE(fs::exists(verifyPath));
667 fs::remove(emptyFile);
668}
669
Marri Devender Raoddf64862018-10-03 07:11:02 -0500670/** @brief Check if install fails if certificate file is corrupted
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500671 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600672TEST_F(TestCertificates, TestInvalidCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500673{
674 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600675 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500676 std::string type("client");
677
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500678 std::ofstream ofs;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500679 ofs.open(certificateFile, std::ofstream::out);
680 ofs << "-----BEGIN CERTIFICATE-----";
681 ofs << "ADD_SOME_INVALID_DATA_INTO_FILE";
682 ofs << "-----END CERTIFICATE-----";
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500683 ofs.close();
684
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600685 std::string installPath(certDir + "/" + certificateFile);
686 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500687 std::string verifyUnit(unit);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500688 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500689 EXPECT_THROW(
690 {
691 try
692 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500693 auto event = sdeventplus::Event::get_default();
694 // Attach the bus to sd_event to service user requests
695 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
696 Manager manager(bus, event, objPath.c_str(), type,
697 std::move(unit), std::move(installPath));
698 MainApp mainApp(&manager);
699 mainApp.install(certificateFile);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500700 }
701 catch (const InvalidCertificate& e)
702 {
703 throw;
704 }
705 },
706 InvalidCertificate);
707 EXPECT_FALSE(fs::exists(verifyPath));
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500708}
Marri Devender Raoddf64862018-10-03 07:11:02 -0500709
710/**
711 * Class to generate private and certificate only file and test verification
712 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600713class TestInvalidCertificate : public ::testing::Test
Marri Devender Raoddf64862018-10-03 07:11:02 -0500714{
715 public:
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600716 TestInvalidCertificate() : bus(sdbusplus::bus::new_default())
Marri Devender Raoddf64862018-10-03 07:11:02 -0500717 {
718 }
719 void SetUp() override
720 {
721 char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
722 auto dirPtr = mkdtemp(dirTemplate);
723 if (dirPtr == NULL)
724 {
725 throw std::bad_alloc();
726 }
Zbigniew Lukwinskife590c42019-12-10 12:33:50 +0100727 certDir = std::string(dirPtr) + "/certs";
728 fs::create_directories(certDir);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500729 certificateFile = "cert.pem";
730 keyFile = "key.pem";
731 std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
732 cmd += "-keyout key.pem -out cert.pem -days 3650 ";
733 cmd += "-subj "
734 "/O=openbmc-project.xyz/CN=localhost"
735 " -nodes";
736
737 auto val = std::system(cmd.c_str());
738 if (val)
739 {
740 std::cout << "command Error: " << val << std::endl;
741 }
742 }
743 void TearDown() override
744 {
745 fs::remove_all(certDir);
746 fs::remove(certificateFile);
747 fs::remove(keyFile);
748 }
749
750 protected:
751 sdbusplus::bus::bus bus;
752 std::string certificateFile;
753 std::string keyFile;
754 std::string certDir;
755};
756
757/** @brief Check install fails if private key is missing in certificate file
758 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600759TEST_F(TestInvalidCertificate, TestMissingPrivateKey)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500760{
761 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600762 std::string unit("");
Marri Devender Raoddf64862018-10-03 07:11:02 -0500763 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600764 std::string installPath(certDir + "/" + certificateFile);
765 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500766 std::string verifyUnit(unit);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500767 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600768 EXPECT_THROW(
769 {
770 try
771 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500772 auto event = sdeventplus::Event::get_default();
773 // Attach the bus to sd_event to service user requests
774 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
775 Manager manager(bus, event, objPath.c_str(), type,
776 std::move(unit), std::move(installPath));
777 MainApp mainApp(&manager);
778 mainApp.install(certificateFile);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600779 }
Marri Devender Raocd30c492019-06-12 01:40:17 -0500780 catch (const InternalFailure& e)
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600781 {
782 throw;
783 }
784 },
Marri Devender Raocd30c492019-06-12 01:40:17 -0500785 InternalFailure);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600786 EXPECT_FALSE(fs::exists(verifyPath));
787}
788
789/** @brief Check install fails if ceritificate is missing in certificate file
790 */
791TEST_F(TestInvalidCertificate, TestMissingCeritificate)
792{
793 std::string endpoint("ldap");
794 std::string unit("");
795 std::string type("client");
796 std::string installPath(certDir + "/" + keyFile);
797 std::string verifyPath(installPath);
798 std::string verifyUnit(unit);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600799 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
800 EXPECT_THROW(
801 {
802 try
803 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500804 auto event = sdeventplus::Event::get_default();
805 // Attach the bus to sd_event to service user requests
806 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
807 Manager manager(bus, event, objPath.c_str(), type,
808 std::move(unit), std::move(installPath));
809 MainApp mainApp(&manager);
810 mainApp.install(keyFile);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500811 }
Marri Devender Raocd30c492019-06-12 01:40:17 -0500812 catch (const InternalFailure& e)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500813 {
814 throw;
815 }
816 },
817 InvalidCertificate);
818 EXPECT_FALSE(fs::exists(verifyPath));
819}
820
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600821/** @brief Check if error is thrown when multiple certificates are installed
822 * At present only one certificate per service is allowed
Marri Devender Raoddf64862018-10-03 07:11:02 -0500823 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600824TEST_F(TestCertificates, TestCertInstallNotAllowed)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500825{
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600826 using NotAllowed =
827 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500828 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600829 std::string unit("");
Marri Devender Raoddf64862018-10-03 07:11:02 -0500830 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600831 std::string installPath(certDir + "/" + certificateFile);
832 std::string verifyPath(installPath);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500833 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raof4682712019-03-19 05:00:28 -0500834 auto event = sdeventplus::Event::get_default();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500835 // Attach the bus to sd_event to service user requests
836 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
Marri Devender Raof4682712019-03-19 05:00:28 -0500837 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600838 std::move(installPath));
Marri Devender Raoddf64862018-10-03 07:11:02 -0500839 MainApp mainApp(&manager);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600840 mainApp.install(certificateFile);
841 EXPECT_TRUE(fs::exists(verifyPath));
Marri Devender Raoddf64862018-10-03 07:11:02 -0500842 EXPECT_THROW(
843 {
844 try
845 {
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600846 // install second certificate
847 mainApp.install(certificateFile);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500848 }
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600849 catch (const NotAllowed& e)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500850 {
851 throw;
852 }
853 },
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600854 NotAllowed);
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500855}
Marri Devender Raof4682712019-03-19 05:00:28 -0500856
857TEST_F(TestCertificates, TestGenerateCSR)
858{
859 std::string endpoint("https");
860 std::string unit("");
861 std::string type("Server");
862 std::string installPath(certDir + "/" + certificateFile);
863 std::string verifyPath(installPath);
864 std::string CSRPath(certDir + "/" + CSRFile);
865 std::string privateKeyPath(certDir + "/" + privateKeyFile);
866 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500867 std::string challengePassword("Password");
Marri Devender Raof4682712019-03-19 05:00:28 -0500868 std::string city("HYB");
869 std::string commonName("abc.com");
870 std::string contactPerson("Admin");
871 std::string country("IN");
872 std::string email("admin@in.ibm.com");
873 std::string givenName("givenName");
874 std::string initials("G");
875 int64_t keyBitLength(2048);
876 std::string keyCurveId("0");
877 std::string keyPairAlgorithm("RSA");
878 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
879 std::string organization("IBM");
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500880 std::string organizationalUnit("orgUnit");
Marri Devender Raof4682712019-03-19 05:00:28 -0500881 std::string state("TS");
882 std::string surname("surname");
883 std::string unstructuredName("unstructuredName");
884 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
885 auto event = sdeventplus::Event::get_default();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500886 // Attach the bus to sd_event to service user requests
887 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
Marri Devender Raof4682712019-03-19 05:00:28 -0500888 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
889 std::move(installPath));
890 Status status;
891 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
892 MainApp mainApp(&manager, &csr);
893 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
894 contactPerson, country, email, givenName, initials,
895 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
896 organization, organizationalUnit, state, surname,
897 unstructuredName);
898 std::string csrData("");
899 // generateCSR takes considerable time to create CSR and privateKey Files
900 EXPECT_FALSE(fs::exists(CSRPath));
901 EXPECT_FALSE(fs::exists(privateKeyPath));
902 EXPECT_THROW(
903 {
904 try
905 {
Patrick Williamse129be32021-04-30 20:35:19 -0500906#ifdef SDBUSPP_NEW_CAMELCASE
907 csrData = csr.csr();
908#else
Marri Devender Raof4682712019-03-19 05:00:28 -0500909 csrData = csr.cSR();
Patrick Williamse129be32021-04-30 20:35:19 -0500910#endif
Marri Devender Raof4682712019-03-19 05:00:28 -0500911 }
912 catch (const InternalFailure& e)
913 {
914 throw;
915 }
916 },
917 InternalFailure);
918 // wait for 10 sec to get CSR and privateKey Files generated
919 sleep(10);
920 EXPECT_TRUE(fs::exists(CSRPath));
921 EXPECT_TRUE(fs::exists(privateKeyPath));
Patrick Williamse129be32021-04-30 20:35:19 -0500922#ifdef SDBUSPP_NEW_CAMELCASE
923 csrData = csr.csr();
924#else
Marri Devender Raof4682712019-03-19 05:00:28 -0500925 csrData = csr.cSR();
Patrick Williamse129be32021-04-30 20:35:19 -0500926#endif
Marri Devender Raof4682712019-03-19 05:00:28 -0500927 ASSERT_NE("", csrData.c_str());
928}
929
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500930/** @brief Check if ECC key pair is generated when user is not given algorithm
931 * type. At present RSA and EC key pair algorithm are supported
932 */
933TEST_F(TestCertificates, TestGenerateCSRwithEmptyKeyPairAlgorithm)
934{
935 std::string endpoint("https");
936 std::string unit("");
937 std::string type("Server");
938 std::string installPath(certDir + "/" + certificateFile);
939 std::string verifyPath(installPath);
940 std::string CSRPath(certDir + "/" + CSRFile);
941 std::string privateKeyPath(certDir + "/" + privateKeyFile);
942 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
943 std::string challengePassword("Password");
944 std::string city("HYB");
945 std::string commonName("abc.com");
946 std::string contactPerson("Admin");
947 std::string country("IN");
948 std::string email("admin@in.ibm.com");
949 std::string givenName("givenName");
950 std::string initials("G");
951 int64_t keyBitLength(2048);
952 std::string keyCurveId("");
953 std::string keyPairAlgorithm("");
954 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
955 std::string organization("IBM");
956 std::string organizationalUnit("orgUnit");
957 std::string state("TS");
958 std::string surname("surname");
959 std::string unstructuredName("unstructuredName");
Marri Devender Raof4682712019-03-19 05:00:28 -0500960 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
961 auto event = sdeventplus::Event::get_default();
962 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
963 std::move(installPath));
964 Status status;
965 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
966 MainApp mainApp(&manager, &csr);
967 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
968 contactPerson, country, email, givenName, initials,
969 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
970 organization, organizationalUnit, state, surname,
971 unstructuredName);
972 sleep(10);
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500973 EXPECT_TRUE(fs::exists(CSRPath));
974 EXPECT_TRUE(fs::exists(privateKeyPath));
975}
976
977/** @brief Check if error is thrown when giving un supported key pair
978 * algorithm. At present RSA and EC key pair algorithm are supported
979 */
980TEST_F(TestCertificates, TestGenerateCSRwithUnsupportedKeyPairAlgorithm)
981{
982 std::string endpoint("https");
983 std::string unit("");
984 std::string type("Server");
985 std::string installPath(certDir + "/" + certificateFile);
986 std::string verifyPath(installPath);
987 std::string CSRPath(certDir + "/" + CSRFile);
988 std::string privateKeyPath(certDir + "/" + privateKeyFile);
989 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
990 std::string challengePassword("Password");
991 std::string city("HYB");
992 std::string commonName("abc.com");
993 std::string contactPerson("Admin");
994 std::string country("IN");
995 std::string email("admin@in.ibm.com");
996 std::string givenName("givenName");
997 std::string initials("G");
998 int64_t keyBitLength(2048);
999 std::string keyCurveId("secp521r1");
1000 std::string keyPairAlgorithm("UnSupportedAlgorithm");
1001 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1002 std::string organization("IBM");
1003 std::string organizationalUnit("orgUnit");
1004 std::string state("TS");
1005 std::string surname("surname");
1006 std::string unstructuredName("unstructuredName");
1007 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1008 auto event = sdeventplus::Event::get_default();
1009 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1010 std::move(installPath));
1011 Status status;
1012 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1013 MainApp mainApp(&manager, &csr);
1014 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1015 contactPerson, country, email, givenName, initials,
1016 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1017 organization, organizationalUnit, state, surname,
1018 unstructuredName);
Marri Devender Raof4682712019-03-19 05:00:28 -05001019 EXPECT_FALSE(fs::exists(CSRPath));
1020 EXPECT_FALSE(fs::exists(privateKeyPath));
1021}
Ramesh Iyyar8a09b522019-06-07 05:23:29 -05001022
1023/** @brief Check if error is thrown when NID_undef is returned for given key
1024 * curve id
1025 */
1026TEST_F(TestCertificates, TestECKeyGenerationwithNIDundefCase)
1027{
1028 std::string endpoint("https");
1029 std::string unit("");
1030 std::string type("Server");
1031 std::string installPath(certDir + "/" + certificateFile);
1032 std::string verifyPath(installPath);
1033 std::string CSRPath(certDir + "/" + CSRFile);
1034 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1035 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1036 std::string challengePassword("Password");
1037 std::string city("BLR");
1038 std::string commonName("abc.com");
1039 std::string contactPerson("Admin");
1040 std::string country("IN");
1041 std::string email("admin@in.ibm.com");
1042 std::string givenName("givenName");
1043 std::string initials("G");
1044 int64_t keyBitLength(2048);
1045 std::string keyCurveId("DummyCurveName");
1046 std::string keyPairAlgorithm("EC");
1047 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1048 std::string organization("IBM");
1049 std::string organizationalUnit("orgUnit");
1050 std::string state("TS");
1051 std::string surname("surname");
1052 std::string unstructuredName("unstructuredName");
1053 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1054 auto event = sdeventplus::Event::get_default();
1055 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1056 std::move(installPath));
1057 Status status;
1058 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1059 MainApp mainApp(&manager, &csr);
1060 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1061 contactPerson, country, email, givenName, initials,
1062 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1063 organization, organizationalUnit, state, surname,
1064 unstructuredName);
1065 EXPECT_FALSE(fs::exists(CSRPath));
1066 EXPECT_FALSE(fs::exists(privateKeyPath));
1067}
1068
1069/** @brief Check default Key Curve Id is used if given curve id is empty
1070 */
1071TEST_F(TestCertificates, TestECKeyGenerationwithDefaultKeyCurveId)
1072{
1073 std::string endpoint("https");
1074 std::string unit("");
1075 std::string type("Server");
1076 std::string installPath(certDir + "/" + certificateFile);
1077 std::string verifyPath(installPath);
1078 std::string CSRPath(certDir + "/" + CSRFile);
1079 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1080 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1081 std::string challengePassword("Password");
1082 std::string city("BLR");
1083 std::string commonName("abc.com");
1084 std::string contactPerson("Admin");
1085 std::string country("IN");
1086 std::string email("admin@in.ibm.com");
1087 std::string givenName("givenName");
1088 std::string initials("G");
1089 int64_t keyBitLength(2048);
1090 std::string keyCurveId("");
1091 std::string keyPairAlgorithm("EC");
1092 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1093 std::string organization("IBM");
1094 std::string organizationalUnit("orgUnit");
1095 std::string state("TS");
1096 std::string surname("surname");
1097 std::string unstructuredName("unstructuredName");
1098 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1099 auto event = sdeventplus::Event::get_default();
1100 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1101 std::move(installPath));
1102 Status status;
1103 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1104 MainApp mainApp(&manager, &csr);
1105 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1106 contactPerson, country, email, givenName, initials,
1107 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1108 organization, organizationalUnit, state, surname,
1109 unstructuredName);
1110 sleep(10);
1111 EXPECT_TRUE(fs::exists(CSRPath));
1112 EXPECT_TRUE(fs::exists(privateKeyPath));
1113}
1114
1115/** @brief Check if error is not thrown to generate EC key pair
1116 */
1117TEST_F(TestCertificates, TestECKeyGeneration)
1118{
1119 std::string endpoint("https");
1120 std::string unit("");
1121 std::string type("Server");
1122 std::string installPath(certDir + "/" + certificateFile);
1123 std::string verifyPath(installPath);
1124 std::string CSRPath(certDir + "/" + CSRFile);
1125 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1126 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1127 std::string challengePassword("Password");
1128 std::string city("BLR");
1129 std::string commonName("abc.com");
1130 std::string contactPerson("Admin");
1131 std::string country("IN");
1132 std::string email("admin@in.ibm.com");
1133 std::string givenName("givenName");
1134 std::string initials("G");
1135 int64_t keyBitLength(2048);
1136 std::string keyCurveId("secp521r1");
1137 std::string keyPairAlgorithm("EC");
1138 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1139 std::string organization("IBM");
1140 std::string organizationalUnit("orgUnit");
1141 std::string state("TS");
1142 std::string surname("surname");
1143 std::string unstructuredName("unstructuredName");
1144 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1145 auto event = sdeventplus::Event::get_default();
1146 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1147 std::move(installPath));
1148 Status status;
1149 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1150 MainApp mainApp(&manager, &csr);
1151 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1152 contactPerson, country, email, givenName, initials,
1153 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1154 organization, organizationalUnit, state, surname,
1155 unstructuredName);
1156 std::cout << "CSRPath: " << CSRPath << std::endl
1157 << "privateKeyPath: " << privateKeyPath << std::endl;
1158 sleep(10);
1159 EXPECT_TRUE(fs::exists(CSRPath));
1160 EXPECT_TRUE(fs::exists(privateKeyPath));
1161}
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -05001162
1163/** @brief Check error is thrown if giving unsupported ket bit length to
1164 * generate rsa key
1165 */
1166TEST_F(TestCertificates, TestRSAKeyWithUnsupportedKeyBitLength)
1167{
1168 std::string endpoint("https");
1169 std::string unit("");
1170 std::string type("Server");
1171 std::string installPath(certDir + "/" + certificateFile);
1172 std::string verifyPath(installPath);
1173 std::string CSRPath(certDir + "/" + CSRFile);
1174 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1175 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1176 std::string challengePassword("Password");
1177 std::string city("BLR");
1178 std::string commonName("abc.com");
1179 std::string contactPerson("Admin");
1180 std::string country("IN");
1181 std::string email("admin@in.ibm.com");
1182 std::string givenName("givenName");
1183 std::string initials("G");
1184 int64_t keyBitLength(4096);
1185 std::string keyCurveId("secp521r1");
1186 std::string keyPairAlgorithm("RSA");
1187 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1188 std::string organization("IBM");
1189 std::string organizationalUnit("orgUnit");
1190 std::string state("TS");
1191 std::string surname("surname");
1192 std::string unstructuredName("unstructuredName");
1193 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1194 auto event = sdeventplus::Event::get_default();
1195 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1196 std::move(installPath));
1197 Status status;
1198 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1199 MainApp mainApp(&manager, &csr);
1200 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1201 contactPerson, country, email, givenName, initials,
1202 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1203 organization, organizationalUnit, state, surname,
1204 unstructuredName);
1205 EXPECT_FALSE(fs::exists(CSRPath));
1206 EXPECT_FALSE(fs::exists(privateKeyPath));
1207}
1208
1209/** @brief Check error is thrown if generated rsa key file is not present
1210 */
1211TEST_F(TestCertificates, TestRSAKeyFileNotPresentCase)
1212{
1213 std::string endpoint("https");
1214 std::string unit("");
1215 std::string type("Server");
1216 std::string installPath(certDir + "/" + certificateFile);
1217 std::string verifyPath(installPath);
1218 std::string CSRPath(certDir + "/" + CSRFile);
1219 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1220 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1221 std::string challengePassword("Password");
1222 std::string city("BLR");
1223 std::string commonName("abc.com");
1224 std::string contactPerson("Admin");
1225 std::string country("IN");
1226 std::string email("admin@in.ibm.com");
1227 std::string givenName("givenName");
1228 std::string initials("G");
1229 int64_t keyBitLength(2048);
1230 std::string keyCurveId("secp521r1");
1231 std::string keyPairAlgorithm("RSA");
1232 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1233 std::string organization("IBM");
1234 std::string organizationalUnit("orgUnit");
1235 std::string state("TS");
1236 std::string surname("surname");
1237 std::string unstructuredName("unstructuredName");
1238 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1239 auto event = sdeventplus::Event::get_default();
1240 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1241 std::move(installPath));
1242
1243 // Removing generated RSA key file
1244 fs::remove(rsaPrivateKeyFilePath);
1245
1246 Status status;
1247 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1248 MainApp mainApp(&manager, &csr);
1249 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1250 contactPerson, country, email, givenName, initials,
1251 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1252 organization, organizationalUnit, state, surname,
1253 unstructuredName);
1254 EXPECT_FALSE(fs::exists(CSRPath));
1255 EXPECT_FALSE(fs::exists(privateKeyPath));
1256}
1257
1258/** @brief Check private key file is created from generated rsa key file is
1259 * `present
1260 */
1261TEST_F(TestCertificates, TestRSAKeyFromRSAKeyFileIsWrittenIntoPrivateKeyFile)
1262{
1263 std::string endpoint("https");
1264 std::string unit("");
1265 std::string type("Server");
1266 std::string installPath(certDir + "/" + certificateFile);
1267 std::string verifyPath(installPath);
1268 std::string CSRPath(certDir + "/" + CSRFile);
1269 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1270 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1271 std::string challengePassword("Password");
1272 std::string city("BLR");
1273 std::string commonName("abc.com");
1274 std::string contactPerson("Admin");
1275 std::string country("IN");
1276 std::string email("admin@in.ibm.com");
1277 std::string givenName("givenName");
1278 std::string initials("G");
1279 int64_t keyBitLength(2048);
1280 std::string keyCurveId("secp521r1");
1281 std::string keyPairAlgorithm("RSA");
1282 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1283 std::string organization("IBM");
1284 std::string organizationalUnit("orgUnit");
1285 std::string state("TS");
1286 std::string surname("surname");
1287 std::string unstructuredName("unstructuredName");
1288 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1289 auto event = sdeventplus::Event::get_default();
1290 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1291 std::move(installPath));
1292 Status status;
1293 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1294 MainApp mainApp(&manager, &csr);
1295 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1296 contactPerson, country, email, givenName, initials,
1297 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1298 organization, organizationalUnit, state, surname,
1299 unstructuredName);
1300 sleep(10);
1301 EXPECT_TRUE(fs::exists(CSRPath));
1302 EXPECT_TRUE(fs::exists(privateKeyPath));
1303}
1304
1305/** @brief Check RSA key is generted during application startup*/
1306TEST_F(TestCertificates, TestGenerateRSAPrivateKeyFile)
1307{
1308 std::string endpoint("https");
1309 std::string unit("");
1310 std::string type("Server");
1311 std::string installPath(certDir + "/" + certificateFile);
1312 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1313 auto event = sdeventplus::Event::get_default();
1314
1315 EXPECT_FALSE(fs::exists(rsaPrivateKeyFilePath));
1316 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1317 std::move(installPath));
1318 EXPECT_TRUE(fs::exists(rsaPrivateKeyFilePath));
1319}