1 #include "config.h"
2 
3 #include "certificate.hpp"
4 #include "certs_manager.hpp"
5 
6 #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 
13 #include <algorithm>
14 #include <filesystem>
15 #include <fstream>
16 #include <iterator>
17 #include <sdeventplus/event.hpp>
18 #include <string>
19 #include <xyz/openbmc_project/Certs/error.hpp>
20 #include <xyz/openbmc_project/Common/error.hpp>
21 
22 #include <gtest/gtest.h>
23 
24 namespace phosphor::certs
25 {
26 namespace
27 {
28 namespace fs = std::filesystem;
29 using ::sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate;
30 using ::sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
31 
32 /**
33  * Class to generate certificate file and test verification of certificate file
34  */
35 class TestCertificates : public ::testing::Test
36 {
37   public:
38     TestCertificates() : bus(sdbusplus::bus::new_default())
39     {
40     }
41     void SetUp() override
42     {
43         char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
44         auto dirPtr = mkdtemp(dirTemplate);
45         if (dirPtr == nullptr)
46         {
47             throw std::bad_alloc();
48         }
49         certDir = std::string(dirPtr) + "/certs";
50         fs::create_directories(certDir);
51 
52         createNewCertificate();
53     }
54 
55     void TearDown() override
56     {
57         fs::remove_all(certDir);
58         fs::remove(certificateFile);
59         fs::remove(CSRFile);
60         fs::remove(privateKeyFile);
61         fs::remove_all("demoCA");
62     }
63 
64     void createNewCertificate(bool setNewCertId = false)
65     {
66         certificateFile = "cert.pem";
67         CSRFile = "domain.csr";
68         privateKeyFile = "privkey.pem";
69         rsaPrivateKeyFilePath = certDir + "/.rsaprivkey.pem";
70         std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
71         cmd += "-keyout cert.pem -out cert.pem -days 365000 -nodes";
72         cmd += " -subj /O=openbmc-project.xyz/CN=localhost";
73 
74         if (setNewCertId)
75         {
76             cmd += std::to_string(certId++);
77         }
78 
79         auto val = std::system(cmd.c_str());
80         if (val)
81         {
82             std::cout << "COMMAND Error: " << val << std::endl;
83         }
84     }
85 
86     void createNeverExpiredRootCertificate()
87     {
88         // remove the old cert
89         fs::remove(certificateFile);
90 
91         // The following routines create a cert that has NotBefore
92         // set to 1970/01/01 and NotAfter set to 9999/12/31 via the
93         // OpenSSL CA application.
94         certificateFile = "cert.pem";
95         ASSERT_EQ(std::system("mkdir -p demoCA"), 0);
96         ASSERT_EQ(std::system("mkdir -p demoCA/private/"), 0);
97         ASSERT_EQ(std::system("mkdir -p demoCA/newcerts/"), 0);
98         ASSERT_EQ(std::system("touch demoCA/index.txt"), 0);
99         ASSERT_EQ(std::system("echo 1000 > demoCA/serial"), 0);
100         ASSERT_EQ(
101             std::system(
102                 "openssl req -x509 -sha256 -newkey rsa:2048 -keyout "
103                 "demoCA/private/cakey.pem -out demoCA/cacert.pem -nodes "
104                 "-subj /O=openbmc-project.xyz/C=US/ST=CA/CN=localhost-ca"),
105             0);
106         ASSERT_EQ(std::system(
107                       "openssl req -new -newkey rsa:2048 -nodes -keyout "
108                       "demoCA/server.key -out demoCA/server.csr -subj "
109                       "/O=openbmc-project.xyz/C=US/ST=CA/CN=localhost-server"),
110                   0);
111         ASSERT_EQ(
112             std::system(
113                 "openssl ca -batch -startdate 19700101000000Z -enddate "
114                 "99991231235959Z -out cert.pem -infiles demoCA/server.csr"),
115             0);
116     }
117 
118     bool compareFiles(const std::string& file1, const std::string& file2)
119     {
120         std::ifstream f1(file1, std::ifstream::binary | std::ifstream::ate);
121         std::ifstream f2(file2, std::ifstream::binary | std::ifstream::ate);
122 
123         if (f1.fail() || f2.fail())
124         {
125             return false; // file problem
126         }
127 
128         if (f1.tellg() != f2.tellg())
129         {
130             return false; // size mismatch
131         }
132 
133         // seek back to beginning and use std::equal to compare contents
134         f1.seekg(0, std::ifstream::beg);
135         f2.seekg(0, std::ifstream::beg);
136         return std::equal(std::istreambuf_iterator<char>(f1.rdbuf()),
137                           std::istreambuf_iterator<char>(),
138                           std::istreambuf_iterator<char>(f2.rdbuf()));
139     }
140 
141     std::string getCertSubjectNameHash(const std::string& certFilePath)
142     {
143         std::unique_ptr<X509, decltype(&::X509_free)> cert(X509_new(),
144                                                            ::X509_free);
145         if (!cert)
146         {
147             std::string();
148         }
149 
150         std::unique_ptr<BIO, decltype(&::BIO_free)> bioCert(
151             BIO_new_file(certFilePath.c_str(), "rb"), ::BIO_free);
152         if (!bioCert)
153         {
154             std::string();
155         }
156 
157         X509* x509 = cert.get();
158         if (!PEM_read_bio_X509(bioCert.get(), &x509, nullptr, nullptr))
159         {
160             std::string();
161         }
162 
163         unsigned long hash = X509_subject_name_hash(cert.get());
164         static constexpr auto AUTH_CERT_HASH_LENGTH = 9;
165         char hashBuf[AUTH_CERT_HASH_LENGTH];
166         sprintf(hashBuf, "%08lx", hash);
167         return std::string(hashBuf);
168     }
169 
170   protected:
171     sdbusplus::bus::bus bus;
172     std::string certificateFile, CSRFile, privateKeyFile, rsaPrivateKeyFilePath;
173 
174     std::string certDir;
175     uint64_t certId;
176 };
177 
178 class MainApp
179 {
180   public:
181     MainApp(phosphor::certs::Manager* manager,
182             phosphor::certs::CSR* csr = nullptr) :
183         manager(manager),
184         csr_(csr)
185     {
186     }
187     void install(std::string& path)
188     {
189         manager->install(path);
190     }
191     void delete_()
192     {
193         manager->deleteAll();
194     }
195 
196     std::string generateCSR(std::vector<std::string> alternativeNames,
197                             std::string challengePassword, std::string city,
198                             std::string commonName, std::string contactPerson,
199                             std::string country, std::string email,
200                             std::string givenName, std::string initials,
201                             int64_t keyBitLength, std::string keyCurveId,
202                             std::string keyPairAlgorithm,
203                             std::vector<std::string> keyUsage,
204                             std::string organization,
205                             std::string organizationalUnit, std::string state,
206                             std::string surname, std::string unstructuredName)
207     {
208         return (manager->generateCSR(
209             alternativeNames, challengePassword, city, commonName,
210             contactPerson, country, email, givenName, initials, keyBitLength,
211             keyCurveId, keyPairAlgorithm, keyUsage, organization,
212             organizationalUnit, state, surname, unstructuredName));
213     }
214     std::string csr()
215     {
216         return (csr_->csr());
217     }
218     phosphor::certs::Manager* manager;
219     phosphor::certs::CSR* csr_;
220 };
221 
222 /** @brief Check if server install routine is invoked for server setup
223  */
224 TEST_F(TestCertificates, InvokeServerInstall)
225 {
226     std::string endpoint("https");
227     std::string unit;
228     CertificateType type = CertificateType::Server;
229     std::string installPath(certDir + "/" + certificateFile);
230     std::string verifyPath(installPath);
231     std::string verifyUnit(unit);
232     auto objPath = std::string(objectNamePrefix) + '/' +
233                    certificateTypeToString(type) + '/' + endpoint;
234     auto event = sdeventplus::Event::get_default();
235     // Attach the bus to sd_event to service user requests
236     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
237     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
238                     std::move(installPath));
239     MainApp mainApp(&manager);
240     mainApp.install(certificateFile);
241     EXPECT_TRUE(fs::exists(verifyPath));
242 }
243 
244 /** @brief Check if client install routine is invoked for client setup
245  */
246 TEST_F(TestCertificates, InvokeClientInstall)
247 {
248     std::string endpoint("ldap");
249     std::string unit;
250     CertificateType type = CertificateType::Server;
251     std::string installPath(certDir + "/" + certificateFile);
252     std::string verifyPath(installPath);
253     std::string verifyUnit(unit);
254     auto objPath = std::string(objectNamePrefix) + '/' +
255                    certificateTypeToString(type) + '/' + endpoint;
256     auto event = sdeventplus::Event::get_default();
257     // Attach the bus to sd_event to service user requests
258     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
259     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
260                     std::move(installPath));
261     MainApp mainApp(&manager);
262     mainApp.install(certificateFile);
263     EXPECT_TRUE(fs::exists(verifyPath));
264 }
265 
266 /** @brief Check if storage install routine is invoked for storage setup
267  */
268 TEST_F(TestCertificates, InvokeAuthorityInstall)
269 {
270     std::string endpoint("ldap");
271     std::string unit;
272     CertificateType type = CertificateType::Authority;
273     std::string verifyDir(certDir);
274     std::string verifyUnit(unit);
275     auto objPath = std::string(objectNamePrefix) + '/' +
276                    certificateTypeToString(type) + '/' + endpoint;
277     auto event = sdeventplus::Event::get_default();
278     // Attach the bus to sd_event to service user requests
279     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
280     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
281                     std::move(certDir));
282     MainApp mainApp(&manager);
283     // install the default certificate that's valid from today to 100 years
284     // later
285     mainApp.install(certificateFile);
286 
287     std::vector<std::unique_ptr<Certificate>>& certs =
288         manager.getCertificates();
289 
290     ASSERT_EQ(certs.size(), 1);
291     // check some attributes as well
292     EXPECT_EQ(certs.front()->validNotAfter() - certs.front()->validNotBefore(),
293               365000ULL * 24 * 3600);
294     EXPECT_EQ(certs.front()->subject(), "O=openbmc-project.xyz,CN=localhost");
295     EXPECT_EQ(certs.front()->issuer(), "O=openbmc-project.xyz,CN=localhost");
296 
297     std::string verifyPath =
298         verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
299 
300     // Check that certificate has been created at installation directory
301     EXPECT_FALSE(fs::is_empty(verifyDir));
302     EXPECT_TRUE(fs::exists(verifyPath));
303 
304     // Check that installed cert is identical to input one
305     EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
306 }
307 
308 /** @brief Check if storage install routine is invoked for storage setup
309  */
310 TEST_F(TestCertificates, InvokeAuthorityInstallNeverExpiredRootCert)
311 {
312     std::string endpoint("ldap");
313     std::string unit;
314     CertificateType type = CertificateType::Authority;
315     std::string verifyDir(certDir);
316     std::string verifyUnit(unit);
317     auto objPath = std::string(objectNamePrefix) + '/' +
318                    certificateTypeToString(type) + '/' + endpoint;
319     auto event = sdeventplus::Event::get_default();
320     // Attach the bus to sd_event to service user requests
321     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
322     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
323                     std::move(certDir));
324     MainApp mainApp(&manager);
325 
326     // install the certificate that's valid from the Unix Epoch to Dec 31, 9999
327     createNeverExpiredRootCertificate();
328     mainApp.install(certificateFile);
329 
330     std::vector<std::unique_ptr<Certificate>>& certs =
331         manager.getCertificates();
332 
333     EXPECT_EQ(certs.front()->validNotBefore(), 0);
334     EXPECT_EQ(certs.front()->validNotAfter(), 253402300799ULL);
335 
336     std::string verifyPath =
337         verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
338 
339     // Check that certificate has been created at installation directory
340     EXPECT_FALSE(fs::is_empty(verifyDir));
341     EXPECT_TRUE(fs::exists(verifyPath));
342 
343     // Check that installed cert is identical to input one
344     EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
345 }
346 
347 /** @brief Check if in authority mode user can't install the same
348  * certificate twice.
349  */
350 TEST_F(TestCertificates, InvokeInstallSameCertTwice)
351 {
352     std::string endpoint("ldap");
353     std::string unit;
354     CertificateType type = CertificateType::Authority;
355     std::string verifyDir(certDir);
356     std::string verifyUnit(unit);
357     auto objPath = std::string(objectNamePrefix) + '/' +
358                    certificateTypeToString(type) + '/' + endpoint;
359     auto event = sdeventplus::Event::get_default();
360     // Attach the bus to sd_event to service user requests
361     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
362     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
363                     std::move(certDir));
364     MainApp mainApp(&manager);
365     mainApp.install(certificateFile);
366 
367     std::vector<std::unique_ptr<Certificate>>& certs =
368         manager.getCertificates();
369 
370     EXPECT_FALSE(certs.empty());
371 
372     // Check that certificate has been created at installation directory
373     std::string verifyPath =
374         verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
375     EXPECT_FALSE(fs::is_empty(verifyDir));
376     EXPECT_TRUE(fs::exists(verifyPath));
377 
378     // Check that installed cert is identical to input one
379     EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
380 
381     using NotAllowed =
382         sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
383     EXPECT_THROW(
384         {
385             try
386             {
387                 // Try to install the same certificate second time
388                 mainApp.install(certificateFile);
389             }
390             catch (const NotAllowed& e)
391             {
392                 throw;
393             }
394         },
395         NotAllowed);
396 
397     // Check that the original certificate has been not removed
398     EXPECT_FALSE(fs::is_empty(verifyDir));
399     EXPECT_TRUE(fs::exists(verifyPath));
400 }
401 
402 /** @brief Check if in authority mode user can install a certificate with
403  * certain subject hash twice.
404  */
405 TEST_F(TestCertificates, InvokeInstallSameSubjectTwice)
406 {
407     std::string endpoint("ldap");
408     std::string unit;
409     CertificateType type = CertificateType::Authority;
410     std::string verifyDir(certDir);
411     std::string verifyUnit(unit);
412     auto objPath = std::string(objectNamePrefix) + '/' +
413                    certificateTypeToString(type) + '/' + endpoint;
414     auto event = sdeventplus::Event::get_default();
415     // Attach the bus to sd_event to service user requests
416     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
417     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
418                     std::move(certDir));
419     MainApp mainApp(&manager);
420     mainApp.install(certificateFile);
421 
422     std::vector<std::unique_ptr<Certificate>>& certs =
423         manager.getCertificates();
424 
425     EXPECT_FALSE(certs.empty());
426 
427     // Check that certificate has been created at installation directory
428     std::string verifyPath0 =
429         verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
430     EXPECT_FALSE(fs::is_empty(verifyDir));
431     EXPECT_TRUE(fs::exists(verifyPath0));
432 
433     // Check that installed cert is identical to input one
434     EXPECT_TRUE(compareFiles(certificateFile, verifyPath0));
435 
436     // Prepare second certificate with the same subject
437     createNewCertificate();
438 
439     // Install second certificate
440     mainApp.install(certificateFile);
441 
442     // Expect there are exactly two certificates in the collection
443     EXPECT_EQ(certs.size(), 2);
444 
445     // Check that certificate has been created at installation directory
446     std::string verifyPath1 =
447         verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".1";
448     EXPECT_TRUE(fs::exists(verifyPath1));
449 
450     // Check that installed cert is identical to input one
451     EXPECT_TRUE(compareFiles(certificateFile, verifyPath1));
452 
453     // Check that the original/first certificate has been not removed
454     EXPECT_FALSE(fs::is_empty(verifyDir));
455     EXPECT_TRUE(fs::exists(verifyPath0));
456 }
457 
458 /** @brief Check if in authority mode user can't install more than
459  * maxNumAuthorityCertificates certificates.
460  */
461 TEST_F(TestCertificates, InvokeInstallAuthCertLimit)
462 {
463     std::string endpoint("ldap");
464     std::string unit;
465     CertificateType type = CertificateType::Authority;
466     std::string verifyDir(certDir);
467     std::string verifyUnit(unit);
468     auto objPath = std::string(objectNamePrefix) + '/' +
469                    certificateTypeToString(type) + '/' + endpoint;
470     auto event = sdeventplus::Event::get_default();
471     // Attach the bus to sd_event to service user requests
472     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
473     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
474                     std::move(certDir));
475     MainApp mainApp(&manager);
476 
477     std::vector<std::unique_ptr<Certificate>>& certs =
478         manager.getCertificates();
479 
480     std::vector<std::string> verifyPaths;
481 
482     // Prepare maximum number of ceritificates
483     for (std::size_t i = 0; i < maxNumAuthorityCertificates; ++i)
484     {
485         // Prepare new certificatate
486         createNewCertificate(true);
487 
488         // Install ceritificate
489         mainApp.install(certificateFile);
490 
491         // Check number of certificates in the collection
492         EXPECT_EQ(certs.size(), i + 1);
493 
494         // Check that certificate has been created at installation directory
495         std::string verifyPath =
496             verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
497         EXPECT_FALSE(fs::is_empty(verifyDir));
498         EXPECT_TRUE(fs::exists(verifyPath));
499 
500         // Check that installed cert is identical to input one
501         EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
502 
503         // Save current certificate file for later check
504         verifyPaths.push_back(verifyPath);
505     }
506 
507     // Prepare new certificatate
508     createNewCertificate(true);
509 
510     using NotAllowed =
511         sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
512     EXPECT_THROW(
513         {
514             try
515             {
516                 // Try to install one more certificate
517                 mainApp.install(certificateFile);
518             }
519             catch (const NotAllowed& e)
520             {
521                 throw;
522             }
523         },
524         NotAllowed);
525 
526     // Check that the original certificate has been not removed
527     EXPECT_FALSE(fs::is_empty(verifyDir));
528     for (size_t i = 0; i < maxNumAuthorityCertificates; ++i)
529     {
530         EXPECT_TRUE(fs::exists(verifyPaths[i]));
531     }
532 }
533 
534 /** @brief Compare the installed certificate with the copied certificate
535  */
536 TEST_F(TestCertificates, CompareInstalledCertificate)
537 {
538     std::string endpoint("ldap");
539     std::string unit;
540     CertificateType type = CertificateType::Client;
541     ;
542     std::string installPath(certDir + "/" + certificateFile);
543     std::string verifyPath(installPath);
544     std::string verifyUnit(unit);
545     auto objPath = std::string(objectNamePrefix) + '/' +
546                    certificateTypeToString(type) + '/' + endpoint;
547     auto event = sdeventplus::Event::get_default();
548     // Attach the bus to sd_event to service user requests
549     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
550     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
551                     std::move(installPath));
552     MainApp mainApp(&manager);
553     mainApp.install(certificateFile);
554     EXPECT_TRUE(fs::exists(verifyPath));
555     EXPECT_TRUE(compareFiles(verifyPath, certificateFile));
556 }
557 
558 /** @brief Check if install fails if certificate file is not found
559  */
560 TEST_F(TestCertificates, TestNoCertificateFile)
561 {
562     std::string endpoint("ldap");
563     std::string unit;
564     CertificateType type = CertificateType::Client;
565     ;
566     std::string installPath(certDir + "/" + certificateFile);
567     std::string verifyPath(installPath);
568     std::string verifyUnit(unit);
569     auto objPath = std::string(objectNamePrefix) + '/' +
570                    certificateTypeToString(type) + '/' + endpoint;
571     std::string uploadFile = "nofile.pem";
572     EXPECT_THROW(
573         {
574             try
575             {
576                 auto event = sdeventplus::Event::get_default();
577                 // Attach the bus to sd_event to service user requests
578                 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
579                 Manager manager(bus, event, objPath.c_str(), type,
580                                 std::move(unit), std::move(installPath));
581                 MainApp mainApp(&manager);
582                 mainApp.install(uploadFile);
583             }
584             catch (const InternalFailure& e)
585             {
586                 throw;
587             }
588         },
589         InternalFailure);
590     EXPECT_FALSE(fs::exists(verifyPath));
591 }
592 
593 /** @brief Test replacing existing certificate
594  */
595 TEST_F(TestCertificates, TestReplaceCertificate)
596 {
597     std::string endpoint("ldap");
598     std::string unit;
599     CertificateType type = CertificateType::Server;
600     std::string installPath(certDir + "/" + certificateFile);
601     std::string verifyPath(installPath);
602     auto objPath = std::string(objectNamePrefix) + '/' +
603                    certificateTypeToString(type) + '/' + endpoint;
604     auto event = sdeventplus::Event::get_default();
605     // Attach the bus to sd_event to service user requests
606     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
607     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
608                     std::move(installPath));
609     MainApp mainApp(&manager);
610     mainApp.install(certificateFile);
611     EXPECT_TRUE(fs::exists(verifyPath));
612     std::vector<std::unique_ptr<Certificate>>& certs =
613         manager.getCertificates();
614     EXPECT_FALSE(certs.empty());
615     EXPECT_NE(certs[0], nullptr);
616     certs[0]->replace(certificateFile);
617     EXPECT_TRUE(fs::exists(verifyPath));
618 }
619 
620 /** @brief Test replacing existing certificate
621  */
622 TEST_F(TestCertificates, TestAuthorityReplaceCertificate)
623 {
624     std::string endpoint("ldap");
625     std::string unit;
626     CertificateType type = CertificateType::Authority;
627     std::string verifyDir(certDir);
628     std::string verifyUnit(unit);
629     auto objPath = std::string(objectNamePrefix) + '/' +
630                    certificateTypeToString(type) + '/' + endpoint;
631     auto event = sdeventplus::Event::get_default();
632     // Attach the bus to sd_event to service user requests
633     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
634     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
635                     std::move(certDir));
636     MainApp mainApp(&manager);
637     mainApp.install(certificateFile);
638 
639     std::vector<std::unique_ptr<Certificate>>& certs =
640         manager.getCertificates();
641     constexpr const unsigned int REPLACE_ITERATIONS = 10;
642 
643     for (unsigned int i = 0; i < REPLACE_ITERATIONS; i++)
644     {
645         // Certificate successfully installed
646         EXPECT_FALSE(certs.empty());
647 
648         std::string verifyPath =
649             verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
650 
651         // Check that certificate has been created at installation directory
652         EXPECT_FALSE(fs::is_empty(verifyDir));
653         EXPECT_TRUE(fs::exists(verifyPath));
654 
655         // Check that installed cert is identical to input one
656         EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
657 
658         // Create new certificate
659         createNewCertificate(true);
660 
661         certs[0]->replace(certificateFile);
662 
663         // Verify that old certificate has been removed
664         EXPECT_FALSE(fs::exists(verifyPath));
665     }
666 }
667 
668 /** @brief Test verifiing if delete function works.
669  */
670 TEST_F(TestCertificates, TestStorageDeleteCertificate)
671 {
672     std::string endpoint("ldap");
673     std::string unit;
674     CertificateType type = CertificateType::Authority;
675     std::string verifyDir(certDir);
676     std::string verifyUnit(unit);
677     auto objPath = std::string(objectNamePrefix) + '/' +
678                    certificateTypeToString(type) + '/' + endpoint;
679     auto event = sdeventplus::Event::get_default();
680     // Attach the bus to sd_event to service user requests
681     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
682     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
683                     std::move(certDir));
684     MainApp mainApp(&manager);
685 
686     // Check if certificate placeholder dir is empty
687     EXPECT_TRUE(fs::is_empty(verifyDir));
688     mainApp.install(certificateFile);
689 
690     // Create new certificate
691     createNewCertificate(true);
692     mainApp.install(certificateFile);
693 
694     createNewCertificate(true);
695     mainApp.install(certificateFile);
696 
697     std::vector<std::unique_ptr<Certificate>>& certs =
698         manager.getCertificates();
699 
700     // All 3 certificates successfully installed and added to manager
701     EXPECT_EQ(certs.size(), 3);
702 
703     // Check if certificate placeholder is not empty, there should be 3
704     // certificates
705     EXPECT_FALSE(fs::is_empty(verifyDir));
706 
707     certs[0]->delete_();
708     EXPECT_EQ(certs.size(), 2);
709 
710     certs[0]->delete_();
711     EXPECT_EQ(certs.size(), 1);
712 
713     certs[0]->delete_();
714     EXPECT_EQ(certs.size(), 0);
715 
716     // Check if certificate placeholder is empty.
717     EXPECT_TRUE(fs::is_empty(verifyDir));
718 }
719 
720 /** @brief Check if install fails if certificate file is empty
721  */
722 TEST_F(TestCertificates, TestEmptyCertificateFile)
723 {
724     std::string endpoint("ldap");
725     std::string unit;
726     CertificateType type = CertificateType::Client;
727     ;
728     std::string installPath(certDir + "/" + certificateFile);
729     std::string verifyPath(installPath);
730     std::string verifyUnit(unit);
731     auto objPath = std::string(objectNamePrefix) + '/' +
732                    certificateTypeToString(type) + '/' + endpoint;
733     std::string emptyFile("emptycert.pem");
734     std::ofstream ofs;
735     ofs.open(emptyFile, std::ofstream::out);
736     ofs.close();
737     EXPECT_THROW(
738         {
739             try
740             {
741                 auto event = sdeventplus::Event::get_default();
742                 // Attach the bus to sd_event to service user requests
743                 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
744                 Manager manager(bus, event, objPath.c_str(), type,
745                                 std::move(unit), std::move(installPath));
746                 MainApp mainApp(&manager);
747                 mainApp.install(emptyFile);
748             }
749             catch (const InvalidCertificate& e)
750             {
751                 throw;
752             }
753         },
754         InvalidCertificate);
755     EXPECT_FALSE(fs::exists(verifyPath));
756     fs::remove(emptyFile);
757 }
758 
759 /** @brief Check if install fails if certificate file is corrupted
760  */
761 TEST_F(TestCertificates, TestInvalidCertificateFile)
762 {
763     std::string endpoint("ldap");
764     std::string unit;
765     CertificateType type = CertificateType::Client;
766     ;
767 
768     std::ofstream ofs;
769     ofs.open(certificateFile, std::ofstream::out);
770     ofs << "-----BEGIN CERTIFICATE-----";
771     ofs << "ADD_SOME_INVALID_DATA_INTO_FILE";
772     ofs << "-----END CERTIFICATE-----";
773     ofs.close();
774 
775     std::string installPath(certDir + "/" + certificateFile);
776     std::string verifyPath(installPath);
777     std::string verifyUnit(unit);
778     auto objPath = std::string(objectNamePrefix) + '/' +
779                    certificateTypeToString(type) + '/' + endpoint;
780     EXPECT_THROW(
781         {
782             try
783             {
784                 auto event = sdeventplus::Event::get_default();
785                 // Attach the bus to sd_event to service user requests
786                 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
787                 Manager manager(bus, event, objPath.c_str(), type,
788                                 std::move(unit), std::move(installPath));
789                 MainApp mainApp(&manager);
790                 mainApp.install(certificateFile);
791             }
792             catch (const InvalidCertificate& e)
793             {
794                 throw;
795             }
796         },
797         InvalidCertificate);
798     EXPECT_FALSE(fs::exists(verifyPath));
799 }
800 
801 /**
802  * Class to generate private and certificate only file and test verification
803  */
804 class TestInvalidCertificate : public ::testing::Test
805 {
806   public:
807     TestInvalidCertificate() : bus(sdbusplus::bus::new_default())
808     {
809     }
810     void SetUp() override
811     {
812         char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
813         auto dirPtr = mkdtemp(dirTemplate);
814         if (dirPtr == nullptr)
815         {
816             throw std::bad_alloc();
817         }
818         certDir = std::string(dirPtr) + "/certs";
819         fs::create_directories(certDir);
820         certificateFile = "cert.pem";
821         keyFile = "key.pem";
822         std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
823         cmd += "-keyout key.pem -out cert.pem -days 3650 ";
824         cmd += "-subj "
825                "/O=openbmc-project.xyz/CN=localhost"
826                " -nodes";
827 
828         auto val = std::system(cmd.c_str());
829         if (val)
830         {
831             std::cout << "command Error: " << val << std::endl;
832         }
833     }
834     void TearDown() override
835     {
836         fs::remove_all(certDir);
837         fs::remove(certificateFile);
838         fs::remove(keyFile);
839     }
840 
841   protected:
842     sdbusplus::bus::bus bus;
843     std::string certificateFile;
844     std::string keyFile;
845     std::string certDir;
846 };
847 
848 /** @brief Check install fails if private key is missing in certificate file
849  */
850 TEST_F(TestInvalidCertificate, TestMissingPrivateKey)
851 {
852     std::string endpoint("ldap");
853     std::string unit;
854     CertificateType type = CertificateType::Client;
855     ;
856     std::string installPath(certDir + "/" + certificateFile);
857     std::string verifyPath(installPath);
858     std::string verifyUnit(unit);
859     auto objPath = std::string(objectNamePrefix) + '/' +
860                    certificateTypeToString(type) + '/' + endpoint;
861     EXPECT_THROW(
862         {
863             try
864             {
865                 auto event = sdeventplus::Event::get_default();
866                 // Attach the bus to sd_event to service user requests
867                 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
868                 Manager manager(bus, event, objPath.c_str(), type,
869                                 std::move(unit), std::move(installPath));
870                 MainApp mainApp(&manager);
871                 mainApp.install(certificateFile);
872             }
873             catch (const InternalFailure& e)
874             {
875                 throw;
876             }
877         },
878         InternalFailure);
879     EXPECT_FALSE(fs::exists(verifyPath));
880 }
881 
882 /** @brief Check install fails if ceritificate is missing in certificate file
883  */
884 TEST_F(TestInvalidCertificate, TestMissingCeritificate)
885 {
886     std::string endpoint("ldap");
887     std::string unit;
888     CertificateType type = CertificateType::Client;
889     ;
890     std::string installPath(certDir + "/" + keyFile);
891     std::string verifyPath(installPath);
892     std::string verifyUnit(unit);
893     auto objPath = std::string(objectNamePrefix) + '/' +
894                    certificateTypeToString(type) + '/' + endpoint;
895     EXPECT_THROW(
896         {
897             try
898             {
899                 auto event = sdeventplus::Event::get_default();
900                 // Attach the bus to sd_event to service user requests
901                 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
902                 Manager manager(bus, event, objPath.c_str(), type,
903                                 std::move(unit), std::move(installPath));
904                 MainApp mainApp(&manager);
905                 mainApp.install(keyFile);
906             }
907             catch (const InternalFailure& e)
908             {
909                 throw;
910             }
911         },
912         InvalidCertificate);
913     EXPECT_FALSE(fs::exists(verifyPath));
914 }
915 
916 /** @brief Check if error is thrown when multiple certificates are installed
917  *  At present only one certificate per service is allowed
918  */
919 TEST_F(TestCertificates, TestCertInstallNotAllowed)
920 {
921     using NotAllowed =
922         sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
923     std::string endpoint("ldap");
924     std::string unit;
925     CertificateType type = CertificateType::Client;
926     ;
927     std::string installPath(certDir + "/" + certificateFile);
928     std::string verifyPath(installPath);
929     auto objPath = std::string(objectNamePrefix) + '/' +
930                    certificateTypeToString(type) + '/' + endpoint;
931     auto event = sdeventplus::Event::get_default();
932     // Attach the bus to sd_event to service user requests
933     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
934     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
935                     std::move(installPath));
936     MainApp mainApp(&manager);
937     mainApp.install(certificateFile);
938     EXPECT_TRUE(fs::exists(verifyPath));
939     EXPECT_THROW(
940         {
941             try
942             {
943                 // install second certificate
944                 mainApp.install(certificateFile);
945             }
946             catch (const NotAllowed& e)
947             {
948                 throw;
949             }
950         },
951         NotAllowed);
952 }
953 
954 TEST_F(TestCertificates, TestGenerateCSR)
955 {
956     std::string endpoint("https");
957     std::string unit;
958     CertificateType type = CertificateType::Server;
959     std::string installPath(certDir + "/" + certificateFile);
960     std::string verifyPath(installPath);
961     std::string CSRPath(certDir + "/" + CSRFile);
962     std::string privateKeyPath(certDir + "/" + privateKeyFile);
963     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
964     std::string challengePassword("Password");
965     std::string city("HYB");
966     std::string commonName("abc.com");
967     std::string contactPerson("Admin");
968     std::string country("IN");
969     std::string email("admin@in.ibm.com");
970     std::string givenName("givenName");
971     std::string initials("G");
972     int64_t keyBitLength(2048);
973     std::string keyCurveId("0");
974     std::string keyPairAlgorithm("RSA");
975     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
976     std::string organization("IBM");
977     std::string organizationalUnit("orgUnit");
978     std::string state("TS");
979     std::string surname("surname");
980     std::string unstructuredName("unstructuredName");
981     auto objPath = std::string(objectNamePrefix) + '/' +
982                    certificateTypeToString(type) + '/' + endpoint;
983     auto event = sdeventplus::Event::get_default();
984     // Attach the bus to sd_event to service user requests
985     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
986     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
987                     std::move(installPath));
988     Status status;
989     CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
990     MainApp mainApp(&manager, &csr);
991     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
992                         contactPerson, country, email, givenName, initials,
993                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
994                         organization, organizationalUnit, state, surname,
995                         unstructuredName);
996     std::string csrData("");
997     // generateCSR takes considerable time to create CSR and privateKey Files
998     EXPECT_FALSE(fs::exists(CSRPath));
999     EXPECT_FALSE(fs::exists(privateKeyPath));
1000     EXPECT_THROW(
1001         {
1002             try
1003             {
1004                 csrData = csr.csr();
1005             }
1006             catch (const InternalFailure& e)
1007             {
1008                 throw;
1009             }
1010         },
1011         InternalFailure);
1012     // wait for 10 sec to get CSR and privateKey Files generated
1013     sleep(10);
1014     EXPECT_TRUE(fs::exists(CSRPath));
1015     EXPECT_TRUE(fs::exists(privateKeyPath));
1016     csrData = csr.csr();
1017     ASSERT_NE("", csrData.c_str());
1018 }
1019 
1020 /** @brief Check if ECC key pair is generated when user is not given algorithm
1021  * type. At present RSA and EC key pair algorithm are supported
1022  */
1023 TEST_F(TestCertificates, TestGenerateCSRwithEmptyKeyPairAlgorithm)
1024 {
1025     std::string endpoint("https");
1026     std::string unit;
1027     CertificateType type = CertificateType::Server;
1028     std::string installPath(certDir + "/" + certificateFile);
1029     std::string verifyPath(installPath);
1030     std::string CSRPath(certDir + "/" + CSRFile);
1031     std::string privateKeyPath(certDir + "/" + privateKeyFile);
1032     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1033     std::string challengePassword("Password");
1034     std::string city("HYB");
1035     std::string commonName("abc.com");
1036     std::string contactPerson("Admin");
1037     std::string country("IN");
1038     std::string email("admin@in.ibm.com");
1039     std::string givenName("givenName");
1040     std::string initials("G");
1041     int64_t keyBitLength(2048);
1042     std::string keyCurveId("");
1043     std::string keyPairAlgorithm("");
1044     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1045     std::string organization("IBM");
1046     std::string organizationalUnit("orgUnit");
1047     std::string state("TS");
1048     std::string surname("surname");
1049     std::string unstructuredName("unstructuredName");
1050     auto objPath = std::string(objectNamePrefix) + '/' +
1051                    certificateTypeToString(type) + '/' + endpoint;
1052     auto event = sdeventplus::Event::get_default();
1053     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1054                     std::move(installPath));
1055     Status status;
1056     CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1057     MainApp mainApp(&manager, &csr);
1058     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1059                         contactPerson, country, email, givenName, initials,
1060                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1061                         organization, organizationalUnit, state, surname,
1062                         unstructuredName);
1063     sleep(10);
1064     EXPECT_TRUE(fs::exists(CSRPath));
1065     EXPECT_TRUE(fs::exists(privateKeyPath));
1066 }
1067 
1068 /** @brief Check if error is thrown when giving un supported key pair
1069  * algorithm. At present RSA and EC key pair algorithm are supported
1070  */
1071 TEST_F(TestCertificates, TestGenerateCSRwithUnsupportedKeyPairAlgorithm)
1072 {
1073     std::string endpoint("https");
1074     std::string unit;
1075     CertificateType type = CertificateType::Server;
1076     std::string installPath(certDir + "/" + certificateFile);
1077     std::string verifyPath(installPath);
1078     std::string CSRPath(certDir + "/" + CSRFile);
1079     std::string privateKeyPath(certDir + "/" + privateKeyFile);
1080     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1081     std::string challengePassword("Password");
1082     std::string city("HYB");
1083     std::string commonName("abc.com");
1084     std::string contactPerson("Admin");
1085     std::string country("IN");
1086     std::string email("admin@in.ibm.com");
1087     std::string givenName("givenName");
1088     std::string initials("G");
1089     int64_t keyBitLength(2048);
1090     std::string keyCurveId("secp521r1");
1091     std::string keyPairAlgorithm("UnSupportedAlgorithm");
1092     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1093     std::string organization("IBM");
1094     std::string organizationalUnit("orgUnit");
1095     std::string state("TS");
1096     std::string surname("surname");
1097     std::string unstructuredName("unstructuredName");
1098     auto objPath = std::string(objectNamePrefix) + '/' +
1099                    certificateTypeToString(type) + '/' + endpoint;
1100     auto event = sdeventplus::Event::get_default();
1101     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1102                     std::move(installPath));
1103     Status status;
1104     CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1105     MainApp mainApp(&manager, &csr);
1106     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1107                         contactPerson, country, email, givenName, initials,
1108                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1109                         organization, organizationalUnit, state, surname,
1110                         unstructuredName);
1111     EXPECT_FALSE(fs::exists(CSRPath));
1112     EXPECT_FALSE(fs::exists(privateKeyPath));
1113 }
1114 
1115 /** @brief Check if error is thrown when NID_undef is returned for given key
1116  * curve id
1117  */
1118 TEST_F(TestCertificates, TestECKeyGenerationwithNIDundefCase)
1119 {
1120     std::string endpoint("https");
1121     std::string unit;
1122     CertificateType type = CertificateType::Server;
1123     std::string installPath(certDir + "/" + certificateFile);
1124     std::string verifyPath(installPath);
1125     std::string CSRPath(certDir + "/" + CSRFile);
1126     std::string privateKeyPath(certDir + "/" + privateKeyFile);
1127     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1128     std::string challengePassword("Password");
1129     std::string city("BLR");
1130     std::string commonName("abc.com");
1131     std::string contactPerson("Admin");
1132     std::string country("IN");
1133     std::string email("admin@in.ibm.com");
1134     std::string givenName("givenName");
1135     std::string initials("G");
1136     int64_t keyBitLength(2048);
1137     std::string keyCurveId("DummyCurveName");
1138     std::string keyPairAlgorithm("EC");
1139     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1140     std::string organization("IBM");
1141     std::string organizationalUnit("orgUnit");
1142     std::string state("TS");
1143     std::string surname("surname");
1144     std::string unstructuredName("unstructuredName");
1145     auto objPath = std::string(objectNamePrefix) + '/' +
1146                    certificateTypeToString(type) + '/' + endpoint;
1147     auto event = sdeventplus::Event::get_default();
1148     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1149                     std::move(installPath));
1150     Status status;
1151     CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1152     MainApp mainApp(&manager, &csr);
1153     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1154                         contactPerson, country, email, givenName, initials,
1155                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1156                         organization, organizationalUnit, state, surname,
1157                         unstructuredName);
1158     EXPECT_FALSE(fs::exists(CSRPath));
1159     EXPECT_FALSE(fs::exists(privateKeyPath));
1160 }
1161 
1162 /** @brief Check default Key Curve Id is used if given curve id is empty
1163  */
1164 TEST_F(TestCertificates, TestECKeyGenerationwithDefaultKeyCurveId)
1165 {
1166     std::string endpoint("https");
1167     std::string unit;
1168     CertificateType type = CertificateType::Server;
1169     std::string installPath(certDir + "/" + certificateFile);
1170     std::string verifyPath(installPath);
1171     std::string CSRPath(certDir + "/" + CSRFile);
1172     std::string privateKeyPath(certDir + "/" + privateKeyFile);
1173     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1174     std::string challengePassword("Password");
1175     std::string city("BLR");
1176     std::string commonName("abc.com");
1177     std::string contactPerson("Admin");
1178     std::string country("IN");
1179     std::string email("admin@in.ibm.com");
1180     std::string givenName("givenName");
1181     std::string initials("G");
1182     int64_t keyBitLength(2048);
1183     std::string keyCurveId("");
1184     std::string keyPairAlgorithm("EC");
1185     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1186     std::string organization("IBM");
1187     std::string organizationalUnit("orgUnit");
1188     std::string state("TS");
1189     std::string surname("surname");
1190     std::string unstructuredName("unstructuredName");
1191     auto objPath = std::string(objectNamePrefix) + '/' +
1192                    certificateTypeToString(type) + '/' + endpoint;
1193     auto event = sdeventplus::Event::get_default();
1194     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1195                     std::move(installPath));
1196     Status status;
1197     CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1198     MainApp mainApp(&manager, &csr);
1199     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1200                         contactPerson, country, email, givenName, initials,
1201                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1202                         organization, organizationalUnit, state, surname,
1203                         unstructuredName);
1204     sleep(10);
1205     EXPECT_TRUE(fs::exists(CSRPath));
1206     EXPECT_TRUE(fs::exists(privateKeyPath));
1207 }
1208 
1209 /** @brief Check if error is not thrown to generate EC key pair
1210  */
1211 TEST_F(TestCertificates, TestECKeyGeneration)
1212 {
1213     std::string endpoint("https");
1214     std::string unit;
1215     CertificateType type = CertificateType::Server;
1216     std::string installPath(certDir + "/" + certificateFile);
1217     std::string verifyPath(installPath);
1218     std::string CSRPath(certDir + "/" + CSRFile);
1219     std::string privateKeyPath(certDir + "/" + privateKeyFile);
1220     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1221     std::string challengePassword("Password");
1222     std::string city("BLR");
1223     std::string commonName("abc.com");
1224     std::string contactPerson("Admin");
1225     std::string country("IN");
1226     std::string email("admin@in.ibm.com");
1227     std::string givenName("givenName");
1228     std::string initials("G");
1229     int64_t keyBitLength(2048);
1230     std::string keyCurveId("secp521r1");
1231     std::string keyPairAlgorithm("EC");
1232     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1233     std::string organization("IBM");
1234     std::string organizationalUnit("orgUnit");
1235     std::string state("TS");
1236     std::string surname("surname");
1237     std::string unstructuredName("unstructuredName");
1238     auto objPath = std::string(objectNamePrefix) + '/' +
1239                    certificateTypeToString(type) + '/' + endpoint;
1240     auto event = sdeventplus::Event::get_default();
1241     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1242                     std::move(installPath));
1243     Status status;
1244     CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1245     MainApp mainApp(&manager, &csr);
1246     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1247                         contactPerson, country, email, givenName, initials,
1248                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1249                         organization, organizationalUnit, state, surname,
1250                         unstructuredName);
1251     std::cout << "CSRPath: " << CSRPath << std::endl
1252               << "privateKeyPath: " << privateKeyPath << std::endl;
1253     sleep(10);
1254     EXPECT_TRUE(fs::exists(CSRPath));
1255     EXPECT_TRUE(fs::exists(privateKeyPath));
1256 }
1257 
1258 /** @brief Check error is thrown if giving unsupported key bit length to
1259  * generate rsa key
1260  */
1261 TEST_F(TestCertificates, TestRSAKeyWithUnsupportedKeyBitLength)
1262 {
1263     std::string endpoint("https");
1264     std::string unit;
1265     CertificateType type = CertificateType::Server;
1266     std::string installPath(certDir + "/" + certificateFile);
1267     std::string verifyPath(installPath);
1268     std::string CSRPath(certDir + "/" + CSRFile);
1269     std::string privateKeyPath(certDir + "/" + privateKeyFile);
1270     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1271     std::string challengePassword("Password");
1272     std::string city("BLR");
1273     std::string commonName("abc.com");
1274     std::string contactPerson("Admin");
1275     std::string country("IN");
1276     std::string email("admin@in.ibm.com");
1277     std::string givenName("givenName");
1278     std::string initials("G");
1279     int64_t keyBitLength(4096);
1280     std::string keyCurveId("secp521r1");
1281     std::string keyPairAlgorithm("RSA");
1282     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1283     std::string organization("IBM");
1284     std::string organizationalUnit("orgUnit");
1285     std::string state("TS");
1286     std::string surname("surname");
1287     std::string unstructuredName("unstructuredName");
1288     auto objPath = std::string(objectNamePrefix) + '/' +
1289                    certificateTypeToString(type) + '/' + endpoint;
1290     auto event = sdeventplus::Event::get_default();
1291     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1292                     std::move(installPath));
1293     Status status;
1294     CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1295     MainApp mainApp(&manager, &csr);
1296     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1297                         contactPerson, country, email, givenName, initials,
1298                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1299                         organization, organizationalUnit, state, surname,
1300                         unstructuredName);
1301     EXPECT_FALSE(fs::exists(CSRPath));
1302     EXPECT_FALSE(fs::exists(privateKeyPath));
1303 }
1304 
1305 /** @brief Check error is thrown if generated rsa key file is not present
1306  */
1307 TEST_F(TestCertificates, TestRSAKeyFileNotPresentCase)
1308 {
1309     std::string endpoint("https");
1310     std::string unit;
1311     CertificateType type = CertificateType::Server;
1312     std::string installPath(certDir + "/" + certificateFile);
1313     std::string verifyPath(installPath);
1314     std::string CSRPath(certDir + "/" + CSRFile);
1315     std::string privateKeyPath(certDir + "/" + privateKeyFile);
1316     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1317     std::string challengePassword("Password");
1318     std::string city("BLR");
1319     std::string commonName("abc.com");
1320     std::string contactPerson("Admin");
1321     std::string country("IN");
1322     std::string email("admin@in.ibm.com");
1323     std::string givenName("givenName");
1324     std::string initials("G");
1325     int64_t keyBitLength(2048);
1326     std::string keyCurveId("secp521r1");
1327     std::string keyPairAlgorithm("RSA");
1328     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1329     std::string organization("IBM");
1330     std::string organizationalUnit("orgUnit");
1331     std::string state("TS");
1332     std::string surname("surname");
1333     std::string unstructuredName("unstructuredName");
1334     auto objPath = std::string(objectNamePrefix) + '/' +
1335                    certificateTypeToString(type) + '/' + endpoint;
1336     auto event = sdeventplus::Event::get_default();
1337     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1338                     std::move(installPath));
1339 
1340     // Removing generated RSA key file
1341     fs::remove(rsaPrivateKeyFilePath);
1342 
1343     Status status;
1344     CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1345     MainApp mainApp(&manager, &csr);
1346     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1347                         contactPerson, country, email, givenName, initials,
1348                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1349                         organization, organizationalUnit, state, surname,
1350                         unstructuredName);
1351     EXPECT_FALSE(fs::exists(CSRPath));
1352     EXPECT_FALSE(fs::exists(privateKeyPath));
1353 }
1354 
1355 /** @brief Check private key file is created from generated rsa key file is
1356  * `present
1357  */
1358 TEST_F(TestCertificates, TestRSAKeyFromRSAKeyFileIsWrittenIntoPrivateKeyFile)
1359 {
1360     std::string endpoint("https");
1361     std::string unit;
1362     CertificateType type = CertificateType::Server;
1363     std::string installPath(certDir + "/" + certificateFile);
1364     std::string verifyPath(installPath);
1365     std::string CSRPath(certDir + "/" + CSRFile);
1366     std::string privateKeyPath(certDir + "/" + privateKeyFile);
1367     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1368     std::string challengePassword("Password");
1369     std::string city("BLR");
1370     std::string commonName("abc.com");
1371     std::string contactPerson("Admin");
1372     std::string country("IN");
1373     std::string email("admin@in.ibm.com");
1374     std::string givenName("givenName");
1375     std::string initials("G");
1376     int64_t keyBitLength(2048);
1377     std::string keyCurveId("secp521r1");
1378     std::string keyPairAlgorithm("RSA");
1379     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1380     std::string organization("IBM");
1381     std::string organizationalUnit("orgUnit");
1382     std::string state("TS");
1383     std::string surname("surname");
1384     std::string unstructuredName("unstructuredName");
1385     auto objPath = std::string(objectNamePrefix) + '/' +
1386                    certificateTypeToString(type) + '/' + endpoint;
1387     auto event = sdeventplus::Event::get_default();
1388     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1389                     std::move(installPath));
1390     Status status;
1391     CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
1392     MainApp mainApp(&manager, &csr);
1393     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1394                         contactPerson, country, email, givenName, initials,
1395                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1396                         organization, organizationalUnit, state, surname,
1397                         unstructuredName);
1398     sleep(10);
1399     EXPECT_TRUE(fs::exists(CSRPath));
1400     EXPECT_TRUE(fs::exists(privateKeyPath));
1401 }
1402 
1403 /** @brief Check RSA key is generated during application startup*/
1404 TEST_F(TestCertificates, TestGenerateRSAPrivateKeyFile)
1405 {
1406     std::string endpoint("https");
1407     std::string unit;
1408     CertificateType type = CertificateType::Server;
1409     std::string installPath(certDir + "/" + certificateFile);
1410     auto objPath = std::string(objectNamePrefix) + '/' +
1411                    certificateTypeToString(type) + '/' + endpoint;
1412     auto event = sdeventplus::Event::get_default();
1413 
1414     EXPECT_FALSE(fs::exists(rsaPrivateKeyFilePath));
1415     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1416                     std::move(installPath));
1417     EXPECT_TRUE(fs::exists(rsaPrivateKeyFilePath));
1418 }
1419 } // namespace
1420 } // namespace phosphor::certs
1421