blob: 30f0dd10fd5d295f76642b3ccfd2a5dce732b25d [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),
149 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 }
179 std::string cSR()
180 {
181 return (csr->cSR());
182 }
Marri Devender Rao947258d2018-09-25 10:52:24 -0500183 phosphor::certs::Manager* manager;
Marri Devender Raof4682712019-03-19 05:00:28 -0500184 phosphor::certs::CSR* csr;
Marri Devender Rao947258d2018-09-25 10:52:24 -0500185};
186
Marri Devender Rao947258d2018-09-25 10:52:24 -0500187/** @brief Check if server install routine is invoked for server setup
188 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600189TEST_F(TestCertificates, InvokeServerInstall)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500190{
191 std::string endpoint("https");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600192 std::string unit("");
Marri Devender Rao947258d2018-09-25 10:52:24 -0500193 std::string type("server");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600194 std::string installPath(certDir + "/" + certificateFile);
195 std::string verifyPath(installPath);
196 UnitsToRestart verifyUnit(unit);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500197 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500198 auto event = sdeventplus::Event::get_default();
199 // Attach the bus to sd_event to service user requests
200 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
201 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
202 std::move(installPath));
203 MainApp mainApp(&manager);
204 mainApp.install(certificateFile);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500205 EXPECT_TRUE(fs::exists(verifyPath));
206}
207
208/** @brief Check if client install routine is invoked for client setup
209 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600210TEST_F(TestCertificates, InvokeClientInstall)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500211{
212 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600213 std::string unit("");
214 std::string type("server");
215 std::string installPath(certDir + "/" + certificateFile);
216 std::string verifyPath(installPath);
217 UnitsToRestart verifyUnit(unit);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500218 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500219 auto event = sdeventplus::Event::get_default();
220 // Attach the bus to sd_event to service user requests
221 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
222 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
223 std::move(installPath));
224 MainApp mainApp(&manager);
225 mainApp.install(certificateFile);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500226 EXPECT_TRUE(fs::exists(verifyPath));
227}
228
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200229/** @brief Check if storage install routine is invoked for storage setup
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500230 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600231TEST_F(TestCertificates, InvokeAuthorityInstall)
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500232{
233 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600234 std::string unit("");
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500235 std::string type("authority");
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200236 std::string verifyDir(certDir);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600237 UnitsToRestart verifyUnit(unit);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500238 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500239 auto event = sdeventplus::Event::get_default();
240 // Attach the bus to sd_event to service user requests
241 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
242 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200243 std::move(certDir));
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500244 MainApp mainApp(&manager);
245 mainApp.install(certificateFile);
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200246
247 std::vector<std::unique_ptr<Certificate>>& certs =
248 manager.getCertificates();
249
250 EXPECT_FALSE(certs.empty());
251
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100252 std::string verifyPath =
253 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200254
255 // Check that certificate has been created at installation directory
256 EXPECT_FALSE(fs::is_empty(verifyDir));
257 EXPECT_TRUE(fs::exists(verifyPath));
258
259 // Check that installed cert is identical to input one
260 EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
261}
262
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100263/** @brief Check if in authority mode user can't install the same
264 * certificate twice.
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200265 */
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100266TEST_F(TestCertificates, InvokeInstallSameCertTwice)
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200267{
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200268 std::string endpoint("ldap");
269 std::string unit("");
270 std::string type("authority");
271 std::string verifyDir(certDir);
272 UnitsToRestart verifyUnit(unit);
273 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
274 auto event = sdeventplus::Event::get_default();
275 // Attach the bus to sd_event to service user requests
276 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
277 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
278 std::move(certDir));
279 MainApp mainApp(&manager);
280 mainApp.install(certificateFile);
281
282 std::vector<std::unique_ptr<Certificate>>& certs =
283 manager.getCertificates();
284
285 EXPECT_FALSE(certs.empty());
286
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200287 // Check that certificate has been created at installation directory
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100288 std::string verifyPath =
289 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200290 EXPECT_FALSE(fs::is_empty(verifyDir));
291 EXPECT_TRUE(fs::exists(verifyPath));
292
293 // Check that installed cert is identical to input one
294 EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
295
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100296 using NotAllowed =
297 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200298 EXPECT_THROW(
299 {
300 try
301 {
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100302 // Try to install the same certificate second time
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200303 mainApp.install(certificateFile);
304 }
305 catch (const NotAllowed& e)
306 {
307 throw;
308 }
309 },
310 NotAllowed);
311
312 // Check that the original certificate has been not removed
313 EXPECT_FALSE(fs::is_empty(verifyDir));
Marri Devender Rao947258d2018-09-25 10:52:24 -0500314 EXPECT_TRUE(fs::exists(verifyPath));
315}
316
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100317/** @brief Check if in authority mode user cannot install a certificate with
318 * certain subject hash twice.
319 */
320TEST_F(TestCertificates, InvokeInstallSameSubjectTwice)
321{
322 std::string endpoint("ldap");
323 std::string unit("");
324 std::string type("authority");
325 std::string verifyDir(certDir);
326 UnitsToRestart verifyUnit(unit);
327 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
328 auto event = sdeventplus::Event::get_default();
329 // Attach the bus to sd_event to service user requests
330 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
331 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
332 std::move(certDir));
333 MainApp mainApp(&manager);
334 mainApp.install(certificateFile);
335
336 std::vector<std::unique_ptr<Certificate>>& certs =
337 manager.getCertificates();
338
339 EXPECT_FALSE(certs.empty());
340
341 // Check that certificate has been created at installation directory
342 std::string verifyPath0 =
343 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
344 EXPECT_FALSE(fs::is_empty(verifyDir));
345 EXPECT_TRUE(fs::exists(verifyPath0));
346
347 // Check that installed cert is identical to input one
348 EXPECT_TRUE(compareFiles(certificateFile, verifyPath0));
349
350 // Prepare second certificate with the same subject
351 createNewCertificate();
352
353 using NotAllowed =
354 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
355 EXPECT_THROW(
356 {
357 try
358 {
359 // Install second certificate
360 mainApp.install(certificateFile);
361 }
362 catch (const NotAllowed& e)
363 {
364 throw;
365 }
366 },
367 NotAllowed);
368
369 // Expect there are exactly two certificates in the collection
370 EXPECT_EQ(certs.size(), 1);
371
372 // Check that the original/first certificate has been not removed
373 EXPECT_FALSE(fs::is_empty(verifyDir));
374 EXPECT_TRUE(fs::exists(verifyPath0));
375}
376
377/** @brief Check if in authority mode user can't install more than
378 * AUTHORITY_CERTIFICATES_LIMIT certificates.
379 */
380TEST_F(TestCertificates, InvokeInstallAuthCertLimit)
381{
382 std::string endpoint("ldap");
383 std::string unit("");
384 std::string type("authority");
385 std::string verifyDir(certDir);
386 UnitsToRestart verifyUnit(unit);
387 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
388 auto event = sdeventplus::Event::get_default();
389 // Attach the bus to sd_event to service user requests
390 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
391 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
392 std::move(certDir));
393 MainApp mainApp(&manager);
394
395 std::vector<std::unique_ptr<Certificate>>& certs =
396 manager.getCertificates();
397
398 std::vector<std::string> verifyPaths;
399
400 // Prepare maximum number of ceritificates
401 for (std::size_t i = 0; i < AUTHORITY_CERTIFICATES_LIMIT; ++i)
402 {
403 // Prepare new certificatate
404 createNewCertificate(true);
405
406 // Install ceritificate
407 mainApp.install(certificateFile);
408
409 // Check number of certificates in the collection
410 EXPECT_EQ(certs.size(), i + 1);
411
412 // Check that certificate has been created at installation directory
413 std::string verifyPath =
414 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
415 EXPECT_FALSE(fs::is_empty(verifyDir));
416 EXPECT_TRUE(fs::exists(verifyPath));
417
418 // Check that installed cert is identical to input one
419 EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
420
421 // Save current certificate file for later check
422 verifyPaths.push_back(verifyPath);
423 }
424
425 // Prepare new certificatate
426 createNewCertificate(true);
427
428 using NotAllowed =
429 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
430 EXPECT_THROW(
431 {
432 try
433 {
434 // Try to install one more certificate
435 mainApp.install(certificateFile);
436 }
437 catch (const NotAllowed& e)
438 {
439 throw;
440 }
441 },
442 NotAllowed);
443
444 // Check that the original certificate has been not removed
445 EXPECT_FALSE(fs::is_empty(verifyDir));
446 for (int i = 0; i < AUTHORITY_CERTIFICATES_LIMIT; ++i)
447 {
448 EXPECT_TRUE(fs::exists(verifyPaths[i]));
449 }
450}
451
Marri Devender Rao947258d2018-09-25 10:52:24 -0500452/** @brief Compare the installed certificate with the copied certificate
453 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600454TEST_F(TestCertificates, CompareInstalledCertificate)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500455{
456 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600457 std::string unit("");
Marri Devender Rao947258d2018-09-25 10:52:24 -0500458 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600459 std::string installPath(certDir + "/" + certificateFile);
460 std::string verifyPath(installPath);
461 UnitsToRestart verifyUnit(unit);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500462 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500463 auto event = sdeventplus::Event::get_default();
464 // Attach the bus to sd_event to service user requests
465 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
466 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
467 std::move(installPath));
468 MainApp mainApp(&manager);
469 mainApp.install(certificateFile);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500470 EXPECT_TRUE(fs::exists(verifyPath));
471 EXPECT_TRUE(compareFiles(verifyPath, certificateFile));
472}
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500473
474/** @brief Check if install fails if certificate file is not found
475 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600476TEST_F(TestCertificates, TestNoCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500477{
478 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600479 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500480 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600481 std::string installPath(certDir + "/" + certificateFile);
482 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500483 std::string verifyUnit(unit);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500484 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600485 std::string uploadFile = "nofile.pem";
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500486 EXPECT_THROW(
487 {
488 try
489 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500490 auto event = sdeventplus::Event::get_default();
491 // Attach the bus to sd_event to service user requests
492 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
493 Manager manager(bus, event, objPath.c_str(), type,
494 std::move(unit), std::move(installPath));
495 MainApp mainApp(&manager);
496 mainApp.install(uploadFile);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500497 }
498 catch (const InternalFailure& e)
499 {
500 throw;
501 }
502 },
503 InternalFailure);
504 EXPECT_FALSE(fs::exists(verifyPath));
505}
506
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500507/** @brief Test replacing existing certificate
508 */
509TEST_F(TestCertificates, TestReplaceCertificate)
510{
511 std::string endpoint("ldap");
512 std::string unit("");
513 std::string type("server");
514 std::string installPath(certDir + "/" + certificateFile);
515 std::string verifyPath(installPath);
516 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
517 auto event = sdeventplus::Event::get_default();
518 // Attach the bus to sd_event to service user requests
519 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
520 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
521 std::move(installPath));
522 MainApp mainApp(&manager);
523 mainApp.install(certificateFile);
524 EXPECT_TRUE(fs::exists(verifyPath));
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200525 std::vector<std::unique_ptr<Certificate>>& certs =
526 manager.getCertificates();
527 EXPECT_FALSE(certs.empty());
528 EXPECT_NE(certs[0], nullptr);
529 certs[0]->replace(certificateFile);
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500530 EXPECT_TRUE(fs::exists(verifyPath));
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200531}
532
533/** @brief Test replacing existing certificate
534 */
535TEST_F(TestCertificates, TestAuthorityReplaceCertificate)
536{
537 std::string endpoint("ldap");
538 std::string unit("");
539 std::string type("authority");
540 std::string verifyDir(certDir);
541 UnitsToRestart verifyUnit(unit);
542 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
543 auto event = sdeventplus::Event::get_default();
544 // Attach the bus to sd_event to service user requests
545 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
546 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
547 std::move(certDir));
548 MainApp mainApp(&manager);
549 mainApp.install(certificateFile);
550
551 std::vector<std::unique_ptr<Certificate>>& certs =
552 manager.getCertificates();
553 constexpr const unsigned int REPLACE_ITERATIONS = 10;
554
555 for (unsigned int i = 0; i < REPLACE_ITERATIONS; i++)
556 {
557 // Certificate successfully installed
558 EXPECT_FALSE(certs.empty());
559
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100560 std::string verifyPath =
561 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200562
563 // Check that certificate has been created at installation directory
564 EXPECT_FALSE(fs::is_empty(verifyDir));
565 EXPECT_TRUE(fs::exists(verifyPath));
566
567 // Check that installed cert is identical to input one
568 EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
569
570 // Create new certificate
571 createNewCertificate(true);
572
573 certs[0]->replace(certificateFile);
574
575 // Verify that old certificate has been removed
576 EXPECT_FALSE(fs::exists(verifyPath));
577 }
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500578}
579
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +0200580/** @brief Test verifiing if delete function works.
581 */
582TEST_F(TestCertificates, TestStorageDeleteCertificate)
583{
584 std::string endpoint("ldap");
585 std::string unit("");
586 std::string type("authority");
587 std::string verifyDir(certDir);
588 UnitsToRestart verifyUnit(unit);
589 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
590 auto event = sdeventplus::Event::get_default();
591 // Attach the bus to sd_event to service user requests
592 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
593 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
594 std::move(certDir));
595 MainApp mainApp(&manager);
596
597 // Check if certificate placeholder dir is empty
598 EXPECT_TRUE(fs::is_empty(verifyDir));
599 mainApp.install(certificateFile);
600
601 // Create new certificate
602 createNewCertificate(true);
603 mainApp.install(certificateFile);
604
605 createNewCertificate(true);
606 mainApp.install(certificateFile);
607
608 std::vector<std::unique_ptr<Certificate>>& certs =
609 manager.getCertificates();
610
611 // All 3 certificates successfully installed and added to manager
612 EXPECT_EQ(certs.size(), 3);
613
614 // Check if certificate placeholder is not empty, there should be 3
615 // certificates
616 EXPECT_FALSE(fs::is_empty(verifyDir));
617
618 certs[0]->delete_();
619 EXPECT_EQ(certs.size(), 2);
620
621 certs[0]->delete_();
622 EXPECT_EQ(certs.size(), 1);
623
624 certs[0]->delete_();
625 EXPECT_EQ(certs.size(), 0);
626
627 // Check if certificate placeholder is empty.
628 EXPECT_TRUE(fs::is_empty(verifyDir));
629}
630
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500631/** @brief Check if install fails if certificate file is empty
632 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600633TEST_F(TestCertificates, TestEmptyCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500634{
635 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600636 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500637 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600638 std::string installPath(certDir + "/" + certificateFile);
639 std::string verifyPath(installPath);
640 std::string verifyUnit(unit);
641 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500642 std::string emptyFile("emptycert.pem");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500643 std::ofstream ofs;
644 ofs.open(emptyFile, std::ofstream::out);
645 ofs.close();
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500646 EXPECT_THROW(
647 {
648 try
649 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500650 auto event = sdeventplus::Event::get_default();
651 // Attach the bus to sd_event to service user requests
652 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
653 Manager manager(bus, event, objPath.c_str(), type,
654 std::move(unit), std::move(installPath));
655 MainApp mainApp(&manager);
656 mainApp.install(emptyFile);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500657 }
658 catch (const InvalidCertificate& e)
659 {
660 throw;
661 }
662 },
663 InvalidCertificate);
664 EXPECT_FALSE(fs::exists(verifyPath));
665 fs::remove(emptyFile);
666}
667
Marri Devender Raoddf64862018-10-03 07:11:02 -0500668/** @brief Check if install fails if certificate file is corrupted
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500669 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600670TEST_F(TestCertificates, TestInvalidCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500671{
672 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600673 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500674 std::string type("client");
675
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500676 std::ofstream ofs;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500677 ofs.open(certificateFile, std::ofstream::out);
678 ofs << "-----BEGIN CERTIFICATE-----";
679 ofs << "ADD_SOME_INVALID_DATA_INTO_FILE";
680 ofs << "-----END CERTIFICATE-----";
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500681 ofs.close();
682
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600683 std::string installPath(certDir + "/" + certificateFile);
684 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500685 std::string verifyUnit(unit);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500686 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500687 EXPECT_THROW(
688 {
689 try
690 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500691 auto event = sdeventplus::Event::get_default();
692 // Attach the bus to sd_event to service user requests
693 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
694 Manager manager(bus, event, objPath.c_str(), type,
695 std::move(unit), std::move(installPath));
696 MainApp mainApp(&manager);
697 mainApp.install(certificateFile);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500698 }
699 catch (const InvalidCertificate& e)
700 {
701 throw;
702 }
703 },
704 InvalidCertificate);
705 EXPECT_FALSE(fs::exists(verifyPath));
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500706}
Marri Devender Raoddf64862018-10-03 07:11:02 -0500707
708/**
709 * Class to generate private and certificate only file and test verification
710 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600711class TestInvalidCertificate : public ::testing::Test
Marri Devender Raoddf64862018-10-03 07:11:02 -0500712{
713 public:
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600714 TestInvalidCertificate() : bus(sdbusplus::bus::new_default())
Marri Devender Raoddf64862018-10-03 07:11:02 -0500715 {
716 }
717 void SetUp() override
718 {
719 char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
720 auto dirPtr = mkdtemp(dirTemplate);
721 if (dirPtr == NULL)
722 {
723 throw std::bad_alloc();
724 }
Zbigniew Lukwinskife590c42019-12-10 12:33:50 +0100725 certDir = std::string(dirPtr) + "/certs";
726 fs::create_directories(certDir);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500727 certificateFile = "cert.pem";
728 keyFile = "key.pem";
729 std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
730 cmd += "-keyout key.pem -out cert.pem -days 3650 ";
731 cmd += "-subj "
732 "/O=openbmc-project.xyz/CN=localhost"
733 " -nodes";
734
735 auto val = std::system(cmd.c_str());
736 if (val)
737 {
738 std::cout << "command Error: " << val << std::endl;
739 }
740 }
741 void TearDown() override
742 {
743 fs::remove_all(certDir);
744 fs::remove(certificateFile);
745 fs::remove(keyFile);
746 }
747
748 protected:
749 sdbusplus::bus::bus bus;
750 std::string certificateFile;
751 std::string keyFile;
752 std::string certDir;
753};
754
755/** @brief Check install fails if private key is missing in certificate file
756 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600757TEST_F(TestInvalidCertificate, TestMissingPrivateKey)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500758{
759 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600760 std::string unit("");
Marri Devender Raoddf64862018-10-03 07:11:02 -0500761 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600762 std::string installPath(certDir + "/" + certificateFile);
763 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500764 std::string verifyUnit(unit);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500765 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600766 EXPECT_THROW(
767 {
768 try
769 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500770 auto event = sdeventplus::Event::get_default();
771 // Attach the bus to sd_event to service user requests
772 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
773 Manager manager(bus, event, objPath.c_str(), type,
774 std::move(unit), std::move(installPath));
775 MainApp mainApp(&manager);
776 mainApp.install(certificateFile);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600777 }
Marri Devender Raocd30c492019-06-12 01:40:17 -0500778 catch (const InternalFailure& e)
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600779 {
780 throw;
781 }
782 },
Marri Devender Raocd30c492019-06-12 01:40:17 -0500783 InternalFailure);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600784 EXPECT_FALSE(fs::exists(verifyPath));
785}
786
787/** @brief Check install fails if ceritificate is missing in certificate file
788 */
789TEST_F(TestInvalidCertificate, TestMissingCeritificate)
790{
791 std::string endpoint("ldap");
792 std::string unit("");
793 std::string type("client");
794 std::string installPath(certDir + "/" + keyFile);
795 std::string verifyPath(installPath);
796 std::string verifyUnit(unit);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600797 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
798 EXPECT_THROW(
799 {
800 try
801 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500802 auto event = sdeventplus::Event::get_default();
803 // Attach the bus to sd_event to service user requests
804 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
805 Manager manager(bus, event, objPath.c_str(), type,
806 std::move(unit), std::move(installPath));
807 MainApp mainApp(&manager);
808 mainApp.install(keyFile);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500809 }
Marri Devender Raocd30c492019-06-12 01:40:17 -0500810 catch (const InternalFailure& e)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500811 {
812 throw;
813 }
814 },
815 InvalidCertificate);
816 EXPECT_FALSE(fs::exists(verifyPath));
817}
818
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600819/** @brief Check if error is thrown when multiple certificates are installed
820 * At present only one certificate per service is allowed
Marri Devender Raoddf64862018-10-03 07:11:02 -0500821 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600822TEST_F(TestCertificates, TestCertInstallNotAllowed)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500823{
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600824 using NotAllowed =
825 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500826 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600827 std::string unit("");
Marri Devender Raoddf64862018-10-03 07:11:02 -0500828 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600829 std::string installPath(certDir + "/" + certificateFile);
830 std::string verifyPath(installPath);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500831 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raof4682712019-03-19 05:00:28 -0500832 auto event = sdeventplus::Event::get_default();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500833 // Attach the bus to sd_event to service user requests
834 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
Marri Devender Raof4682712019-03-19 05:00:28 -0500835 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600836 std::move(installPath));
Marri Devender Raoddf64862018-10-03 07:11:02 -0500837 MainApp mainApp(&manager);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600838 mainApp.install(certificateFile);
839 EXPECT_TRUE(fs::exists(verifyPath));
Marri Devender Raoddf64862018-10-03 07:11:02 -0500840 EXPECT_THROW(
841 {
842 try
843 {
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600844 // install second certificate
845 mainApp.install(certificateFile);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500846 }
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600847 catch (const NotAllowed& e)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500848 {
849 throw;
850 }
851 },
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600852 NotAllowed);
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500853}
Marri Devender Raof4682712019-03-19 05:00:28 -0500854
855TEST_F(TestCertificates, TestGenerateCSR)
856{
857 std::string endpoint("https");
858 std::string unit("");
859 std::string type("Server");
860 std::string installPath(certDir + "/" + certificateFile);
861 std::string verifyPath(installPath);
862 std::string CSRPath(certDir + "/" + CSRFile);
863 std::string privateKeyPath(certDir + "/" + privateKeyFile);
864 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500865 std::string challengePassword("Password");
Marri Devender Raof4682712019-03-19 05:00:28 -0500866 std::string city("HYB");
867 std::string commonName("abc.com");
868 std::string contactPerson("Admin");
869 std::string country("IN");
870 std::string email("admin@in.ibm.com");
871 std::string givenName("givenName");
872 std::string initials("G");
873 int64_t keyBitLength(2048);
874 std::string keyCurveId("0");
875 std::string keyPairAlgorithm("RSA");
876 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
877 std::string organization("IBM");
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500878 std::string organizationalUnit("orgUnit");
Marri Devender Raof4682712019-03-19 05:00:28 -0500879 std::string state("TS");
880 std::string surname("surname");
881 std::string unstructuredName("unstructuredName");
882 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
883 auto event = sdeventplus::Event::get_default();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500884 // Attach the bus to sd_event to service user requests
885 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
Marri Devender Raof4682712019-03-19 05:00:28 -0500886 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
887 std::move(installPath));
888 Status status;
889 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
890 MainApp mainApp(&manager, &csr);
891 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
892 contactPerson, country, email, givenName, initials,
893 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
894 organization, organizationalUnit, state, surname,
895 unstructuredName);
896 std::string csrData("");
897 // generateCSR takes considerable time to create CSR and privateKey Files
898 EXPECT_FALSE(fs::exists(CSRPath));
899 EXPECT_FALSE(fs::exists(privateKeyPath));
900 EXPECT_THROW(
901 {
902 try
903 {
904 csrData = csr.cSR();
905 }
906 catch (const InternalFailure& e)
907 {
908 throw;
909 }
910 },
911 InternalFailure);
912 // wait for 10 sec to get CSR and privateKey Files generated
913 sleep(10);
914 EXPECT_TRUE(fs::exists(CSRPath));
915 EXPECT_TRUE(fs::exists(privateKeyPath));
916 csrData = csr.cSR();
917 ASSERT_NE("", csrData.c_str());
918}
919
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500920/** @brief Check if ECC key pair is generated when user is not given algorithm
921 * type. At present RSA and EC key pair algorithm are supported
922 */
923TEST_F(TestCertificates, TestGenerateCSRwithEmptyKeyPairAlgorithm)
924{
925 std::string endpoint("https");
926 std::string unit("");
927 std::string type("Server");
928 std::string installPath(certDir + "/" + certificateFile);
929 std::string verifyPath(installPath);
930 std::string CSRPath(certDir + "/" + CSRFile);
931 std::string privateKeyPath(certDir + "/" + privateKeyFile);
932 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
933 std::string challengePassword("Password");
934 std::string city("HYB");
935 std::string commonName("abc.com");
936 std::string contactPerson("Admin");
937 std::string country("IN");
938 std::string email("admin@in.ibm.com");
939 std::string givenName("givenName");
940 std::string initials("G");
941 int64_t keyBitLength(2048);
942 std::string keyCurveId("");
943 std::string keyPairAlgorithm("");
944 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
945 std::string organization("IBM");
946 std::string organizationalUnit("orgUnit");
947 std::string state("TS");
948 std::string surname("surname");
949 std::string unstructuredName("unstructuredName");
Marri Devender Raof4682712019-03-19 05:00:28 -0500950 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
951 auto event = sdeventplus::Event::get_default();
952 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
953 std::move(installPath));
954 Status status;
955 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
956 MainApp mainApp(&manager, &csr);
957 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
958 contactPerson, country, email, givenName, initials,
959 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
960 organization, organizationalUnit, state, surname,
961 unstructuredName);
962 sleep(10);
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500963 EXPECT_TRUE(fs::exists(CSRPath));
964 EXPECT_TRUE(fs::exists(privateKeyPath));
965}
966
967/** @brief Check if error is thrown when giving un supported key pair
968 * algorithm. At present RSA and EC key pair algorithm are supported
969 */
970TEST_F(TestCertificates, TestGenerateCSRwithUnsupportedKeyPairAlgorithm)
971{
972 std::string endpoint("https");
973 std::string unit("");
974 std::string type("Server");
975 std::string installPath(certDir + "/" + certificateFile);
976 std::string verifyPath(installPath);
977 std::string CSRPath(certDir + "/" + CSRFile);
978 std::string privateKeyPath(certDir + "/" + privateKeyFile);
979 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
980 std::string challengePassword("Password");
981 std::string city("HYB");
982 std::string commonName("abc.com");
983 std::string contactPerson("Admin");
984 std::string country("IN");
985 std::string email("admin@in.ibm.com");
986 std::string givenName("givenName");
987 std::string initials("G");
988 int64_t keyBitLength(2048);
989 std::string keyCurveId("secp521r1");
990 std::string keyPairAlgorithm("UnSupportedAlgorithm");
991 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
992 std::string organization("IBM");
993 std::string organizationalUnit("orgUnit");
994 std::string state("TS");
995 std::string surname("surname");
996 std::string unstructuredName("unstructuredName");
997 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
998 auto event = sdeventplus::Event::get_default();
999 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1000 std::move(installPath));
1001 Status status;
1002 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1003 MainApp mainApp(&manager, &csr);
1004 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1005 contactPerson, country, email, givenName, initials,
1006 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1007 organization, organizationalUnit, state, surname,
1008 unstructuredName);
Marri Devender Raof4682712019-03-19 05:00:28 -05001009 EXPECT_FALSE(fs::exists(CSRPath));
1010 EXPECT_FALSE(fs::exists(privateKeyPath));
1011}
Ramesh Iyyar8a09b522019-06-07 05:23:29 -05001012
1013/** @brief Check if error is thrown when NID_undef is returned for given key
1014 * curve id
1015 */
1016TEST_F(TestCertificates, TestECKeyGenerationwithNIDundefCase)
1017{
1018 std::string endpoint("https");
1019 std::string unit("");
1020 std::string type("Server");
1021 std::string installPath(certDir + "/" + certificateFile);
1022 std::string verifyPath(installPath);
1023 std::string CSRPath(certDir + "/" + CSRFile);
1024 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1025 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1026 std::string challengePassword("Password");
1027 std::string city("BLR");
1028 std::string commonName("abc.com");
1029 std::string contactPerson("Admin");
1030 std::string country("IN");
1031 std::string email("admin@in.ibm.com");
1032 std::string givenName("givenName");
1033 std::string initials("G");
1034 int64_t keyBitLength(2048);
1035 std::string keyCurveId("DummyCurveName");
1036 std::string keyPairAlgorithm("EC");
1037 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1038 std::string organization("IBM");
1039 std::string organizationalUnit("orgUnit");
1040 std::string state("TS");
1041 std::string surname("surname");
1042 std::string unstructuredName("unstructuredName");
1043 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1044 auto event = sdeventplus::Event::get_default();
1045 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1046 std::move(installPath));
1047 Status status;
1048 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1049 MainApp mainApp(&manager, &csr);
1050 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1051 contactPerson, country, email, givenName, initials,
1052 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1053 organization, organizationalUnit, state, surname,
1054 unstructuredName);
1055 EXPECT_FALSE(fs::exists(CSRPath));
1056 EXPECT_FALSE(fs::exists(privateKeyPath));
1057}
1058
1059/** @brief Check default Key Curve Id is used if given curve id is empty
1060 */
1061TEST_F(TestCertificates, TestECKeyGenerationwithDefaultKeyCurveId)
1062{
1063 std::string endpoint("https");
1064 std::string unit("");
1065 std::string type("Server");
1066 std::string installPath(certDir + "/" + certificateFile);
1067 std::string verifyPath(installPath);
1068 std::string CSRPath(certDir + "/" + CSRFile);
1069 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1070 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1071 std::string challengePassword("Password");
1072 std::string city("BLR");
1073 std::string commonName("abc.com");
1074 std::string contactPerson("Admin");
1075 std::string country("IN");
1076 std::string email("admin@in.ibm.com");
1077 std::string givenName("givenName");
1078 std::string initials("G");
1079 int64_t keyBitLength(2048);
1080 std::string keyCurveId("");
1081 std::string keyPairAlgorithm("EC");
1082 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1083 std::string organization("IBM");
1084 std::string organizationalUnit("orgUnit");
1085 std::string state("TS");
1086 std::string surname("surname");
1087 std::string unstructuredName("unstructuredName");
1088 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1089 auto event = sdeventplus::Event::get_default();
1090 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1091 std::move(installPath));
1092 Status status;
1093 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1094 MainApp mainApp(&manager, &csr);
1095 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1096 contactPerson, country, email, givenName, initials,
1097 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1098 organization, organizationalUnit, state, surname,
1099 unstructuredName);
1100 sleep(10);
1101 EXPECT_TRUE(fs::exists(CSRPath));
1102 EXPECT_TRUE(fs::exists(privateKeyPath));
1103}
1104
1105/** @brief Check if error is not thrown to generate EC key pair
1106 */
1107TEST_F(TestCertificates, TestECKeyGeneration)
1108{
1109 std::string endpoint("https");
1110 std::string unit("");
1111 std::string type("Server");
1112 std::string installPath(certDir + "/" + certificateFile);
1113 std::string verifyPath(installPath);
1114 std::string CSRPath(certDir + "/" + CSRFile);
1115 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1116 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1117 std::string challengePassword("Password");
1118 std::string city("BLR");
1119 std::string commonName("abc.com");
1120 std::string contactPerson("Admin");
1121 std::string country("IN");
1122 std::string email("admin@in.ibm.com");
1123 std::string givenName("givenName");
1124 std::string initials("G");
1125 int64_t keyBitLength(2048);
1126 std::string keyCurveId("secp521r1");
1127 std::string keyPairAlgorithm("EC");
1128 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1129 std::string organization("IBM");
1130 std::string organizationalUnit("orgUnit");
1131 std::string state("TS");
1132 std::string surname("surname");
1133 std::string unstructuredName("unstructuredName");
1134 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1135 auto event = sdeventplus::Event::get_default();
1136 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1137 std::move(installPath));
1138 Status status;
1139 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1140 MainApp mainApp(&manager, &csr);
1141 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1142 contactPerson, country, email, givenName, initials,
1143 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1144 organization, organizationalUnit, state, surname,
1145 unstructuredName);
1146 std::cout << "CSRPath: " << CSRPath << std::endl
1147 << "privateKeyPath: " << privateKeyPath << std::endl;
1148 sleep(10);
1149 EXPECT_TRUE(fs::exists(CSRPath));
1150 EXPECT_TRUE(fs::exists(privateKeyPath));
1151}
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -05001152
1153/** @brief Check error is thrown if giving unsupported ket bit length to
1154 * generate rsa key
1155 */
1156TEST_F(TestCertificates, TestRSAKeyWithUnsupportedKeyBitLength)
1157{
1158 std::string endpoint("https");
1159 std::string unit("");
1160 std::string type("Server");
1161 std::string installPath(certDir + "/" + certificateFile);
1162 std::string verifyPath(installPath);
1163 std::string CSRPath(certDir + "/" + CSRFile);
1164 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1165 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1166 std::string challengePassword("Password");
1167 std::string city("BLR");
1168 std::string commonName("abc.com");
1169 std::string contactPerson("Admin");
1170 std::string country("IN");
1171 std::string email("admin@in.ibm.com");
1172 std::string givenName("givenName");
1173 std::string initials("G");
1174 int64_t keyBitLength(4096);
1175 std::string keyCurveId("secp521r1");
1176 std::string keyPairAlgorithm("RSA");
1177 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1178 std::string organization("IBM");
1179 std::string organizationalUnit("orgUnit");
1180 std::string state("TS");
1181 std::string surname("surname");
1182 std::string unstructuredName("unstructuredName");
1183 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1184 auto event = sdeventplus::Event::get_default();
1185 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1186 std::move(installPath));
1187 Status status;
1188 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1189 MainApp mainApp(&manager, &csr);
1190 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1191 contactPerson, country, email, givenName, initials,
1192 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1193 organization, organizationalUnit, state, surname,
1194 unstructuredName);
1195 EXPECT_FALSE(fs::exists(CSRPath));
1196 EXPECT_FALSE(fs::exists(privateKeyPath));
1197}
1198
1199/** @brief Check error is thrown if generated rsa key file is not present
1200 */
1201TEST_F(TestCertificates, TestRSAKeyFileNotPresentCase)
1202{
1203 std::string endpoint("https");
1204 std::string unit("");
1205 std::string type("Server");
1206 std::string installPath(certDir + "/" + certificateFile);
1207 std::string verifyPath(installPath);
1208 std::string CSRPath(certDir + "/" + CSRFile);
1209 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1210 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1211 std::string challengePassword("Password");
1212 std::string city("BLR");
1213 std::string commonName("abc.com");
1214 std::string contactPerson("Admin");
1215 std::string country("IN");
1216 std::string email("admin@in.ibm.com");
1217 std::string givenName("givenName");
1218 std::string initials("G");
1219 int64_t keyBitLength(2048);
1220 std::string keyCurveId("secp521r1");
1221 std::string keyPairAlgorithm("RSA");
1222 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1223 std::string organization("IBM");
1224 std::string organizationalUnit("orgUnit");
1225 std::string state("TS");
1226 std::string surname("surname");
1227 std::string unstructuredName("unstructuredName");
1228 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1229 auto event = sdeventplus::Event::get_default();
1230 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1231 std::move(installPath));
1232
1233 // Removing generated RSA key file
1234 fs::remove(rsaPrivateKeyFilePath);
1235
1236 Status status;
1237 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1238 MainApp mainApp(&manager, &csr);
1239 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1240 contactPerson, country, email, givenName, initials,
1241 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1242 organization, organizationalUnit, state, surname,
1243 unstructuredName);
1244 EXPECT_FALSE(fs::exists(CSRPath));
1245 EXPECT_FALSE(fs::exists(privateKeyPath));
1246}
1247
1248/** @brief Check private key file is created from generated rsa key file is
1249 * `present
1250 */
1251TEST_F(TestCertificates, TestRSAKeyFromRSAKeyFileIsWrittenIntoPrivateKeyFile)
1252{
1253 std::string endpoint("https");
1254 std::string unit("");
1255 std::string type("Server");
1256 std::string installPath(certDir + "/" + certificateFile);
1257 std::string verifyPath(installPath);
1258 std::string CSRPath(certDir + "/" + CSRFile);
1259 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1260 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1261 std::string challengePassword("Password");
1262 std::string city("BLR");
1263 std::string commonName("abc.com");
1264 std::string contactPerson("Admin");
1265 std::string country("IN");
1266 std::string email("admin@in.ibm.com");
1267 std::string givenName("givenName");
1268 std::string initials("G");
1269 int64_t keyBitLength(2048);
1270 std::string keyCurveId("secp521r1");
1271 std::string keyPairAlgorithm("RSA");
1272 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1273 std::string organization("IBM");
1274 std::string organizationalUnit("orgUnit");
1275 std::string state("TS");
1276 std::string surname("surname");
1277 std::string unstructuredName("unstructuredName");
1278 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1279 auto event = sdeventplus::Event::get_default();
1280 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1281 std::move(installPath));
1282 Status status;
1283 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1284 MainApp mainApp(&manager, &csr);
1285 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1286 contactPerson, country, email, givenName, initials,
1287 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1288 organization, organizationalUnit, state, surname,
1289 unstructuredName);
1290 sleep(10);
1291 EXPECT_TRUE(fs::exists(CSRPath));
1292 EXPECT_TRUE(fs::exists(privateKeyPath));
1293}
1294
1295/** @brief Check RSA key is generted during application startup*/
1296TEST_F(TestCertificates, TestGenerateRSAPrivateKeyFile)
1297{
1298 std::string endpoint("https");
1299 std::string unit("");
1300 std::string type("Server");
1301 std::string installPath(certDir + "/" + certificateFile);
1302 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1303 auto event = sdeventplus::Event::get_default();
1304
1305 EXPECT_FALSE(fs::exists(rsaPrivateKeyFilePath));
1306 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1307 std::move(installPath));
1308 EXPECT_TRUE(fs::exists(rsaPrivateKeyFilePath));
1309}