blob: b971bed616864245099e4c32f9acc70db8c8a8fb [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 Lukwinski73d1fbf2020-01-15 15:31:12 +0100317/** @brief Check if in authority mode user can install a certificate with
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100318 * 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
Zbigniew Lukwinski73d1fbf2020-01-15 15:31:12 +0100353 // Install second certificate
354 mainApp.install(certificateFile);
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100355
356 // Expect there are exactly two certificates in the collection
Zbigniew Lukwinski73d1fbf2020-01-15 15:31:12 +0100357 EXPECT_EQ(certs.size(), 2);
358
359 // Check that certificate has been created at installation directory
360 std::string verifyPath1 =
361 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".1";
362 EXPECT_TRUE(fs::exists(verifyPath1));
363
364 // Check that installed cert is identical to input one
365 EXPECT_TRUE(compareFiles(certificateFile, verifyPath1));
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100366
367 // Check that the original/first certificate has been not removed
368 EXPECT_FALSE(fs::is_empty(verifyDir));
369 EXPECT_TRUE(fs::exists(verifyPath0));
370}
371
372/** @brief Check if in authority mode user can't install more than
373 * AUTHORITY_CERTIFICATES_LIMIT certificates.
374 */
375TEST_F(TestCertificates, InvokeInstallAuthCertLimit)
376{
377 std::string endpoint("ldap");
378 std::string unit("");
379 std::string type("authority");
380 std::string verifyDir(certDir);
381 UnitsToRestart verifyUnit(unit);
382 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
383 auto event = sdeventplus::Event::get_default();
384 // Attach the bus to sd_event to service user requests
385 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
386 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
387 std::move(certDir));
388 MainApp mainApp(&manager);
389
390 std::vector<std::unique_ptr<Certificate>>& certs =
391 manager.getCertificates();
392
393 std::vector<std::string> verifyPaths;
394
395 // Prepare maximum number of ceritificates
396 for (std::size_t i = 0; i < AUTHORITY_CERTIFICATES_LIMIT; ++i)
397 {
398 // Prepare new certificatate
399 createNewCertificate(true);
400
401 // Install ceritificate
402 mainApp.install(certificateFile);
403
404 // Check number of certificates in the collection
405 EXPECT_EQ(certs.size(), i + 1);
406
407 // Check that certificate has been created at installation directory
408 std::string verifyPath =
409 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
410 EXPECT_FALSE(fs::is_empty(verifyDir));
411 EXPECT_TRUE(fs::exists(verifyPath));
412
413 // Check that installed cert is identical to input one
414 EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
415
416 // Save current certificate file for later check
417 verifyPaths.push_back(verifyPath);
418 }
419
420 // Prepare new certificatate
421 createNewCertificate(true);
422
423 using NotAllowed =
424 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
425 EXPECT_THROW(
426 {
427 try
428 {
429 // Try to install one more certificate
430 mainApp.install(certificateFile);
431 }
432 catch (const NotAllowed& e)
433 {
434 throw;
435 }
436 },
437 NotAllowed);
438
439 // Check that the original certificate has been not removed
440 EXPECT_FALSE(fs::is_empty(verifyDir));
441 for (int i = 0; i < AUTHORITY_CERTIFICATES_LIMIT; ++i)
442 {
443 EXPECT_TRUE(fs::exists(verifyPaths[i]));
444 }
445}
446
Marri Devender Rao947258d2018-09-25 10:52:24 -0500447/** @brief Compare the installed certificate with the copied certificate
448 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600449TEST_F(TestCertificates, CompareInstalledCertificate)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500450{
451 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600452 std::string unit("");
Marri Devender Rao947258d2018-09-25 10:52:24 -0500453 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600454 std::string installPath(certDir + "/" + certificateFile);
455 std::string verifyPath(installPath);
456 UnitsToRestart verifyUnit(unit);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500457 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500458 auto event = sdeventplus::Event::get_default();
459 // Attach the bus to sd_event to service user requests
460 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
461 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
462 std::move(installPath));
463 MainApp mainApp(&manager);
464 mainApp.install(certificateFile);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500465 EXPECT_TRUE(fs::exists(verifyPath));
466 EXPECT_TRUE(compareFiles(verifyPath, certificateFile));
467}
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500468
469/** @brief Check if install fails if certificate file is not found
470 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600471TEST_F(TestCertificates, TestNoCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500472{
473 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600474 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500475 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600476 std::string installPath(certDir + "/" + certificateFile);
477 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500478 std::string verifyUnit(unit);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500479 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600480 std::string uploadFile = "nofile.pem";
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500481 EXPECT_THROW(
482 {
483 try
484 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500485 auto event = sdeventplus::Event::get_default();
486 // Attach the bus to sd_event to service user requests
487 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
488 Manager manager(bus, event, objPath.c_str(), type,
489 std::move(unit), std::move(installPath));
490 MainApp mainApp(&manager);
491 mainApp.install(uploadFile);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500492 }
493 catch (const InternalFailure& e)
494 {
495 throw;
496 }
497 },
498 InternalFailure);
499 EXPECT_FALSE(fs::exists(verifyPath));
500}
501
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500502/** @brief Test replacing existing certificate
503 */
504TEST_F(TestCertificates, TestReplaceCertificate)
505{
506 std::string endpoint("ldap");
507 std::string unit("");
508 std::string type("server");
509 std::string installPath(certDir + "/" + certificateFile);
510 std::string verifyPath(installPath);
511 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
512 auto event = sdeventplus::Event::get_default();
513 // Attach the bus to sd_event to service user requests
514 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
515 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
516 std::move(installPath));
517 MainApp mainApp(&manager);
518 mainApp.install(certificateFile);
519 EXPECT_TRUE(fs::exists(verifyPath));
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200520 std::vector<std::unique_ptr<Certificate>>& certs =
521 manager.getCertificates();
522 EXPECT_FALSE(certs.empty());
523 EXPECT_NE(certs[0], nullptr);
524 certs[0]->replace(certificateFile);
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500525 EXPECT_TRUE(fs::exists(verifyPath));
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200526}
527
528/** @brief Test replacing existing certificate
529 */
530TEST_F(TestCertificates, TestAuthorityReplaceCertificate)
531{
532 std::string endpoint("ldap");
533 std::string unit("");
534 std::string type("authority");
535 std::string verifyDir(certDir);
536 UnitsToRestart verifyUnit(unit);
537 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
538 auto event = sdeventplus::Event::get_default();
539 // Attach the bus to sd_event to service user requests
540 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
541 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
542 std::move(certDir));
543 MainApp mainApp(&manager);
544 mainApp.install(certificateFile);
545
546 std::vector<std::unique_ptr<Certificate>>& certs =
547 manager.getCertificates();
548 constexpr const unsigned int REPLACE_ITERATIONS = 10;
549
550 for (unsigned int i = 0; i < REPLACE_ITERATIONS; i++)
551 {
552 // Certificate successfully installed
553 EXPECT_FALSE(certs.empty());
554
Zbigniew Lukwinski2f3563c2020-01-08 12:35:23 +0100555 std::string verifyPath =
556 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
Kowalski, Kamildb029c92019-07-08 17:09:39 +0200557
558 // Check that certificate has been created at installation directory
559 EXPECT_FALSE(fs::is_empty(verifyDir));
560 EXPECT_TRUE(fs::exists(verifyPath));
561
562 // Check that installed cert is identical to input one
563 EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
564
565 // Create new certificate
566 createNewCertificate(true);
567
568 certs[0]->replace(certificateFile);
569
570 // Verify that old certificate has been removed
571 EXPECT_FALSE(fs::exists(verifyPath));
572 }
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500573}
574
Zbigniew Kurzynskia3bb38f2019-09-17 13:34:25 +0200575/** @brief Test verifiing if delete function works.
576 */
577TEST_F(TestCertificates, TestStorageDeleteCertificate)
578{
579 std::string endpoint("ldap");
580 std::string unit("");
581 std::string type("authority");
582 std::string verifyDir(certDir);
583 UnitsToRestart verifyUnit(unit);
584 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
585 auto event = sdeventplus::Event::get_default();
586 // Attach the bus to sd_event to service user requests
587 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
588 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
589 std::move(certDir));
590 MainApp mainApp(&manager);
591
592 // Check if certificate placeholder dir is empty
593 EXPECT_TRUE(fs::is_empty(verifyDir));
594 mainApp.install(certificateFile);
595
596 // Create new certificate
597 createNewCertificate(true);
598 mainApp.install(certificateFile);
599
600 createNewCertificate(true);
601 mainApp.install(certificateFile);
602
603 std::vector<std::unique_ptr<Certificate>>& certs =
604 manager.getCertificates();
605
606 // All 3 certificates successfully installed and added to manager
607 EXPECT_EQ(certs.size(), 3);
608
609 // Check if certificate placeholder is not empty, there should be 3
610 // certificates
611 EXPECT_FALSE(fs::is_empty(verifyDir));
612
613 certs[0]->delete_();
614 EXPECT_EQ(certs.size(), 2);
615
616 certs[0]->delete_();
617 EXPECT_EQ(certs.size(), 1);
618
619 certs[0]->delete_();
620 EXPECT_EQ(certs.size(), 0);
621
622 // Check if certificate placeholder is empty.
623 EXPECT_TRUE(fs::is_empty(verifyDir));
624}
625
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500626/** @brief Check if install fails if certificate file is empty
627 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600628TEST_F(TestCertificates, TestEmptyCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500629{
630 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600631 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500632 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600633 std::string installPath(certDir + "/" + certificateFile);
634 std::string verifyPath(installPath);
635 std::string verifyUnit(unit);
636 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500637 std::string emptyFile("emptycert.pem");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500638 std::ofstream ofs;
639 ofs.open(emptyFile, std::ofstream::out);
640 ofs.close();
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500641 EXPECT_THROW(
642 {
643 try
644 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500645 auto event = sdeventplus::Event::get_default();
646 // Attach the bus to sd_event to service user requests
647 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
648 Manager manager(bus, event, objPath.c_str(), type,
649 std::move(unit), std::move(installPath));
650 MainApp mainApp(&manager);
651 mainApp.install(emptyFile);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500652 }
653 catch (const InvalidCertificate& e)
654 {
655 throw;
656 }
657 },
658 InvalidCertificate);
659 EXPECT_FALSE(fs::exists(verifyPath));
660 fs::remove(emptyFile);
661}
662
Marri Devender Raoddf64862018-10-03 07:11:02 -0500663/** @brief Check if install fails if certificate file is corrupted
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500664 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600665TEST_F(TestCertificates, TestInvalidCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500666{
667 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600668 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500669 std::string type("client");
670
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500671 std::ofstream ofs;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500672 ofs.open(certificateFile, std::ofstream::out);
673 ofs << "-----BEGIN CERTIFICATE-----";
674 ofs << "ADD_SOME_INVALID_DATA_INTO_FILE";
675 ofs << "-----END CERTIFICATE-----";
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500676 ofs.close();
677
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600678 std::string installPath(certDir + "/" + certificateFile);
679 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500680 std::string verifyUnit(unit);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500681 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500682 EXPECT_THROW(
683 {
684 try
685 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500686 auto event = sdeventplus::Event::get_default();
687 // Attach the bus to sd_event to service user requests
688 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
689 Manager manager(bus, event, objPath.c_str(), type,
690 std::move(unit), std::move(installPath));
691 MainApp mainApp(&manager);
692 mainApp.install(certificateFile);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500693 }
694 catch (const InvalidCertificate& e)
695 {
696 throw;
697 }
698 },
699 InvalidCertificate);
700 EXPECT_FALSE(fs::exists(verifyPath));
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500701}
Marri Devender Raoddf64862018-10-03 07:11:02 -0500702
703/**
704 * Class to generate private and certificate only file and test verification
705 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600706class TestInvalidCertificate : public ::testing::Test
Marri Devender Raoddf64862018-10-03 07:11:02 -0500707{
708 public:
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600709 TestInvalidCertificate() : bus(sdbusplus::bus::new_default())
Marri Devender Raoddf64862018-10-03 07:11:02 -0500710 {
711 }
712 void SetUp() override
713 {
714 char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
715 auto dirPtr = mkdtemp(dirTemplate);
716 if (dirPtr == NULL)
717 {
718 throw std::bad_alloc();
719 }
Zbigniew Lukwinskife590c42019-12-10 12:33:50 +0100720 certDir = std::string(dirPtr) + "/certs";
721 fs::create_directories(certDir);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500722 certificateFile = "cert.pem";
723 keyFile = "key.pem";
724 std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
725 cmd += "-keyout key.pem -out cert.pem -days 3650 ";
726 cmd += "-subj "
727 "/O=openbmc-project.xyz/CN=localhost"
728 " -nodes";
729
730 auto val = std::system(cmd.c_str());
731 if (val)
732 {
733 std::cout << "command Error: " << val << std::endl;
734 }
735 }
736 void TearDown() override
737 {
738 fs::remove_all(certDir);
739 fs::remove(certificateFile);
740 fs::remove(keyFile);
741 }
742
743 protected:
744 sdbusplus::bus::bus bus;
745 std::string certificateFile;
746 std::string keyFile;
747 std::string certDir;
748};
749
750/** @brief Check install fails if private key is missing in certificate file
751 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600752TEST_F(TestInvalidCertificate, TestMissingPrivateKey)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500753{
754 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600755 std::string unit("");
Marri Devender Raoddf64862018-10-03 07:11:02 -0500756 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600757 std::string installPath(certDir + "/" + certificateFile);
758 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500759 std::string verifyUnit(unit);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500760 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600761 EXPECT_THROW(
762 {
763 try
764 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500765 auto event = sdeventplus::Event::get_default();
766 // Attach the bus to sd_event to service user requests
767 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
768 Manager manager(bus, event, objPath.c_str(), type,
769 std::move(unit), std::move(installPath));
770 MainApp mainApp(&manager);
771 mainApp.install(certificateFile);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600772 }
Marri Devender Raocd30c492019-06-12 01:40:17 -0500773 catch (const InternalFailure& e)
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600774 {
775 throw;
776 }
777 },
Marri Devender Raocd30c492019-06-12 01:40:17 -0500778 InternalFailure);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600779 EXPECT_FALSE(fs::exists(verifyPath));
780}
781
782/** @brief Check install fails if ceritificate is missing in certificate file
783 */
784TEST_F(TestInvalidCertificate, TestMissingCeritificate)
785{
786 std::string endpoint("ldap");
787 std::string unit("");
788 std::string type("client");
789 std::string installPath(certDir + "/" + keyFile);
790 std::string verifyPath(installPath);
791 std::string verifyUnit(unit);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600792 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
793 EXPECT_THROW(
794 {
795 try
796 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500797 auto event = sdeventplus::Event::get_default();
798 // Attach the bus to sd_event to service user requests
799 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
800 Manager manager(bus, event, objPath.c_str(), type,
801 std::move(unit), std::move(installPath));
802 MainApp mainApp(&manager);
803 mainApp.install(keyFile);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500804 }
Marri Devender Raocd30c492019-06-12 01:40:17 -0500805 catch (const InternalFailure& e)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500806 {
807 throw;
808 }
809 },
810 InvalidCertificate);
811 EXPECT_FALSE(fs::exists(verifyPath));
812}
813
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600814/** @brief Check if error is thrown when multiple certificates are installed
815 * At present only one certificate per service is allowed
Marri Devender Raoddf64862018-10-03 07:11:02 -0500816 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600817TEST_F(TestCertificates, TestCertInstallNotAllowed)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500818{
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600819 using NotAllowed =
820 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500821 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600822 std::string unit("");
Marri Devender Raoddf64862018-10-03 07:11:02 -0500823 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600824 std::string installPath(certDir + "/" + certificateFile);
825 std::string verifyPath(installPath);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500826 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raof4682712019-03-19 05:00:28 -0500827 auto event = sdeventplus::Event::get_default();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500828 // Attach the bus to sd_event to service user requests
829 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
Marri Devender Raof4682712019-03-19 05:00:28 -0500830 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600831 std::move(installPath));
Marri Devender Raoddf64862018-10-03 07:11:02 -0500832 MainApp mainApp(&manager);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600833 mainApp.install(certificateFile);
834 EXPECT_TRUE(fs::exists(verifyPath));
Marri Devender Raoddf64862018-10-03 07:11:02 -0500835 EXPECT_THROW(
836 {
837 try
838 {
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600839 // install second certificate
840 mainApp.install(certificateFile);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500841 }
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600842 catch (const NotAllowed& e)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500843 {
844 throw;
845 }
846 },
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600847 NotAllowed);
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500848}
Marri Devender Raof4682712019-03-19 05:00:28 -0500849
850TEST_F(TestCertificates, TestGenerateCSR)
851{
852 std::string endpoint("https");
853 std::string unit("");
854 std::string type("Server");
855 std::string installPath(certDir + "/" + certificateFile);
856 std::string verifyPath(installPath);
857 std::string CSRPath(certDir + "/" + CSRFile);
858 std::string privateKeyPath(certDir + "/" + privateKeyFile);
859 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500860 std::string challengePassword("Password");
Marri Devender Raof4682712019-03-19 05:00:28 -0500861 std::string city("HYB");
862 std::string commonName("abc.com");
863 std::string contactPerson("Admin");
864 std::string country("IN");
865 std::string email("admin@in.ibm.com");
866 std::string givenName("givenName");
867 std::string initials("G");
868 int64_t keyBitLength(2048);
869 std::string keyCurveId("0");
870 std::string keyPairAlgorithm("RSA");
871 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
872 std::string organization("IBM");
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500873 std::string organizationalUnit("orgUnit");
Marri Devender Raof4682712019-03-19 05:00:28 -0500874 std::string state("TS");
875 std::string surname("surname");
876 std::string unstructuredName("unstructuredName");
877 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
878 auto event = sdeventplus::Event::get_default();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500879 // Attach the bus to sd_event to service user requests
880 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
Marri Devender Raof4682712019-03-19 05:00:28 -0500881 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
882 std::move(installPath));
883 Status status;
884 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
885 MainApp mainApp(&manager, &csr);
886 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
887 contactPerson, country, email, givenName, initials,
888 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
889 organization, organizationalUnit, state, surname,
890 unstructuredName);
891 std::string csrData("");
892 // generateCSR takes considerable time to create CSR and privateKey Files
893 EXPECT_FALSE(fs::exists(CSRPath));
894 EXPECT_FALSE(fs::exists(privateKeyPath));
895 EXPECT_THROW(
896 {
897 try
898 {
899 csrData = csr.cSR();
900 }
901 catch (const InternalFailure& e)
902 {
903 throw;
904 }
905 },
906 InternalFailure);
907 // wait for 10 sec to get CSR and privateKey Files generated
908 sleep(10);
909 EXPECT_TRUE(fs::exists(CSRPath));
910 EXPECT_TRUE(fs::exists(privateKeyPath));
911 csrData = csr.cSR();
912 ASSERT_NE("", csrData.c_str());
913}
914
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500915/** @brief Check if ECC key pair is generated when user is not given algorithm
916 * type. At present RSA and EC key pair algorithm are supported
917 */
918TEST_F(TestCertificates, TestGenerateCSRwithEmptyKeyPairAlgorithm)
919{
920 std::string endpoint("https");
921 std::string unit("");
922 std::string type("Server");
923 std::string installPath(certDir + "/" + certificateFile);
924 std::string verifyPath(installPath);
925 std::string CSRPath(certDir + "/" + CSRFile);
926 std::string privateKeyPath(certDir + "/" + privateKeyFile);
927 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
928 std::string challengePassword("Password");
929 std::string city("HYB");
930 std::string commonName("abc.com");
931 std::string contactPerson("Admin");
932 std::string country("IN");
933 std::string email("admin@in.ibm.com");
934 std::string givenName("givenName");
935 std::string initials("G");
936 int64_t keyBitLength(2048);
937 std::string keyCurveId("");
938 std::string keyPairAlgorithm("");
939 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
940 std::string organization("IBM");
941 std::string organizationalUnit("orgUnit");
942 std::string state("TS");
943 std::string surname("surname");
944 std::string unstructuredName("unstructuredName");
Marri Devender Raof4682712019-03-19 05:00:28 -0500945 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
946 auto event = sdeventplus::Event::get_default();
947 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
948 std::move(installPath));
949 Status status;
950 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
951 MainApp mainApp(&manager, &csr);
952 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
953 contactPerson, country, email, givenName, initials,
954 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
955 organization, organizationalUnit, state, surname,
956 unstructuredName);
957 sleep(10);
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500958 EXPECT_TRUE(fs::exists(CSRPath));
959 EXPECT_TRUE(fs::exists(privateKeyPath));
960}
961
962/** @brief Check if error is thrown when giving un supported key pair
963 * algorithm. At present RSA and EC key pair algorithm are supported
964 */
965TEST_F(TestCertificates, TestGenerateCSRwithUnsupportedKeyPairAlgorithm)
966{
967 std::string endpoint("https");
968 std::string unit("");
969 std::string type("Server");
970 std::string installPath(certDir + "/" + certificateFile);
971 std::string verifyPath(installPath);
972 std::string CSRPath(certDir + "/" + CSRFile);
973 std::string privateKeyPath(certDir + "/" + privateKeyFile);
974 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
975 std::string challengePassword("Password");
976 std::string city("HYB");
977 std::string commonName("abc.com");
978 std::string contactPerson("Admin");
979 std::string country("IN");
980 std::string email("admin@in.ibm.com");
981 std::string givenName("givenName");
982 std::string initials("G");
983 int64_t keyBitLength(2048);
984 std::string keyCurveId("secp521r1");
985 std::string keyPairAlgorithm("UnSupportedAlgorithm");
986 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
987 std::string organization("IBM");
988 std::string organizationalUnit("orgUnit");
989 std::string state("TS");
990 std::string surname("surname");
991 std::string unstructuredName("unstructuredName");
992 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
993 auto event = sdeventplus::Event::get_default();
994 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
995 std::move(installPath));
996 Status status;
997 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
998 MainApp mainApp(&manager, &csr);
999 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1000 contactPerson, country, email, givenName, initials,
1001 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1002 organization, organizationalUnit, state, surname,
1003 unstructuredName);
Marri Devender Raof4682712019-03-19 05:00:28 -05001004 EXPECT_FALSE(fs::exists(CSRPath));
1005 EXPECT_FALSE(fs::exists(privateKeyPath));
1006}
Ramesh Iyyar8a09b522019-06-07 05:23:29 -05001007
1008/** @brief Check if error is thrown when NID_undef is returned for given key
1009 * curve id
1010 */
1011TEST_F(TestCertificates, TestECKeyGenerationwithNIDundefCase)
1012{
1013 std::string endpoint("https");
1014 std::string unit("");
1015 std::string type("Server");
1016 std::string installPath(certDir + "/" + certificateFile);
1017 std::string verifyPath(installPath);
1018 std::string CSRPath(certDir + "/" + CSRFile);
1019 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1020 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1021 std::string challengePassword("Password");
1022 std::string city("BLR");
1023 std::string commonName("abc.com");
1024 std::string contactPerson("Admin");
1025 std::string country("IN");
1026 std::string email("admin@in.ibm.com");
1027 std::string givenName("givenName");
1028 std::string initials("G");
1029 int64_t keyBitLength(2048);
1030 std::string keyCurveId("DummyCurveName");
1031 std::string keyPairAlgorithm("EC");
1032 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1033 std::string organization("IBM");
1034 std::string organizationalUnit("orgUnit");
1035 std::string state("TS");
1036 std::string surname("surname");
1037 std::string unstructuredName("unstructuredName");
1038 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1039 auto event = sdeventplus::Event::get_default();
1040 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1041 std::move(installPath));
1042 Status status;
1043 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1044 MainApp mainApp(&manager, &csr);
1045 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1046 contactPerson, country, email, givenName, initials,
1047 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1048 organization, organizationalUnit, state, surname,
1049 unstructuredName);
1050 EXPECT_FALSE(fs::exists(CSRPath));
1051 EXPECT_FALSE(fs::exists(privateKeyPath));
1052}
1053
1054/** @brief Check default Key Curve Id is used if given curve id is empty
1055 */
1056TEST_F(TestCertificates, TestECKeyGenerationwithDefaultKeyCurveId)
1057{
1058 std::string endpoint("https");
1059 std::string unit("");
1060 std::string type("Server");
1061 std::string installPath(certDir + "/" + certificateFile);
1062 std::string verifyPath(installPath);
1063 std::string CSRPath(certDir + "/" + CSRFile);
1064 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1065 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1066 std::string challengePassword("Password");
1067 std::string city("BLR");
1068 std::string commonName("abc.com");
1069 std::string contactPerson("Admin");
1070 std::string country("IN");
1071 std::string email("admin@in.ibm.com");
1072 std::string givenName("givenName");
1073 std::string initials("G");
1074 int64_t keyBitLength(2048);
1075 std::string keyCurveId("");
1076 std::string keyPairAlgorithm("EC");
1077 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1078 std::string organization("IBM");
1079 std::string organizationalUnit("orgUnit");
1080 std::string state("TS");
1081 std::string surname("surname");
1082 std::string unstructuredName("unstructuredName");
1083 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1084 auto event = sdeventplus::Event::get_default();
1085 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1086 std::move(installPath));
1087 Status status;
1088 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1089 MainApp mainApp(&manager, &csr);
1090 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1091 contactPerson, country, email, givenName, initials,
1092 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1093 organization, organizationalUnit, state, surname,
1094 unstructuredName);
1095 sleep(10);
1096 EXPECT_TRUE(fs::exists(CSRPath));
1097 EXPECT_TRUE(fs::exists(privateKeyPath));
1098}
1099
1100/** @brief Check if error is not thrown to generate EC key pair
1101 */
1102TEST_F(TestCertificates, TestECKeyGeneration)
1103{
1104 std::string endpoint("https");
1105 std::string unit("");
1106 std::string type("Server");
1107 std::string installPath(certDir + "/" + certificateFile);
1108 std::string verifyPath(installPath);
1109 std::string CSRPath(certDir + "/" + CSRFile);
1110 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1111 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1112 std::string challengePassword("Password");
1113 std::string city("BLR");
1114 std::string commonName("abc.com");
1115 std::string contactPerson("Admin");
1116 std::string country("IN");
1117 std::string email("admin@in.ibm.com");
1118 std::string givenName("givenName");
1119 std::string initials("G");
1120 int64_t keyBitLength(2048);
1121 std::string keyCurveId("secp521r1");
1122 std::string keyPairAlgorithm("EC");
1123 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1124 std::string organization("IBM");
1125 std::string organizationalUnit("orgUnit");
1126 std::string state("TS");
1127 std::string surname("surname");
1128 std::string unstructuredName("unstructuredName");
1129 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1130 auto event = sdeventplus::Event::get_default();
1131 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1132 std::move(installPath));
1133 Status status;
1134 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1135 MainApp mainApp(&manager, &csr);
1136 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1137 contactPerson, country, email, givenName, initials,
1138 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1139 organization, organizationalUnit, state, surname,
1140 unstructuredName);
1141 std::cout << "CSRPath: " << CSRPath << std::endl
1142 << "privateKeyPath: " << privateKeyPath << std::endl;
1143 sleep(10);
1144 EXPECT_TRUE(fs::exists(CSRPath));
1145 EXPECT_TRUE(fs::exists(privateKeyPath));
1146}
Ramesh Iyyarc6e58c72019-07-16 08:52:47 -05001147
1148/** @brief Check error is thrown if giving unsupported ket bit length to
1149 * generate rsa key
1150 */
1151TEST_F(TestCertificates, TestRSAKeyWithUnsupportedKeyBitLength)
1152{
1153 std::string endpoint("https");
1154 std::string unit("");
1155 std::string type("Server");
1156 std::string installPath(certDir + "/" + certificateFile);
1157 std::string verifyPath(installPath);
1158 std::string CSRPath(certDir + "/" + CSRFile);
1159 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1160 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1161 std::string challengePassword("Password");
1162 std::string city("BLR");
1163 std::string commonName("abc.com");
1164 std::string contactPerson("Admin");
1165 std::string country("IN");
1166 std::string email("admin@in.ibm.com");
1167 std::string givenName("givenName");
1168 std::string initials("G");
1169 int64_t keyBitLength(4096);
1170 std::string keyCurveId("secp521r1");
1171 std::string keyPairAlgorithm("RSA");
1172 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1173 std::string organization("IBM");
1174 std::string organizationalUnit("orgUnit");
1175 std::string state("TS");
1176 std::string surname("surname");
1177 std::string unstructuredName("unstructuredName");
1178 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1179 auto event = sdeventplus::Event::get_default();
1180 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1181 std::move(installPath));
1182 Status status;
1183 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1184 MainApp mainApp(&manager, &csr);
1185 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1186 contactPerson, country, email, givenName, initials,
1187 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1188 organization, organizationalUnit, state, surname,
1189 unstructuredName);
1190 EXPECT_FALSE(fs::exists(CSRPath));
1191 EXPECT_FALSE(fs::exists(privateKeyPath));
1192}
1193
1194/** @brief Check error is thrown if generated rsa key file is not present
1195 */
1196TEST_F(TestCertificates, TestRSAKeyFileNotPresentCase)
1197{
1198 std::string endpoint("https");
1199 std::string unit("");
1200 std::string type("Server");
1201 std::string installPath(certDir + "/" + certificateFile);
1202 std::string verifyPath(installPath);
1203 std::string CSRPath(certDir + "/" + CSRFile);
1204 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1205 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1206 std::string challengePassword("Password");
1207 std::string city("BLR");
1208 std::string commonName("abc.com");
1209 std::string contactPerson("Admin");
1210 std::string country("IN");
1211 std::string email("admin@in.ibm.com");
1212 std::string givenName("givenName");
1213 std::string initials("G");
1214 int64_t keyBitLength(2048);
1215 std::string keyCurveId("secp521r1");
1216 std::string keyPairAlgorithm("RSA");
1217 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1218 std::string organization("IBM");
1219 std::string organizationalUnit("orgUnit");
1220 std::string state("TS");
1221 std::string surname("surname");
1222 std::string unstructuredName("unstructuredName");
1223 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1224 auto event = sdeventplus::Event::get_default();
1225 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1226 std::move(installPath));
1227
1228 // Removing generated RSA key file
1229 fs::remove(rsaPrivateKeyFilePath);
1230
1231 Status status;
1232 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1233 MainApp mainApp(&manager, &csr);
1234 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1235 contactPerson, country, email, givenName, initials,
1236 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1237 organization, organizationalUnit, state, surname,
1238 unstructuredName);
1239 EXPECT_FALSE(fs::exists(CSRPath));
1240 EXPECT_FALSE(fs::exists(privateKeyPath));
1241}
1242
1243/** @brief Check private key file is created from generated rsa key file is
1244 * `present
1245 */
1246TEST_F(TestCertificates, TestRSAKeyFromRSAKeyFileIsWrittenIntoPrivateKeyFile)
1247{
1248 std::string endpoint("https");
1249 std::string unit("");
1250 std::string type("Server");
1251 std::string installPath(certDir + "/" + certificateFile);
1252 std::string verifyPath(installPath);
1253 std::string CSRPath(certDir + "/" + CSRFile);
1254 std::string privateKeyPath(certDir + "/" + privateKeyFile);
1255 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1256 std::string challengePassword("Password");
1257 std::string city("BLR");
1258 std::string commonName("abc.com");
1259 std::string contactPerson("Admin");
1260 std::string country("IN");
1261 std::string email("admin@in.ibm.com");
1262 std::string givenName("givenName");
1263 std::string initials("G");
1264 int64_t keyBitLength(2048);
1265 std::string keyCurveId("secp521r1");
1266 std::string keyPairAlgorithm("RSA");
1267 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1268 std::string organization("IBM");
1269 std::string organizationalUnit("orgUnit");
1270 std::string state("TS");
1271 std::string surname("surname");
1272 std::string unstructuredName("unstructuredName");
1273 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1274 auto event = sdeventplus::Event::get_default();
1275 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1276 std::move(installPath));
1277 Status status;
1278 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1279 MainApp mainApp(&manager, &csr);
1280 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1281 contactPerson, country, email, givenName, initials,
1282 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1283 organization, organizationalUnit, state, surname,
1284 unstructuredName);
1285 sleep(10);
1286 EXPECT_TRUE(fs::exists(CSRPath));
1287 EXPECT_TRUE(fs::exists(privateKeyPath));
1288}
1289
1290/** @brief Check RSA key is generted during application startup*/
1291TEST_F(TestCertificates, TestGenerateRSAPrivateKeyFile)
1292{
1293 std::string endpoint("https");
1294 std::string unit("");
1295 std::string type("Server");
1296 std::string installPath(certDir + "/" + certificateFile);
1297 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
1298 auto event = sdeventplus::Event::get_default();
1299
1300 EXPECT_FALSE(fs::exists(rsaPrivateKeyFilePath));
1301 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1302 std::move(installPath));
1303 EXPECT_TRUE(fs::exists(rsaPrivateKeyFilePath));
1304}