113bf74e4SMarri Devender Rao #include "config.h"
213bf74e4SMarri Devender Rao 
38841dbd6SMarri Devender Rao #include "certificate.hpp"
4947258dcSMarri Devender Rao #include "certs_manager.hpp"
5014be0bfSNan Zhou #include "csr.hpp"
6947258dcSMarri Devender Rao 
72f3563ccSZbigniew Lukwinski #include <openssl/bio.h>
8014be0bfSNan Zhou #include <openssl/ossl_typ.h>
92f3563ccSZbigniew Lukwinski #include <openssl/pem.h>
10014be0bfSNan Zhou #include <openssl/x509.h>
11014be0bfSNan Zhou #include <systemd/sd-event.h>
12014be0bfSNan Zhou #include <unistd.h>
132f3563ccSZbigniew Lukwinski 
14223e4604SPatrick Williams #include <sdbusplus/bus.hpp>
15223e4604SPatrick Williams #include <sdeventplus/event.hpp>
16223e4604SPatrick Williams #include <xyz/openbmc_project/Certs/error.hpp>
17223e4604SPatrick Williams #include <xyz/openbmc_project/Common/error.hpp>
18223e4604SPatrick Williams 
19014be0bfSNan Zhou #include <cstdint>
20014be0bfSNan Zhou #include <cstdio>
21014be0bfSNan Zhou #include <cstdlib>
228841dbd6SMarri Devender Rao #include <filesystem>
23947258dcSMarri Devender Rao #include <fstream>
24014be0bfSNan Zhou #include <iostream>
25947258dcSMarri Devender Rao #include <iterator>
26014be0bfSNan Zhou #include <memory>
27014be0bfSNan Zhou #include <new>
28947258dcSMarri Devender Rao #include <string>
296ec13c8fSNan Zhou #include <unordered_set>
30014be0bfSNan Zhou #include <utility>
31014be0bfSNan Zhou #include <vector>
32947258dcSMarri Devender Rao 
336ec13c8fSNan Zhou #include <gmock/gmock.h>
34947258dcSMarri Devender Rao #include <gtest/gtest.h>
35e1289adfSNan Zhou 
36e1289adfSNan Zhou namespace phosphor::certs
37e1289adfSNan Zhou {
38e1289adfSNan Zhou namespace
39e1289adfSNan Zhou {
408841dbd6SMarri Devender Rao namespace fs = std::filesystem;
41cf06ccdcSNan Zhou using ::sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate;
42cf06ccdcSNan Zhou using ::sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
436ec13c8fSNan Zhou using ::testing::Eq;
446ec13c8fSNan Zhou using ::testing::Return;
456ec13c8fSNan Zhou // Compares two files; returns true only if the two are the same
compareFiles(const std::string & file1,const std::string & file2)466ec13c8fSNan Zhou bool compareFiles(const std::string& file1, const std::string& file2)
476ec13c8fSNan Zhou {
486ec13c8fSNan Zhou     std::ifstream f1(file1, std::ifstream::binary | std::ifstream::ate);
496ec13c8fSNan Zhou     std::ifstream f2(file2, std::ifstream::binary | std::ifstream::ate);
506ec13c8fSNan Zhou 
516ec13c8fSNan Zhou     if (f1.fail() || f2.fail())
526ec13c8fSNan Zhou     {
536ec13c8fSNan Zhou         return false; // file problem
546ec13c8fSNan Zhou     }
556ec13c8fSNan Zhou 
566ec13c8fSNan Zhou     if (f1.tellg() != f2.tellg())
576ec13c8fSNan Zhou     {
586ec13c8fSNan Zhou         return false; // size mismatch
596ec13c8fSNan Zhou     }
606ec13c8fSNan Zhou 
616ec13c8fSNan Zhou     // seek back to beginning and use std::equal to compare contents
626ec13c8fSNan Zhou     f1.seekg(0, std::ifstream::beg);
636ec13c8fSNan Zhou     f2.seekg(0, std::ifstream::beg);
646ec13c8fSNan Zhou     return std::equal(std::istreambuf_iterator<char>(f1.rdbuf()),
656ec13c8fSNan Zhou                       std::istreambuf_iterator<char>(),
666ec13c8fSNan Zhou                       std::istreambuf_iterator<char>(f2.rdbuf()));
676ec13c8fSNan Zhou }
68e6597c5bSMarri Devender Rao 
69ddf64866SMarri Devender Rao /**
70ddf64866SMarri Devender Rao  * Class to generate certificate file and test verification of certificate file
71ddf64866SMarri Devender Rao  */
728841dbd6SMarri Devender Rao class TestCertificates : public ::testing::Test
73947258dcSMarri Devender Rao {
74947258dcSMarri Devender Rao   public:
TestCertificates()75223e4604SPatrick Williams     TestCertificates() : bus(sdbusplus::bus::new_default()) {}
SetUp()76947258dcSMarri Devender Rao     void SetUp() override
77947258dcSMarri Devender Rao     {
78947258dcSMarri Devender Rao         char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
79947258dcSMarri Devender Rao         auto dirPtr = mkdtemp(dirTemplate);
80cfb5802aSNan Zhou         if (dirPtr == nullptr)
81947258dcSMarri Devender Rao         {
82947258dcSMarri Devender Rao             throw std::bad_alloc();
83947258dcSMarri Devender Rao         }
84fe590c4eSZbigniew Lukwinski         certDir = std::string(dirPtr) + "/certs";
85fe590c4eSZbigniew Lukwinski         fs::create_directories(certDir);
86db029c95SKowalski, Kamil 
87db029c95SKowalski, Kamil         createNewCertificate();
88947258dcSMarri Devender Rao     }
89db029c95SKowalski, Kamil 
TearDown()90947258dcSMarri Devender Rao     void TearDown() override
91947258dcSMarri Devender Rao     {
92947258dcSMarri Devender Rao         fs::remove_all(certDir);
93947258dcSMarri Devender Rao         fs::remove(certificateFile);
94f4682712SMarri Devender Rao         fs::remove(CSRFile);
95f4682712SMarri Devender Rao         fs::remove(privateKeyFile);
96cf811c43SNan Zhou         fs::remove_all("demoCA");
97947258dcSMarri Devender Rao     }
98947258dcSMarri Devender Rao 
createNewCertificate(bool setNewCertId=false)99db029c95SKowalski, Kamil     void createNewCertificate(bool setNewCertId = false)
100db029c95SKowalski, Kamil     {
101db029c95SKowalski, Kamil         certificateFile = "cert.pem";
102db029c95SKowalski, Kamil         CSRFile = "domain.csr";
103db029c95SKowalski, Kamil         privateKeyFile = "privkey.pem";
104db029c95SKowalski, Kamil         rsaPrivateKeyFilePath = certDir + "/.rsaprivkey.pem";
105db029c95SKowalski, Kamil         std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
106cf811c43SNan Zhou         cmd += "-keyout cert.pem -out cert.pem -days 365000 -nodes";
107db029c95SKowalski, Kamil         cmd += " -subj /O=openbmc-project.xyz/CN=localhost";
108db029c95SKowalski, Kamil 
109db029c95SKowalski, Kamil         if (setNewCertId)
110db029c95SKowalski, Kamil         {
111db029c95SKowalski, Kamil             cmd += std::to_string(certId++);
112db029c95SKowalski, Kamil         }
113db029c95SKowalski, Kamil 
114db029c95SKowalski, Kamil         auto val = std::system(cmd.c_str());
115db029c95SKowalski, Kamil         if (val)
116db029c95SKowalski, Kamil         {
117db029c95SKowalski, Kamil             std::cout << "COMMAND Error: " << val << std::endl;
118db029c95SKowalski, Kamil         }
119db029c95SKowalski, Kamil     }
120db029c95SKowalski, Kamil 
createNeverExpiredRootCertificate()121cf811c43SNan Zhou     void createNeverExpiredRootCertificate()
122cf811c43SNan Zhou     {
123cf811c43SNan Zhou         // remove the old cert
124cf811c43SNan Zhou         fs::remove(certificateFile);
125cf811c43SNan Zhou 
126cf811c43SNan Zhou         // The following routines create a cert that has NotBefore
127cf811c43SNan Zhou         // set to 1970/01/01 and NotAfter set to 9999/12/31 via the
128cf811c43SNan Zhou         // OpenSSL CA application.
129cf811c43SNan Zhou         certificateFile = "cert.pem";
130cf811c43SNan Zhou         ASSERT_EQ(std::system("mkdir -p demoCA"), 0);
131cf811c43SNan Zhou         ASSERT_EQ(std::system("mkdir -p demoCA/private/"), 0);
132cf811c43SNan Zhou         ASSERT_EQ(std::system("mkdir -p demoCA/newcerts/"), 0);
133cf811c43SNan Zhou         ASSERT_EQ(std::system("touch demoCA/index.txt"), 0);
134cf811c43SNan Zhou         ASSERT_EQ(std::system("echo 1000 > demoCA/serial"), 0);
135cf811c43SNan Zhou         ASSERT_EQ(
136cf811c43SNan Zhou             std::system(
137cf811c43SNan Zhou                 "openssl req -x509 -sha256 -newkey rsa:2048 -keyout "
138cf811c43SNan Zhou                 "demoCA/private/cakey.pem -out demoCA/cacert.pem -nodes "
139cf811c43SNan Zhou                 "-subj /O=openbmc-project.xyz/C=US/ST=CA/CN=localhost-ca"),
140cf811c43SNan Zhou             0);
141cf811c43SNan Zhou         ASSERT_EQ(std::system(
142cf811c43SNan Zhou                       "openssl req -new -newkey rsa:2048 -nodes -keyout "
143cf811c43SNan Zhou                       "demoCA/server.key -out demoCA/server.csr -subj "
144cf811c43SNan Zhou                       "/O=openbmc-project.xyz/C=US/ST=CA/CN=localhost-server"),
145cf811c43SNan Zhou                   0);
146cf811c43SNan Zhou         ASSERT_EQ(
147cf811c43SNan Zhou             std::system(
148cf811c43SNan Zhou                 "openssl ca -batch -startdate 19700101000000Z -enddate "
149cf811c43SNan Zhou                 "99991231235959Z -out cert.pem -infiles demoCA/server.csr"),
150cf811c43SNan Zhou             0);
151cf811c43SNan Zhou     }
152cf811c43SNan Zhou 
compareFiles(const std::string & file1,const std::string & file2)153947258dcSMarri Devender Rao     bool compareFiles(const std::string& file1, const std::string& file2)
154947258dcSMarri Devender Rao     {
155947258dcSMarri Devender Rao         std::ifstream f1(file1, std::ifstream::binary | std::ifstream::ate);
156947258dcSMarri Devender Rao         std::ifstream f2(file2, std::ifstream::binary | std::ifstream::ate);
157947258dcSMarri Devender Rao 
158947258dcSMarri Devender Rao         if (f1.fail() || f2.fail())
159947258dcSMarri Devender Rao         {
160947258dcSMarri Devender Rao             return false; // file problem
161947258dcSMarri Devender Rao         }
162947258dcSMarri Devender Rao 
163947258dcSMarri Devender Rao         if (f1.tellg() != f2.tellg())
164947258dcSMarri Devender Rao         {
165947258dcSMarri Devender Rao             return false; // size mismatch
166947258dcSMarri Devender Rao         }
167947258dcSMarri Devender Rao 
168947258dcSMarri Devender Rao         // seek back to beginning and use std::equal to compare contents
169947258dcSMarri Devender Rao         f1.seekg(0, std::ifstream::beg);
170947258dcSMarri Devender Rao         f2.seekg(0, std::ifstream::beg);
171947258dcSMarri Devender Rao         return std::equal(std::istreambuf_iterator<char>(f1.rdbuf()),
172947258dcSMarri Devender Rao                           std::istreambuf_iterator<char>(),
173947258dcSMarri Devender Rao                           std::istreambuf_iterator<char>(f2.rdbuf()));
174947258dcSMarri Devender Rao     }
175947258dcSMarri Devender Rao 
getCertSubjectNameHash(const std::string & certFilePath)1762f3563ccSZbigniew Lukwinski     std::string getCertSubjectNameHash(const std::string& certFilePath)
1772f3563ccSZbigniew Lukwinski     {
1782f3563ccSZbigniew Lukwinski         std::unique_ptr<X509, decltype(&::X509_free)> cert(X509_new(),
1792f3563ccSZbigniew Lukwinski                                                            ::X509_free);
1802f3563ccSZbigniew Lukwinski         if (!cert)
1812f3563ccSZbigniew Lukwinski         {
1822f3563ccSZbigniew Lukwinski             std::string();
1832f3563ccSZbigniew Lukwinski         }
1842f3563ccSZbigniew Lukwinski 
1852f3563ccSZbigniew Lukwinski         std::unique_ptr<BIO, decltype(&::BIO_free)> bioCert(
1862f3563ccSZbigniew Lukwinski             BIO_new_file(certFilePath.c_str(), "rb"), ::BIO_free);
1872f3563ccSZbigniew Lukwinski         if (!bioCert)
1882f3563ccSZbigniew Lukwinski         {
1892f3563ccSZbigniew Lukwinski             std::string();
1902f3563ccSZbigniew Lukwinski         }
1912f3563ccSZbigniew Lukwinski 
1922f3563ccSZbigniew Lukwinski         X509* x509 = cert.get();
1932f3563ccSZbigniew Lukwinski         if (!PEM_read_bio_X509(bioCert.get(), &x509, nullptr, nullptr))
1942f3563ccSZbigniew Lukwinski         {
1952f3563ccSZbigniew Lukwinski             std::string();
1962f3563ccSZbigniew Lukwinski         }
1972f3563ccSZbigniew Lukwinski 
1982f3563ccSZbigniew Lukwinski         unsigned long hash = X509_subject_name_hash(cert.get());
199e3d47cd4SNan Zhou         static constexpr auto authCertHashLength = 9;
200e3d47cd4SNan Zhou         char hashBuf[authCertHashLength];
2012f3563ccSZbigniew Lukwinski         sprintf(hashBuf, "%08lx", hash);
2022f3563ccSZbigniew Lukwinski         return std::string(hashBuf);
2032f3563ccSZbigniew Lukwinski     }
2042f3563ccSZbigniew Lukwinski 
205947258dcSMarri Devender Rao   protected:
206b3dbfb37SPatrick Williams     sdbusplus::bus_t bus;
207c6e58c7eSRamesh Iyyar     std::string certificateFile, CSRFile, privateKeyFile, rsaPrivateKeyFilePath;
208947258dcSMarri Devender Rao 
209947258dcSMarri Devender Rao     std::string certDir;
210*887ba5bfSRavi Teja     uint64_t certId = 1;
211947258dcSMarri Devender Rao };
212947258dcSMarri Devender Rao 
213947258dcSMarri Devender Rao class MainApp
214947258dcSMarri Devender Rao {
215947258dcSMarri Devender Rao   public:
MainApp(phosphor::certs::Manager * manager,phosphor::certs::CSR * csr=nullptr)216f4682712SMarri Devender Rao     MainApp(phosphor::certs::Manager* manager,
217f4682712SMarri Devender Rao             phosphor::certs::CSR* csr = nullptr) :
218f4682712SMarri Devender Rao         manager(manager),
219e129be3bSPatrick Williams         csr_(csr)
220223e4604SPatrick Williams     {}
install(std::string & path)221947258dcSMarri Devender Rao     void install(std::string& path)
222947258dcSMarri Devender Rao     {
223947258dcSMarri Devender Rao         manager->install(path);
224947258dcSMarri Devender Rao     }
225f4682712SMarri Devender Rao 
generateCSR(std::vector<std::string> alternativeNames,std::string challengePassword,std::string city,std::string commonName,std::string contactPerson,std::string country,std::string email,std::string givenName,std::string initials,int64_t keyBitLength,std::string keyCurveId,std::string keyPairAlgorithm,std::vector<std::string> keyUsage,std::string organization,std::string organizationalUnit,std::string state,std::string surname,std::string unstructuredName)226f4682712SMarri Devender Rao     std::string generateCSR(std::vector<std::string> alternativeNames,
227f4682712SMarri Devender Rao                             std::string challengePassword, std::string city,
228f4682712SMarri Devender Rao                             std::string commonName, std::string contactPerson,
229f4682712SMarri Devender Rao                             std::string country, std::string email,
230f4682712SMarri Devender Rao                             std::string givenName, std::string initials,
231f4682712SMarri Devender Rao                             int64_t keyBitLength, std::string keyCurveId,
232f4682712SMarri Devender Rao                             std::string keyPairAlgorithm,
233f4682712SMarri Devender Rao                             std::vector<std::string> keyUsage,
234f4682712SMarri Devender Rao                             std::string organization,
235f4682712SMarri Devender Rao                             std::string organizationalUnit, std::string state,
236f4682712SMarri Devender Rao                             std::string surname, std::string unstructuredName)
237f4682712SMarri Devender Rao     {
238f4682712SMarri Devender Rao         return (manager->generateCSR(
239f4682712SMarri Devender Rao             alternativeNames, challengePassword, city, commonName,
240f4682712SMarri Devender Rao             contactPerson, country, email, givenName, initials, keyBitLength,
241f4682712SMarri Devender Rao             keyCurveId, keyPairAlgorithm, keyUsage, organization,
242f4682712SMarri Devender Rao             organizationalUnit, state, surname, unstructuredName));
243f4682712SMarri Devender Rao     }
csr()244e129be3bSPatrick Williams     std::string csr()
245e129be3bSPatrick Williams     {
246e129be3bSPatrick Williams         return (csr_->csr());
247e129be3bSPatrick Williams     }
248947258dcSMarri Devender Rao     phosphor::certs::Manager* manager;
249e129be3bSPatrick Williams     phosphor::certs::CSR* csr_;
250947258dcSMarri Devender Rao };
251947258dcSMarri Devender Rao 
2526ec13c8fSNan Zhou class ManagerInTest : public phosphor::certs::Manager
2536ec13c8fSNan Zhou {
2546ec13c8fSNan Zhou   public:
2556ec13c8fSNan Zhou     static constexpr std::string_view unitToRestartInTest =
2566ec13c8fSNan Zhou         "xyz.openbmc_project.awesome-service";
ManagerInTest(sdbusplus::bus_t & bus,sdeventplus::Event & event,const char * path,CertificateType type,const std::string & unit,const std::string & installPath)257b3dbfb37SPatrick Williams     ManagerInTest(sdbusplus::bus_t& bus, sdeventplus::Event& event,
2586ec13c8fSNan Zhou                   const char* path, CertificateType type,
2596ec13c8fSNan Zhou                   const std::string& unit, const std::string& installPath) :
2606ec13c8fSNan Zhou         Manager(bus, event, path, type, unit, installPath)
261223e4604SPatrick Williams     {}
2626ec13c8fSNan Zhou 
2636ec13c8fSNan Zhou     MOCK_METHOD(void, reloadOrReset, (const std::string&), (override));
2646ec13c8fSNan Zhou };
2656ec13c8fSNan Zhou 
266947258dcSMarri Devender Rao /** @brief Check if server install routine is invoked for server setup
267947258dcSMarri Devender Rao  */
TEST_F(TestCertificates,InvokeServerInstall)2688841dbd6SMarri Devender Rao TEST_F(TestCertificates, InvokeServerInstall)
269947258dcSMarri Devender Rao {
270947258dcSMarri Devender Rao     std::string endpoint("https");
271e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
2728841dbd6SMarri Devender Rao     std::string installPath(certDir + "/" + certificateFile);
2738841dbd6SMarri Devender Rao     std::string verifyPath(installPath);
2746ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
275cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
276cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
277ffad1ef1SMarri Devender Rao     auto event = sdeventplus::Event::get_default();
278ffad1ef1SMarri Devender Rao     // Attach the bus to sd_event to service user requests
279ffad1ef1SMarri Devender Rao     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
2806ec13c8fSNan Zhou     ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
2816ec13c8fSNan Zhou                           installPath);
2826ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
2836ec13c8fSNan Zhou         .WillOnce(Return());
284ffad1ef1SMarri Devender Rao     MainApp mainApp(&manager);
285ffad1ef1SMarri Devender Rao     mainApp.install(certificateFile);
286947258dcSMarri Devender Rao     EXPECT_TRUE(fs::exists(verifyPath));
287947258dcSMarri Devender Rao }
288947258dcSMarri Devender Rao 
289947258dcSMarri Devender Rao /** @brief Check if client install routine is invoked for client setup
290947258dcSMarri Devender Rao  */
TEST_F(TestCertificates,InvokeClientInstall)2918841dbd6SMarri Devender Rao TEST_F(TestCertificates, InvokeClientInstall)
292947258dcSMarri Devender Rao {
293947258dcSMarri Devender Rao     std::string endpoint("ldap");
294e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
2958841dbd6SMarri Devender Rao     std::string installPath(certDir + "/" + certificateFile);
2968841dbd6SMarri Devender Rao     std::string verifyPath(installPath);
2976ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
298cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
299cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
300ffad1ef1SMarri Devender Rao     auto event = sdeventplus::Event::get_default();
301ffad1ef1SMarri Devender Rao     // Attach the bus to sd_event to service user requests
302ffad1ef1SMarri Devender Rao     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
3036ec13c8fSNan Zhou     ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
3046ec13c8fSNan Zhou                           installPath);
3056ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
3066ec13c8fSNan Zhou         .WillOnce(Return());
307ffad1ef1SMarri Devender Rao     MainApp mainApp(&manager);
308ffad1ef1SMarri Devender Rao     mainApp.install(certificateFile);
309b50789ceSJayanth Othayoth     EXPECT_TRUE(fs::exists(verifyPath));
310b50789ceSJayanth Othayoth }
311b50789ceSJayanth Othayoth 
312db029c95SKowalski, Kamil /** @brief Check if storage install routine is invoked for storage setup
313b50789ceSJayanth Othayoth  */
TEST_F(TestCertificates,InvokeAuthorityInstall)3148841dbd6SMarri Devender Rao TEST_F(TestCertificates, InvokeAuthorityInstall)
315b50789ceSJayanth Othayoth {
3162e8fa88eSMichal Orzel     std::string endpoint("truststore");
317e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
318db029c95SKowalski, Kamil     std::string verifyDir(certDir);
3196ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
320cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
321cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
322ffad1ef1SMarri Devender Rao     auto event = sdeventplus::Event::get_default();
323ffad1ef1SMarri Devender Rao     // Attach the bus to sd_event to service user requests
324ffad1ef1SMarri Devender Rao     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
3256ec13c8fSNan Zhou     ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
3266ec13c8fSNan Zhou                           verifyDir);
3276ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
3286ec13c8fSNan Zhou         .WillOnce(Return());
329ffad1ef1SMarri Devender Rao     MainApp mainApp(&manager);
330cf811c43SNan Zhou     // install the default certificate that's valid from today to 100 years
331cf811c43SNan Zhou     // later
332ffad1ef1SMarri Devender Rao     mainApp.install(certificateFile);
333db029c95SKowalski, Kamil 
334db029c95SKowalski, Kamil     std::vector<std::unique_ptr<Certificate>>& certs =
335db029c95SKowalski, Kamil         manager.getCertificates();
336db029c95SKowalski, Kamil 
337cf811c43SNan Zhou     ASSERT_EQ(certs.size(), 1);
338cf811c43SNan Zhou     // check some attributes as well
339cf811c43SNan Zhou     EXPECT_EQ(certs.front()->validNotAfter() - certs.front()->validNotBefore(),
340cf811c43SNan Zhou               365000ULL * 24 * 3600);
341cf811c43SNan Zhou     EXPECT_EQ(certs.front()->subject(), "O=openbmc-project.xyz,CN=localhost");
342cf811c43SNan Zhou     EXPECT_EQ(certs.front()->issuer(), "O=openbmc-project.xyz,CN=localhost");
343cf811c43SNan Zhou 
344223e4604SPatrick Williams     std::string verifyPath = verifyDir + "/" +
345223e4604SPatrick Williams                              getCertSubjectNameHash(certificateFile) + ".0";
346cf811c43SNan Zhou 
347cf811c43SNan Zhou     // Check that certificate has been created at installation directory
348cf811c43SNan Zhou     EXPECT_FALSE(fs::is_empty(verifyDir));
349cf811c43SNan Zhou     EXPECT_TRUE(fs::exists(verifyPath));
350cf811c43SNan Zhou 
351cf811c43SNan Zhou     // Check that installed cert is identical to input one
352cf811c43SNan Zhou     EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
353cf811c43SNan Zhou }
354cf811c43SNan Zhou 
355cf811c43SNan Zhou /** @brief Check if storage install routine is invoked for storage setup
356cf811c43SNan Zhou  */
TEST_F(TestCertificates,InvokeAuthorityInstallNeverExpiredRootCert)357cf811c43SNan Zhou TEST_F(TestCertificates, InvokeAuthorityInstallNeverExpiredRootCert)
358cf811c43SNan Zhou {
3592e8fa88eSMichal Orzel     std::string endpoint("truststore");
360e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
361cf811c43SNan Zhou     std::string verifyDir(certDir);
3626ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
363cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
364cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
365cf811c43SNan Zhou     auto event = sdeventplus::Event::get_default();
366cf811c43SNan Zhou     // Attach the bus to sd_event to service user requests
367cf811c43SNan Zhou     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
3686ec13c8fSNan Zhou     ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
3696ec13c8fSNan Zhou                           certDir);
3706ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
3716ec13c8fSNan Zhou         .WillOnce(Return());
372cf811c43SNan Zhou     MainApp mainApp(&manager);
373cf811c43SNan Zhou 
374cf811c43SNan Zhou     // install the certificate that's valid from the Unix Epoch to Dec 31, 9999
375cf811c43SNan Zhou     createNeverExpiredRootCertificate();
376cf811c43SNan Zhou     mainApp.install(certificateFile);
377cf811c43SNan Zhou 
378cf811c43SNan Zhou     std::vector<std::unique_ptr<Certificate>>& certs =
379cf811c43SNan Zhou         manager.getCertificates();
380cf811c43SNan Zhou 
381cf811c43SNan Zhou     EXPECT_EQ(certs.front()->validNotBefore(), 0);
382cf811c43SNan Zhou     EXPECT_EQ(certs.front()->validNotAfter(), 253402300799ULL);
383db029c95SKowalski, Kamil 
384223e4604SPatrick Williams     std::string verifyPath = verifyDir + "/" +
385223e4604SPatrick Williams                              getCertSubjectNameHash(certificateFile) + ".0";
386db029c95SKowalski, Kamil 
387db029c95SKowalski, Kamil     // Check that certificate has been created at installation directory
388db029c95SKowalski, Kamil     EXPECT_FALSE(fs::is_empty(verifyDir));
389db029c95SKowalski, Kamil     EXPECT_TRUE(fs::exists(verifyPath));
390db029c95SKowalski, Kamil 
391db029c95SKowalski, Kamil     // Check that installed cert is identical to input one
392db029c95SKowalski, Kamil     EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
393db029c95SKowalski, Kamil }
394db029c95SKowalski, Kamil 
3952f3563ccSZbigniew Lukwinski /** @brief Check if in authority mode user can't install the same
3962f3563ccSZbigniew Lukwinski  * certificate twice.
397db029c95SKowalski, Kamil  */
TEST_F(TestCertificates,InvokeInstallSameCertTwice)3982f3563ccSZbigniew Lukwinski TEST_F(TestCertificates, InvokeInstallSameCertTwice)
399db029c95SKowalski, Kamil {
4002e8fa88eSMichal Orzel     std::string endpoint("truststore");
401e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
402db029c95SKowalski, Kamil     std::string verifyDir(certDir);
4036ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
404cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
405cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
406db029c95SKowalski, Kamil     auto event = sdeventplus::Event::get_default();
407db029c95SKowalski, Kamil     // Attach the bus to sd_event to service user requests
408db029c95SKowalski, Kamil     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
4096ec13c8fSNan Zhou     ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
410db029c95SKowalski, Kamil                           std::move(certDir));
4116ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
4126ec13c8fSNan Zhou         .WillOnce(Return());
413db029c95SKowalski, Kamil     MainApp mainApp(&manager);
414db029c95SKowalski, Kamil     mainApp.install(certificateFile);
415db029c95SKowalski, Kamil 
416db029c95SKowalski, Kamil     std::vector<std::unique_ptr<Certificate>>& certs =
417db029c95SKowalski, Kamil         manager.getCertificates();
418db029c95SKowalski, Kamil 
419db029c95SKowalski, Kamil     EXPECT_FALSE(certs.empty());
420db029c95SKowalski, Kamil 
421db029c95SKowalski, Kamil     // Check that certificate has been created at installation directory
422223e4604SPatrick Williams     std::string verifyPath = verifyDir + "/" +
423223e4604SPatrick Williams                              getCertSubjectNameHash(certificateFile) + ".0";
424db029c95SKowalski, Kamil     EXPECT_FALSE(fs::is_empty(verifyDir));
425db029c95SKowalski, Kamil     EXPECT_TRUE(fs::exists(verifyPath));
426db029c95SKowalski, Kamil 
427db029c95SKowalski, Kamil     // Check that installed cert is identical to input one
428db029c95SKowalski, Kamil     EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
429db029c95SKowalski, Kamil 
4302f3563ccSZbigniew Lukwinski     using NotAllowed =
4312f3563ccSZbigniew Lukwinski         sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
432db029c95SKowalski, Kamil     EXPECT_THROW(
433db029c95SKowalski, Kamil         {
434db029c95SKowalski, Kamil             try
435db029c95SKowalski, Kamil             {
4362f3563ccSZbigniew Lukwinski                 // Try to install the same certificate second time
437db029c95SKowalski, Kamil                 mainApp.install(certificateFile);
438db029c95SKowalski, Kamil             }
439db029c95SKowalski, Kamil             catch (const NotAllowed& e)
440db029c95SKowalski, Kamil             {
441db029c95SKowalski, Kamil                 throw;
442db029c95SKowalski, Kamil             }
443db029c95SKowalski, Kamil         },
444db029c95SKowalski, Kamil         NotAllowed);
445db029c95SKowalski, Kamil 
446db029c95SKowalski, Kamil     // Check that the original certificate has been not removed
447db029c95SKowalski, Kamil     EXPECT_FALSE(fs::is_empty(verifyDir));
448947258dcSMarri Devender Rao     EXPECT_TRUE(fs::exists(verifyPath));
449947258dcSMarri Devender Rao }
450947258dcSMarri Devender Rao 
45173d1fbf3SZbigniew Lukwinski /** @brief Check if in authority mode user can install a certificate with
4522f3563ccSZbigniew Lukwinski  * certain subject hash twice.
4532f3563ccSZbigniew Lukwinski  */
TEST_F(TestCertificates,InvokeInstallSameSubjectTwice)4542f3563ccSZbigniew Lukwinski TEST_F(TestCertificates, InvokeInstallSameSubjectTwice)
4552f3563ccSZbigniew Lukwinski {
4562e8fa88eSMichal Orzel     std::string endpoint("truststore");
457e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
4582f3563ccSZbigniew Lukwinski     std::string verifyDir(certDir);
4596ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
460cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
461cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
4622f3563ccSZbigniew Lukwinski     auto event = sdeventplus::Event::get_default();
4632f3563ccSZbigniew Lukwinski     // Attach the bus to sd_event to service user requests
4642f3563ccSZbigniew Lukwinski     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
4656ec13c8fSNan Zhou     ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
4666ec13c8fSNan Zhou                           certDir);
4676ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
4686ec13c8fSNan Zhou         .WillOnce(Return())
4696ec13c8fSNan Zhou         .WillOnce(Return());
4702f3563ccSZbigniew Lukwinski     MainApp mainApp(&manager);
4712f3563ccSZbigniew Lukwinski     mainApp.install(certificateFile);
4722f3563ccSZbigniew Lukwinski 
4732f3563ccSZbigniew Lukwinski     std::vector<std::unique_ptr<Certificate>>& certs =
4742f3563ccSZbigniew Lukwinski         manager.getCertificates();
4752f3563ccSZbigniew Lukwinski 
4762f3563ccSZbigniew Lukwinski     EXPECT_FALSE(certs.empty());
4772f3563ccSZbigniew Lukwinski 
4782f3563ccSZbigniew Lukwinski     // Check that certificate has been created at installation directory
479223e4604SPatrick Williams     std::string verifyPath0 = verifyDir + "/" +
480223e4604SPatrick Williams                               getCertSubjectNameHash(certificateFile) + ".0";
4812f3563ccSZbigniew Lukwinski     EXPECT_FALSE(fs::is_empty(verifyDir));
4822f3563ccSZbigniew Lukwinski     EXPECT_TRUE(fs::exists(verifyPath0));
4832f3563ccSZbigniew Lukwinski 
4842f3563ccSZbigniew Lukwinski     // Check that installed cert is identical to input one
4852f3563ccSZbigniew Lukwinski     EXPECT_TRUE(compareFiles(certificateFile, verifyPath0));
4862f3563ccSZbigniew Lukwinski 
4872f3563ccSZbigniew Lukwinski     // Prepare second certificate with the same subject
4882f3563ccSZbigniew Lukwinski     createNewCertificate();
4892f3563ccSZbigniew Lukwinski 
4902f3563ccSZbigniew Lukwinski     // Install second certificate
4912f3563ccSZbigniew Lukwinski     mainApp.install(certificateFile);
4922f3563ccSZbigniew Lukwinski 
4932f3563ccSZbigniew Lukwinski     // Expect there are exactly two certificates in the collection
49473d1fbf3SZbigniew Lukwinski     EXPECT_EQ(certs.size(), 2);
49573d1fbf3SZbigniew Lukwinski 
49673d1fbf3SZbigniew Lukwinski     // Check that certificate has been created at installation directory
497223e4604SPatrick Williams     std::string verifyPath1 = verifyDir + "/" +
498223e4604SPatrick Williams                               getCertSubjectNameHash(certificateFile) + ".1";
49973d1fbf3SZbigniew Lukwinski     EXPECT_TRUE(fs::exists(verifyPath1));
50073d1fbf3SZbigniew Lukwinski 
50173d1fbf3SZbigniew Lukwinski     // Check that installed cert is identical to input one
50273d1fbf3SZbigniew Lukwinski     EXPECT_TRUE(compareFiles(certificateFile, verifyPath1));
5032f3563ccSZbigniew Lukwinski 
5042f3563ccSZbigniew Lukwinski     // Check that the original/first certificate has been not removed
5052f3563ccSZbigniew Lukwinski     EXPECT_FALSE(fs::is_empty(verifyDir));
5062f3563ccSZbigniew Lukwinski     EXPECT_TRUE(fs::exists(verifyPath0));
5072f3563ccSZbigniew Lukwinski }
5082f3563ccSZbigniew Lukwinski 
5092f3563ccSZbigniew Lukwinski /** @brief Check if in authority mode user can't install more than
510718eef37SNan Zhou  * maxNumAuthorityCertificates certificates.
5112f3563ccSZbigniew Lukwinski  */
TEST_F(TestCertificates,InvokeInstallAuthCertLimit)5122f3563ccSZbigniew Lukwinski TEST_F(TestCertificates, InvokeInstallAuthCertLimit)
5132f3563ccSZbigniew Lukwinski {
5142e8fa88eSMichal Orzel     std::string endpoint("truststore");
515e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
5162f3563ccSZbigniew Lukwinski     std::string verifyDir(certDir);
5176ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
518cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
519cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
5202f3563ccSZbigniew Lukwinski     auto event = sdeventplus::Event::get_default();
5212f3563ccSZbigniew Lukwinski     // Attach the bus to sd_event to service user requests
5222f3563ccSZbigniew Lukwinski     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
5236ec13c8fSNan Zhou     ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
5246ec13c8fSNan Zhou                           certDir);
5256ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
5266ec13c8fSNan Zhou         .WillRepeatedly(Return());
5272f3563ccSZbigniew Lukwinski     MainApp mainApp(&manager);
5282f3563ccSZbigniew Lukwinski 
5292f3563ccSZbigniew Lukwinski     std::vector<std::unique_ptr<Certificate>>& certs =
5302f3563ccSZbigniew Lukwinski         manager.getCertificates();
5312f3563ccSZbigniew Lukwinski 
5322f3563ccSZbigniew Lukwinski     std::vector<std::string> verifyPaths;
5332f3563ccSZbigniew Lukwinski 
5342f3563ccSZbigniew Lukwinski     // Prepare maximum number of ceritificates
535718eef37SNan Zhou     for (std::size_t i = 0; i < maxNumAuthorityCertificates; ++i)
5362f3563ccSZbigniew Lukwinski     {
5372f3563ccSZbigniew Lukwinski         // Prepare new certificatate
5382f3563ccSZbigniew Lukwinski         createNewCertificate(true);
5392f3563ccSZbigniew Lukwinski 
5402f3563ccSZbigniew Lukwinski         // Install ceritificate
5412f3563ccSZbigniew Lukwinski         mainApp.install(certificateFile);
5422f3563ccSZbigniew Lukwinski 
5432f3563ccSZbigniew Lukwinski         // Check number of certificates in the collection
5442f3563ccSZbigniew Lukwinski         EXPECT_EQ(certs.size(), i + 1);
5452f3563ccSZbigniew Lukwinski 
5462f3563ccSZbigniew Lukwinski         // Check that certificate has been created at installation directory
547223e4604SPatrick Williams         std::string verifyPath = verifyDir + "/" +
548223e4604SPatrick Williams                                  getCertSubjectNameHash(certificateFile) + ".0";
5492f3563ccSZbigniew Lukwinski         EXPECT_FALSE(fs::is_empty(verifyDir));
5502f3563ccSZbigniew Lukwinski         EXPECT_TRUE(fs::exists(verifyPath));
5512f3563ccSZbigniew Lukwinski 
5522f3563ccSZbigniew Lukwinski         // Check that installed cert is identical to input one
5532f3563ccSZbigniew Lukwinski         EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
5542f3563ccSZbigniew Lukwinski 
5552f3563ccSZbigniew Lukwinski         // Save current certificate file for later check
5562f3563ccSZbigniew Lukwinski         verifyPaths.push_back(verifyPath);
5572f3563ccSZbigniew Lukwinski     }
5582f3563ccSZbigniew Lukwinski 
5592f3563ccSZbigniew Lukwinski     // Prepare new certificatate
5602f3563ccSZbigniew Lukwinski     createNewCertificate(true);
5612f3563ccSZbigniew Lukwinski 
5622f3563ccSZbigniew Lukwinski     using NotAllowed =
5632f3563ccSZbigniew Lukwinski         sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
5642f3563ccSZbigniew Lukwinski     EXPECT_THROW(
5652f3563ccSZbigniew Lukwinski         {
5662f3563ccSZbigniew Lukwinski             try
5672f3563ccSZbigniew Lukwinski             {
5682f3563ccSZbigniew Lukwinski                 // Try to install one more certificate
5692f3563ccSZbigniew Lukwinski                 mainApp.install(certificateFile);
5702f3563ccSZbigniew Lukwinski             }
5712f3563ccSZbigniew Lukwinski             catch (const NotAllowed& e)
5722f3563ccSZbigniew Lukwinski             {
5732f3563ccSZbigniew Lukwinski                 throw;
5742f3563ccSZbigniew Lukwinski             }
5752f3563ccSZbigniew Lukwinski         },
5762f3563ccSZbigniew Lukwinski         NotAllowed);
5772f3563ccSZbigniew Lukwinski 
5782f3563ccSZbigniew Lukwinski     // Check that the original certificate has been not removed
5792f3563ccSZbigniew Lukwinski     EXPECT_FALSE(fs::is_empty(verifyDir));
580718eef37SNan Zhou     for (size_t i = 0; i < maxNumAuthorityCertificates; ++i)
5812f3563ccSZbigniew Lukwinski     {
5822f3563ccSZbigniew Lukwinski         EXPECT_TRUE(fs::exists(verifyPaths[i]));
5832f3563ccSZbigniew Lukwinski     }
5842f3563ccSZbigniew Lukwinski }
5852f3563ccSZbigniew Lukwinski 
586947258dcSMarri Devender Rao /** @brief Compare the installed certificate with the copied certificate
587947258dcSMarri Devender Rao  */
TEST_F(TestCertificates,CompareInstalledCertificate)5888841dbd6SMarri Devender Rao TEST_F(TestCertificates, CompareInstalledCertificate)
589947258dcSMarri Devender Rao {
590947258dcSMarri Devender Rao     std::string endpoint("ldap");
591e3d47cd4SNan Zhou     CertificateType type = CertificateType::client;
5928841dbd6SMarri Devender Rao     std::string installPath(certDir + "/" + certificateFile);
5938841dbd6SMarri Devender Rao     std::string verifyPath(installPath);
5946ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
595cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
596cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
597ffad1ef1SMarri Devender Rao     auto event = sdeventplus::Event::get_default();
598ffad1ef1SMarri Devender Rao     // Attach the bus to sd_event to service user requests
599ffad1ef1SMarri Devender Rao     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
6006ec13c8fSNan Zhou     ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
6016ec13c8fSNan Zhou                           installPath);
6026ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
6036ec13c8fSNan Zhou         .WillOnce(Return());
604ffad1ef1SMarri Devender Rao     MainApp mainApp(&manager);
605ffad1ef1SMarri Devender Rao     mainApp.install(certificateFile);
606947258dcSMarri Devender Rao     EXPECT_TRUE(fs::exists(verifyPath));
607947258dcSMarri Devender Rao     EXPECT_TRUE(compareFiles(verifyPath, certificateFile));
608947258dcSMarri Devender Rao }
609e6597c5bSMarri Devender Rao 
610e6597c5bSMarri Devender Rao /** @brief Check if install fails if certificate file is not found
611e6597c5bSMarri Devender Rao  */
TEST_F(TestCertificates,TestNoCertificateFile)6128841dbd6SMarri Devender Rao TEST_F(TestCertificates, TestNoCertificateFile)
613e6597c5bSMarri Devender Rao {
614e6597c5bSMarri Devender Rao     std::string endpoint("ldap");
615e3d47cd4SNan Zhou     CertificateType type = CertificateType::client;
6168841dbd6SMarri Devender Rao     std::string installPath(certDir + "/" + certificateFile);
6178841dbd6SMarri Devender Rao     std::string verifyPath(installPath);
6186ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
619cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
620cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
6218841dbd6SMarri Devender Rao     std::string uploadFile = "nofile.pem";
622e6597c5bSMarri Devender Rao     EXPECT_THROW(
623e6597c5bSMarri Devender Rao         {
624e6597c5bSMarri Devender Rao             try
625e6597c5bSMarri Devender Rao             {
626ffad1ef1SMarri Devender Rao                 auto event = sdeventplus::Event::get_default();
627ffad1ef1SMarri Devender Rao                 // Attach the bus to sd_event to service user requests
628ffad1ef1SMarri Devender Rao                 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
6296ec13c8fSNan Zhou                 ManagerInTest manager(bus, event, objPath.c_str(), type,
6306ec13c8fSNan Zhou                                       verifyUnit, installPath);
631ffad1ef1SMarri Devender Rao                 MainApp mainApp(&manager);
632ffad1ef1SMarri Devender Rao                 mainApp.install(uploadFile);
633e6597c5bSMarri Devender Rao             }
634e6597c5bSMarri Devender Rao             catch (const InternalFailure& e)
635e6597c5bSMarri Devender Rao             {
636e6597c5bSMarri Devender Rao                 throw;
637e6597c5bSMarri Devender Rao             }
638e6597c5bSMarri Devender Rao         },
639e6597c5bSMarri Devender Rao         InternalFailure);
640e6597c5bSMarri Devender Rao     EXPECT_FALSE(fs::exists(verifyPath));
641e6597c5bSMarri Devender Rao }
642e6597c5bSMarri Devender Rao 
643ffad1ef1SMarri Devender Rao /** @brief Test replacing existing certificate
644ffad1ef1SMarri Devender Rao  */
TEST_F(TestCertificates,TestReplaceCertificate)645ffad1ef1SMarri Devender Rao TEST_F(TestCertificates, TestReplaceCertificate)
646ffad1ef1SMarri Devender Rao {
647ffad1ef1SMarri Devender Rao     std::string endpoint("ldap");
648e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
649ffad1ef1SMarri Devender Rao     std::string installPath(certDir + "/" + certificateFile);
650ffad1ef1SMarri Devender Rao     std::string verifyPath(installPath);
6516ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
652cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
653cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
654ffad1ef1SMarri Devender Rao     auto event = sdeventplus::Event::get_default();
655ffad1ef1SMarri Devender Rao     // Attach the bus to sd_event to service user requests
656ffad1ef1SMarri Devender Rao     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
6576ec13c8fSNan Zhou     ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
658ffad1ef1SMarri Devender Rao                           std::move(installPath));
6596ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
6606ec13c8fSNan Zhou         .WillOnce(Return())
6616ec13c8fSNan Zhou         .WillOnce(Return());
662ffad1ef1SMarri Devender Rao     MainApp mainApp(&manager);
663ffad1ef1SMarri Devender Rao     mainApp.install(certificateFile);
664ffad1ef1SMarri Devender Rao     EXPECT_TRUE(fs::exists(verifyPath));
665db029c95SKowalski, Kamil     std::vector<std::unique_ptr<Certificate>>& certs =
666db029c95SKowalski, Kamil         manager.getCertificates();
667db029c95SKowalski, Kamil     EXPECT_FALSE(certs.empty());
668db029c95SKowalski, Kamil     EXPECT_NE(certs[0], nullptr);
669db029c95SKowalski, Kamil     certs[0]->replace(certificateFile);
670ffad1ef1SMarri Devender Rao     EXPECT_TRUE(fs::exists(verifyPath));
671db029c95SKowalski, Kamil }
672db029c95SKowalski, Kamil 
673db029c95SKowalski, Kamil /** @brief Test replacing existing certificate
674db029c95SKowalski, Kamil  */
TEST_F(TestCertificates,TestAuthorityReplaceCertificate)675db029c95SKowalski, Kamil TEST_F(TestCertificates, TestAuthorityReplaceCertificate)
676db029c95SKowalski, Kamil {
6772e8fa88eSMichal Orzel     std::string endpoint("truststore");
678e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
679db029c95SKowalski, Kamil     std::string verifyDir(certDir);
6806ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
681cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
682cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
683db029c95SKowalski, Kamil     auto event = sdeventplus::Event::get_default();
684db029c95SKowalski, Kamil     // Attach the bus to sd_event to service user requests
685db029c95SKowalski, Kamil     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
6866ec13c8fSNan Zhou     ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
6876ec13c8fSNan Zhou                           certDir);
688e3d47cd4SNan Zhou     constexpr const unsigned int replaceIterations = 10;
6896ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
690e3d47cd4SNan Zhou         .Times(replaceIterations + 1)
6916ec13c8fSNan Zhou         .WillRepeatedly(Return());
692db029c95SKowalski, Kamil     MainApp mainApp(&manager);
693db029c95SKowalski, Kamil     mainApp.install(certificateFile);
694db029c95SKowalski, Kamil 
695db029c95SKowalski, Kamil     std::vector<std::unique_ptr<Certificate>>& certs =
696db029c95SKowalski, Kamil         manager.getCertificates();
697db029c95SKowalski, Kamil 
698e3d47cd4SNan Zhou     for (unsigned int i = 0; i < replaceIterations; i++)
699db029c95SKowalski, Kamil     {
700db029c95SKowalski, Kamil         // Certificate successfully installed
701db029c95SKowalski, Kamil         EXPECT_FALSE(certs.empty());
702db029c95SKowalski, Kamil 
703223e4604SPatrick Williams         std::string verifyPath = verifyDir + "/" +
704223e4604SPatrick Williams                                  getCertSubjectNameHash(certificateFile) + ".0";
705db029c95SKowalski, Kamil 
706db029c95SKowalski, Kamil         // Check that certificate has been created at installation directory
707db029c95SKowalski, Kamil         EXPECT_FALSE(fs::is_empty(verifyDir));
708ffad1ef1SMarri Devender Rao         EXPECT_TRUE(fs::exists(verifyPath));
709db029c95SKowalski, Kamil 
710db029c95SKowalski, Kamil         // Check that installed cert is identical to input one
711db029c95SKowalski, Kamil         EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
712db029c95SKowalski, Kamil 
713db029c95SKowalski, Kamil         // Create new certificate
714db029c95SKowalski, Kamil         createNewCertificate(true);
715db029c95SKowalski, Kamil 
716db029c95SKowalski, Kamil         certs[0]->replace(certificateFile);
717db029c95SKowalski, Kamil 
718db029c95SKowalski, Kamil         // Verify that old certificate has been removed
719db029c95SKowalski, Kamil         EXPECT_FALSE(fs::exists(verifyPath));
720db029c95SKowalski, Kamil     }
721ffad1ef1SMarri Devender Rao }
722ffad1ef1SMarri Devender Rao 
723a3bb38fbSZbigniew Kurzynski /** @brief Test verifiing if delete function works.
724a3bb38fbSZbigniew Kurzynski  */
TEST_F(TestCertificates,TestStorageDeleteCertificate)725a3bb38fbSZbigniew Kurzynski TEST_F(TestCertificates, TestStorageDeleteCertificate)
726a3bb38fbSZbigniew Kurzynski {
7272e8fa88eSMichal Orzel     std::string endpoint("truststore");
728e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
729a3bb38fbSZbigniew Kurzynski     std::string verifyDir(certDir);
7306ec13c8fSNan Zhou     std::string verifyUnit((ManagerInTest::unitToRestartInTest));
731cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
732cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
733a3bb38fbSZbigniew Kurzynski     auto event = sdeventplus::Event::get_default();
734a3bb38fbSZbigniew Kurzynski     // Attach the bus to sd_event to service user requests
735a3bb38fbSZbigniew Kurzynski     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
7366ec13c8fSNan Zhou     ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
7376ec13c8fSNan Zhou                           certDir);
7386ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
7396ec13c8fSNan Zhou         .WillRepeatedly(Return());
740a3bb38fbSZbigniew Kurzynski     MainApp mainApp(&manager);
741a3bb38fbSZbigniew Kurzynski 
742a3bb38fbSZbigniew Kurzynski     // Check if certificate placeholder dir is empty
743a3bb38fbSZbigniew Kurzynski     EXPECT_TRUE(fs::is_empty(verifyDir));
744a3bb38fbSZbigniew Kurzynski     mainApp.install(certificateFile);
745a3bb38fbSZbigniew Kurzynski 
746a3bb38fbSZbigniew Kurzynski     // Create new certificate
747a3bb38fbSZbigniew Kurzynski     createNewCertificate(true);
748a3bb38fbSZbigniew Kurzynski     mainApp.install(certificateFile);
749a3bb38fbSZbigniew Kurzynski 
750a3bb38fbSZbigniew Kurzynski     createNewCertificate(true);
751a3bb38fbSZbigniew Kurzynski     mainApp.install(certificateFile);
752a3bb38fbSZbigniew Kurzynski 
753a3bb38fbSZbigniew Kurzynski     std::vector<std::unique_ptr<Certificate>>& certs =
754a3bb38fbSZbigniew Kurzynski         manager.getCertificates();
755a3bb38fbSZbigniew Kurzynski 
756a3bb38fbSZbigniew Kurzynski     // All 3 certificates successfully installed and added to manager
757a3bb38fbSZbigniew Kurzynski     EXPECT_EQ(certs.size(), 3);
758a3bb38fbSZbigniew Kurzynski 
759a3bb38fbSZbigniew Kurzynski     // Check if certificate placeholder is not empty, there should be 3
760a3bb38fbSZbigniew Kurzynski     // certificates
761a3bb38fbSZbigniew Kurzynski     EXPECT_FALSE(fs::is_empty(verifyDir));
762a3bb38fbSZbigniew Kurzynski 
763a3bb38fbSZbigniew Kurzynski     certs[0]->delete_();
764a3bb38fbSZbigniew Kurzynski     EXPECT_EQ(certs.size(), 2);
765a3bb38fbSZbigniew Kurzynski 
766a3bb38fbSZbigniew Kurzynski     certs[0]->delete_();
767a3bb38fbSZbigniew Kurzynski     EXPECT_EQ(certs.size(), 1);
768a3bb38fbSZbigniew Kurzynski 
769a3bb38fbSZbigniew Kurzynski     certs[0]->delete_();
770a3bb38fbSZbigniew Kurzynski     EXPECT_EQ(certs.size(), 0);
771a3bb38fbSZbigniew Kurzynski 
772a3bb38fbSZbigniew Kurzynski     // Check if certificate placeholder is empty.
773a3bb38fbSZbigniew Kurzynski     EXPECT_TRUE(fs::is_empty(verifyDir));
774a3bb38fbSZbigniew Kurzynski }
775a3bb38fbSZbigniew Kurzynski 
776e6597c5bSMarri Devender Rao /** @brief Check if install fails if certificate file is empty
777e6597c5bSMarri Devender Rao  */
TEST_F(TestCertificates,TestEmptyCertificateFile)7788841dbd6SMarri Devender Rao TEST_F(TestCertificates, TestEmptyCertificateFile)
779e6597c5bSMarri Devender Rao {
780e6597c5bSMarri Devender Rao     std::string endpoint("ldap");
781e3d47cd4SNan Zhou     CertificateType type = CertificateType::client;
7828841dbd6SMarri Devender Rao     std::string installPath(certDir + "/" + certificateFile);
7838841dbd6SMarri Devender Rao     std::string verifyPath(installPath);
7846ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
785cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
786cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
787ddf64866SMarri Devender Rao     std::string emptyFile("emptycert.pem");
788e6597c5bSMarri Devender Rao     std::ofstream ofs;
789e6597c5bSMarri Devender Rao     ofs.open(emptyFile, std::ofstream::out);
790e6597c5bSMarri Devender Rao     ofs.close();
791e6597c5bSMarri Devender Rao     EXPECT_THROW(
792e6597c5bSMarri Devender Rao         {
793e6597c5bSMarri Devender Rao             try
794e6597c5bSMarri Devender Rao             {
795ffad1ef1SMarri Devender Rao                 auto event = sdeventplus::Event::get_default();
796ffad1ef1SMarri Devender Rao                 // Attach the bus to sd_event to service user requests
797ffad1ef1SMarri Devender Rao                 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
7986ec13c8fSNan Zhou                 ManagerInTest manager(bus, event, objPath.c_str(), type,
7996ec13c8fSNan Zhou                                       verifyUnit, installPath);
800ffad1ef1SMarri Devender Rao                 MainApp mainApp(&manager);
801ffad1ef1SMarri Devender Rao                 mainApp.install(emptyFile);
802e6597c5bSMarri Devender Rao             }
803e6597c5bSMarri Devender Rao             catch (const InvalidCertificate& e)
804e6597c5bSMarri Devender Rao             {
805e6597c5bSMarri Devender Rao                 throw;
806e6597c5bSMarri Devender Rao             }
807e6597c5bSMarri Devender Rao         },
808e6597c5bSMarri Devender Rao         InvalidCertificate);
809e6597c5bSMarri Devender Rao     EXPECT_FALSE(fs::exists(verifyPath));
810e6597c5bSMarri Devender Rao     fs::remove(emptyFile);
811e6597c5bSMarri Devender Rao }
812e6597c5bSMarri Devender Rao 
813ddf64866SMarri Devender Rao /** @brief Check if install fails if certificate file is corrupted
814e6597c5bSMarri Devender Rao  */
TEST_F(TestCertificates,TestInvalidCertificateFile)8158841dbd6SMarri Devender Rao TEST_F(TestCertificates, TestInvalidCertificateFile)
816e6597c5bSMarri Devender Rao {
817e6597c5bSMarri Devender Rao     std::string endpoint("ldap");
818e3d47cd4SNan Zhou     CertificateType type = CertificateType::client;
819e6597c5bSMarri Devender Rao 
820e6597c5bSMarri Devender Rao     std::ofstream ofs;
821ddf64866SMarri Devender Rao     ofs.open(certificateFile, std::ofstream::out);
822ddf64866SMarri Devender Rao     ofs << "-----BEGIN CERTIFICATE-----";
823ddf64866SMarri Devender Rao     ofs << "ADD_SOME_INVALID_DATA_INTO_FILE";
824ddf64866SMarri Devender Rao     ofs << "-----END CERTIFICATE-----";
825e6597c5bSMarri Devender Rao     ofs.close();
826e6597c5bSMarri Devender Rao 
8278841dbd6SMarri Devender Rao     std::string installPath(certDir + "/" + certificateFile);
8288841dbd6SMarri Devender Rao     std::string verifyPath(installPath);
8296ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
830cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
831cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
832e6597c5bSMarri Devender Rao     EXPECT_THROW(
833e6597c5bSMarri Devender Rao         {
834e6597c5bSMarri Devender Rao             try
835e6597c5bSMarri Devender Rao             {
836ffad1ef1SMarri Devender Rao                 auto event = sdeventplus::Event::get_default();
837ffad1ef1SMarri Devender Rao                 // Attach the bus to sd_event to service user requests
838ffad1ef1SMarri Devender Rao                 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
8396ec13c8fSNan Zhou                 ManagerInTest manager(bus, event, objPath.c_str(), type,
8406ec13c8fSNan Zhou                                       verifyUnit, installPath);
841ffad1ef1SMarri Devender Rao                 MainApp mainApp(&manager);
842ffad1ef1SMarri Devender Rao                 mainApp.install(certificateFile);
843e6597c5bSMarri Devender Rao             }
844e6597c5bSMarri Devender Rao             catch (const InvalidCertificate& e)
845e6597c5bSMarri Devender Rao             {
846e6597c5bSMarri Devender Rao                 throw;
847e6597c5bSMarri Devender Rao             }
848e6597c5bSMarri Devender Rao         },
849e6597c5bSMarri Devender Rao         InvalidCertificate);
850e6597c5bSMarri Devender Rao     EXPECT_FALSE(fs::exists(verifyPath));
851ddf64866SMarri Devender Rao }
852ddf64866SMarri Devender Rao 
853ddf64866SMarri Devender Rao /**
854ddf64866SMarri Devender Rao  * Class to generate private and certificate only file and test verification
855ddf64866SMarri Devender Rao  */
8568841dbd6SMarri Devender Rao class TestInvalidCertificate : public ::testing::Test
857ddf64866SMarri Devender Rao {
858ddf64866SMarri Devender Rao   public:
TestInvalidCertificate()859223e4604SPatrick Williams     TestInvalidCertificate() : bus(sdbusplus::bus::new_default()) {}
SetUp()860ddf64866SMarri Devender Rao     void SetUp() override
861ddf64866SMarri Devender Rao     {
862ddf64866SMarri Devender Rao         char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
863ddf64866SMarri Devender Rao         auto dirPtr = mkdtemp(dirTemplate);
864cfb5802aSNan Zhou         if (dirPtr == nullptr)
865ddf64866SMarri Devender Rao         {
866ddf64866SMarri Devender Rao             throw std::bad_alloc();
867ddf64866SMarri Devender Rao         }
868fe590c4eSZbigniew Lukwinski         certDir = std::string(dirPtr) + "/certs";
869fe590c4eSZbigniew Lukwinski         fs::create_directories(certDir);
870ddf64866SMarri Devender Rao         certificateFile = "cert.pem";
871ddf64866SMarri Devender Rao         keyFile = "key.pem";
872ddf64866SMarri Devender Rao         std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
873ddf64866SMarri Devender Rao         cmd += "-keyout key.pem -out cert.pem -days 3650 ";
874ddf64866SMarri Devender Rao         cmd += "-subj "
875ddf64866SMarri Devender Rao                "/O=openbmc-project.xyz/CN=localhost"
876ddf64866SMarri Devender Rao                " -nodes";
877ddf64866SMarri Devender Rao 
878ddf64866SMarri Devender Rao         auto val = std::system(cmd.c_str());
879ddf64866SMarri Devender Rao         if (val)
880ddf64866SMarri Devender Rao         {
881ddf64866SMarri Devender Rao             std::cout << "command Error: " << val << std::endl;
882ddf64866SMarri Devender Rao         }
883ddf64866SMarri Devender Rao     }
TearDown()884ddf64866SMarri Devender Rao     void TearDown() override
885ddf64866SMarri Devender Rao     {
886ddf64866SMarri Devender Rao         fs::remove_all(certDir);
887ddf64866SMarri Devender Rao         fs::remove(certificateFile);
888ddf64866SMarri Devender Rao         fs::remove(keyFile);
889ddf64866SMarri Devender Rao     }
890ddf64866SMarri Devender Rao 
891ddf64866SMarri Devender Rao   protected:
892b3dbfb37SPatrick Williams     sdbusplus::bus_t bus;
893ddf64866SMarri Devender Rao     std::string certificateFile;
894ddf64866SMarri Devender Rao     std::string keyFile;
895ddf64866SMarri Devender Rao     std::string certDir;
896ddf64866SMarri Devender Rao };
897ddf64866SMarri Devender Rao 
898ddf64866SMarri Devender Rao /** @brief Check install fails if private key is missing in certificate file
899ddf64866SMarri Devender Rao  */
TEST_F(TestInvalidCertificate,TestMissingPrivateKey)9008841dbd6SMarri Devender Rao TEST_F(TestInvalidCertificate, TestMissingPrivateKey)
901ddf64866SMarri Devender Rao {
902ddf64866SMarri Devender Rao     std::string endpoint("ldap");
903e3d47cd4SNan Zhou     CertificateType type = CertificateType::client;
9048841dbd6SMarri Devender Rao     std::string installPath(certDir + "/" + certificateFile);
9058841dbd6SMarri Devender Rao     std::string verifyPath(installPath);
9066ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
907cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
908cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
9098841dbd6SMarri Devender Rao     EXPECT_THROW(
9108841dbd6SMarri Devender Rao         {
9118841dbd6SMarri Devender Rao             try
9128841dbd6SMarri Devender Rao             {
913ffad1ef1SMarri Devender Rao                 auto event = sdeventplus::Event::get_default();
914ffad1ef1SMarri Devender Rao                 // Attach the bus to sd_event to service user requests
915ffad1ef1SMarri Devender Rao                 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
9166ec13c8fSNan Zhou                 ManagerInTest manager(bus, event, objPath.c_str(), type,
9176ec13c8fSNan Zhou                                       verifyUnit, installPath);
918ffad1ef1SMarri Devender Rao                 MainApp mainApp(&manager);
919ffad1ef1SMarri Devender Rao                 mainApp.install(certificateFile);
9208841dbd6SMarri Devender Rao             }
921cd30c496SMarri Devender Rao             catch (const InternalFailure& e)
9228841dbd6SMarri Devender Rao             {
9238841dbd6SMarri Devender Rao                 throw;
9248841dbd6SMarri Devender Rao             }
9258841dbd6SMarri Devender Rao         },
926cd30c496SMarri Devender Rao         InternalFailure);
9278841dbd6SMarri Devender Rao     EXPECT_FALSE(fs::exists(verifyPath));
9288841dbd6SMarri Devender Rao }
9298841dbd6SMarri Devender Rao 
9308841dbd6SMarri Devender Rao /** @brief Check install fails if ceritificate is missing in certificate file
9318841dbd6SMarri Devender Rao  */
TEST_F(TestInvalidCertificate,TestMissingCeritificate)9328841dbd6SMarri Devender Rao TEST_F(TestInvalidCertificate, TestMissingCeritificate)
9338841dbd6SMarri Devender Rao {
9348841dbd6SMarri Devender Rao     std::string endpoint("ldap");
935e3d47cd4SNan Zhou     CertificateType type = CertificateType::client;
9368841dbd6SMarri Devender Rao     std::string installPath(certDir + "/" + keyFile);
9378841dbd6SMarri Devender Rao     std::string verifyPath(installPath);
9386ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
939cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
940cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
9418841dbd6SMarri Devender Rao     EXPECT_THROW(
9428841dbd6SMarri Devender Rao         {
9438841dbd6SMarri Devender Rao             try
9448841dbd6SMarri Devender Rao             {
945f4682712SMarri Devender Rao                 auto event = sdeventplus::Event::get_default();
946ffad1ef1SMarri Devender Rao                 // Attach the bus to sd_event to service user requests
947ffad1ef1SMarri Devender Rao                 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
9486ec13c8fSNan Zhou                 ManagerInTest manager(bus, event, objPath.c_str(), type,
9496ec13c8fSNan Zhou                                       verifyUnit, installPath);
950ddf64866SMarri Devender Rao                 MainApp mainApp(&manager);
951ffad1ef1SMarri Devender Rao                 mainApp.install(keyFile);
952ddf64866SMarri Devender Rao             }
953cd30c496SMarri Devender Rao             catch (const InternalFailure& e)
954ddf64866SMarri Devender Rao             {
955ddf64866SMarri Devender Rao                 throw;
956ddf64866SMarri Devender Rao             }
957ddf64866SMarri Devender Rao         },
958ddf64866SMarri Devender Rao         InvalidCertificate);
959ddf64866SMarri Devender Rao     EXPECT_FALSE(fs::exists(verifyPath));
960ddf64866SMarri Devender Rao }
961ddf64866SMarri Devender Rao 
9628841dbd6SMarri Devender Rao /** @brief Check if error is thrown when multiple certificates are installed
9638841dbd6SMarri Devender Rao  *  At present only one certificate per service is allowed
964ddf64866SMarri Devender Rao  */
TEST_F(TestCertificates,TestCertInstallNotAllowed)9658841dbd6SMarri Devender Rao TEST_F(TestCertificates, TestCertInstallNotAllowed)
966ddf64866SMarri Devender Rao {
9678841dbd6SMarri Devender Rao     using NotAllowed =
9688841dbd6SMarri Devender Rao         sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
969ddf64866SMarri Devender Rao     std::string endpoint("ldap");
970e3d47cd4SNan Zhou     CertificateType type = CertificateType::client;
9718841dbd6SMarri Devender Rao     std::string installPath(certDir + "/" + certificateFile);
9728841dbd6SMarri Devender Rao     std::string verifyPath(installPath);
9736ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
974cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
975cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
976f4682712SMarri Devender Rao     auto event = sdeventplus::Event::get_default();
977ffad1ef1SMarri Devender Rao     // Attach the bus to sd_event to service user requests
978ffad1ef1SMarri Devender Rao     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
9796ec13c8fSNan Zhou     ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
9806ec13c8fSNan Zhou                           installPath);
981ddf64866SMarri Devender Rao     MainApp mainApp(&manager);
9828841dbd6SMarri Devender Rao     mainApp.install(certificateFile);
9838841dbd6SMarri Devender Rao     EXPECT_TRUE(fs::exists(verifyPath));
984ddf64866SMarri Devender Rao     EXPECT_THROW(
985ddf64866SMarri Devender Rao         {
986ddf64866SMarri Devender Rao             try
987ddf64866SMarri Devender Rao             {
9888841dbd6SMarri Devender Rao                 // install second certificate
9898841dbd6SMarri Devender Rao                 mainApp.install(certificateFile);
990ddf64866SMarri Devender Rao             }
9918841dbd6SMarri Devender Rao             catch (const NotAllowed& e)
992ddf64866SMarri Devender Rao             {
993ddf64866SMarri Devender Rao                 throw;
994ddf64866SMarri Devender Rao             }
995ddf64866SMarri Devender Rao         },
9968841dbd6SMarri Devender Rao         NotAllowed);
997e6597c5bSMarri Devender Rao }
998f4682712SMarri Devender Rao 
TEST_F(TestCertificates,TestGenerateCSR)999f4682712SMarri Devender Rao TEST_F(TestCertificates, TestGenerateCSR)
1000f4682712SMarri Devender Rao {
1001f4682712SMarri Devender Rao     std::string endpoint("https");
1002cf06ccdcSNan Zhou     std::string unit;
1003e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
1004f4682712SMarri Devender Rao     std::string installPath(certDir + "/" + certificateFile);
1005f4682712SMarri Devender Rao     std::string verifyPath(installPath);
1006e3d47cd4SNan Zhou     std::string csrPath(certDir + "/" + CSRFile);
1007f4682712SMarri Devender Rao     std::string privateKeyPath(certDir + "/" + privateKeyFile);
1008f4682712SMarri Devender Rao     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
10098a09b52aSRamesh Iyyar     std::string challengePassword("Password");
1010f4682712SMarri Devender Rao     std::string city("HYB");
1011f4682712SMarri Devender Rao     std::string commonName("abc.com");
1012f4682712SMarri Devender Rao     std::string contactPerson("Admin");
1013f4682712SMarri Devender Rao     std::string country("IN");
1014f4682712SMarri Devender Rao     std::string email("admin@in.ibm.com");
1015f4682712SMarri Devender Rao     std::string givenName("givenName");
1016f4682712SMarri Devender Rao     std::string initials("G");
1017f4682712SMarri Devender Rao     int64_t keyBitLength(2048);
1018f4682712SMarri Devender Rao     std::string keyCurveId("0");
1019f4682712SMarri Devender Rao     std::string keyPairAlgorithm("RSA");
1020f4682712SMarri Devender Rao     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1021f4682712SMarri Devender Rao     std::string organization("IBM");
10228a09b52aSRamesh Iyyar     std::string organizationalUnit("orgUnit");
1023f4682712SMarri Devender Rao     std::string state("TS");
1024f4682712SMarri Devender Rao     std::string surname("surname");
1025f4682712SMarri Devender Rao     std::string unstructuredName("unstructuredName");
1026cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
1027cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
1028f4682712SMarri Devender Rao     auto event = sdeventplus::Event::get_default();
1029ffad1ef1SMarri Devender Rao     // Attach the bus to sd_event to service user requests
1030ffad1ef1SMarri Devender Rao     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
1031f4682712SMarri Devender Rao     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1032f4682712SMarri Devender Rao                     std::move(installPath));
1033*887ba5bfSRavi Teja     Status status = Status::success;
1034e3d47cd4SNan Zhou     CSR csr(bus, objPath.c_str(), csrPath.c_str(), status);
1035f4682712SMarri Devender Rao     MainApp mainApp(&manager, &csr);
1036f4682712SMarri Devender Rao     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1037f4682712SMarri Devender Rao                         contactPerson, country, email, givenName, initials,
1038f4682712SMarri Devender Rao                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1039f4682712SMarri Devender Rao                         organization, organizationalUnit, state, surname,
1040f4682712SMarri Devender Rao                         unstructuredName);
1041*887ba5bfSRavi Teja     std::string csrData{};
1042f4682712SMarri Devender Rao     // generateCSR takes considerable time to create CSR and privateKey Files
1043e3d47cd4SNan Zhou     EXPECT_FALSE(fs::exists(csrPath));
1044f4682712SMarri Devender Rao     EXPECT_FALSE(fs::exists(privateKeyPath));
1045f4682712SMarri Devender Rao     EXPECT_THROW(
1046f4682712SMarri Devender Rao         {
1047f4682712SMarri Devender Rao             try
1048f4682712SMarri Devender Rao             {
1049e129be3bSPatrick Williams                 csrData = csr.csr();
1050f4682712SMarri Devender Rao             }
1051f4682712SMarri Devender Rao             catch (const InternalFailure& e)
1052f4682712SMarri Devender Rao             {
1053f4682712SMarri Devender Rao                 throw;
1054f4682712SMarri Devender Rao             }
1055f4682712SMarri Devender Rao         },
1056f4682712SMarri Devender Rao         InternalFailure);
1057f4682712SMarri Devender Rao     // wait for 10 sec to get CSR and privateKey Files generated
1058f4682712SMarri Devender Rao     sleep(10);
1059e3d47cd4SNan Zhou     EXPECT_TRUE(fs::exists(csrPath));
1060f4682712SMarri Devender Rao     EXPECT_TRUE(fs::exists(privateKeyPath));
1061e129be3bSPatrick Williams     csrData = csr.csr();
1062f4682712SMarri Devender Rao     ASSERT_NE("", csrData.c_str());
1063f4682712SMarri Devender Rao }
1064f4682712SMarri Devender Rao 
10658a09b52aSRamesh Iyyar /** @brief Check if ECC key pair is generated when user is not given algorithm
10668a09b52aSRamesh Iyyar  * type. At present RSA and EC key pair algorithm are supported
10678a09b52aSRamesh Iyyar  */
TEST_F(TestCertificates,TestGenerateCSRwithEmptyKeyPairAlgorithm)10688a09b52aSRamesh Iyyar TEST_F(TestCertificates, TestGenerateCSRwithEmptyKeyPairAlgorithm)
10698a09b52aSRamesh Iyyar {
10708a09b52aSRamesh Iyyar     std::string endpoint("https");
1071cf06ccdcSNan Zhou     std::string unit;
1072e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
10738a09b52aSRamesh Iyyar     std::string installPath(certDir + "/" + certificateFile);
10748a09b52aSRamesh Iyyar     std::string verifyPath(installPath);
1075e3d47cd4SNan Zhou     std::string csrPath(certDir + "/" + CSRFile);
10768a09b52aSRamesh Iyyar     std::string privateKeyPath(certDir + "/" + privateKeyFile);
10778a09b52aSRamesh Iyyar     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
10788a09b52aSRamesh Iyyar     std::string challengePassword("Password");
10798a09b52aSRamesh Iyyar     std::string city("HYB");
10808a09b52aSRamesh Iyyar     std::string commonName("abc.com");
10818a09b52aSRamesh Iyyar     std::string contactPerson("Admin");
10828a09b52aSRamesh Iyyar     std::string country("IN");
10838a09b52aSRamesh Iyyar     std::string email("admin@in.ibm.com");
10848a09b52aSRamesh Iyyar     std::string givenName("givenName");
10858a09b52aSRamesh Iyyar     std::string initials("G");
10868a09b52aSRamesh Iyyar     int64_t keyBitLength(2048);
10878a09b52aSRamesh Iyyar     std::string keyCurveId("");
10888a09b52aSRamesh Iyyar     std::string keyPairAlgorithm("");
10898a09b52aSRamesh Iyyar     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
10908a09b52aSRamesh Iyyar     std::string organization("IBM");
10918a09b52aSRamesh Iyyar     std::string organizationalUnit("orgUnit");
10928a09b52aSRamesh Iyyar     std::string state("TS");
10938a09b52aSRamesh Iyyar     std::string surname("surname");
10948a09b52aSRamesh Iyyar     std::string unstructuredName("unstructuredName");
1095cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
1096cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
1097f4682712SMarri Devender Rao     auto event = sdeventplus::Event::get_default();
1098f4682712SMarri Devender Rao     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1099f4682712SMarri Devender Rao                     std::move(installPath));
1100f4682712SMarri Devender Rao     Status status;
1101e3d47cd4SNan Zhou     CSR csr(bus, objPath.c_str(), csrPath.c_str(), status);
1102f4682712SMarri Devender Rao     MainApp mainApp(&manager, &csr);
1103f4682712SMarri Devender Rao     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1104f4682712SMarri Devender Rao                         contactPerson, country, email, givenName, initials,
1105f4682712SMarri Devender Rao                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1106f4682712SMarri Devender Rao                         organization, organizationalUnit, state, surname,
1107f4682712SMarri Devender Rao                         unstructuredName);
1108f4682712SMarri Devender Rao     sleep(10);
1109e3d47cd4SNan Zhou     EXPECT_TRUE(fs::exists(csrPath));
11108a09b52aSRamesh Iyyar     EXPECT_TRUE(fs::exists(privateKeyPath));
11118a09b52aSRamesh Iyyar }
11128a09b52aSRamesh Iyyar 
11138a09b52aSRamesh Iyyar /** @brief Check if error is thrown when giving un supported key pair
11148a09b52aSRamesh Iyyar  * algorithm. At present RSA and EC key pair algorithm are supported
11158a09b52aSRamesh Iyyar  */
TEST_F(TestCertificates,TestGenerateCSRwithUnsupportedKeyPairAlgorithm)11168a09b52aSRamesh Iyyar TEST_F(TestCertificates, TestGenerateCSRwithUnsupportedKeyPairAlgorithm)
11178a09b52aSRamesh Iyyar {
11188a09b52aSRamesh Iyyar     std::string endpoint("https");
1119cf06ccdcSNan Zhou     std::string unit;
1120e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
11218a09b52aSRamesh Iyyar     std::string installPath(certDir + "/" + certificateFile);
11228a09b52aSRamesh Iyyar     std::string verifyPath(installPath);
1123e3d47cd4SNan Zhou     std::string csrPath(certDir + "/" + CSRFile);
11248a09b52aSRamesh Iyyar     std::string privateKeyPath(certDir + "/" + privateKeyFile);
11258a09b52aSRamesh Iyyar     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
11268a09b52aSRamesh Iyyar     std::string challengePassword("Password");
11278a09b52aSRamesh Iyyar     std::string city("HYB");
11288a09b52aSRamesh Iyyar     std::string commonName("abc.com");
11298a09b52aSRamesh Iyyar     std::string contactPerson("Admin");
11308a09b52aSRamesh Iyyar     std::string country("IN");
11318a09b52aSRamesh Iyyar     std::string email("admin@in.ibm.com");
11328a09b52aSRamesh Iyyar     std::string givenName("givenName");
11338a09b52aSRamesh Iyyar     std::string initials("G");
11348a09b52aSRamesh Iyyar     int64_t keyBitLength(2048);
11358a09b52aSRamesh Iyyar     std::string keyCurveId("secp521r1");
11368a09b52aSRamesh Iyyar     std::string keyPairAlgorithm("UnSupportedAlgorithm");
11378a09b52aSRamesh Iyyar     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
11388a09b52aSRamesh Iyyar     std::string organization("IBM");
11398a09b52aSRamesh Iyyar     std::string organizationalUnit("orgUnit");
11408a09b52aSRamesh Iyyar     std::string state("TS");
11418a09b52aSRamesh Iyyar     std::string surname("surname");
11428a09b52aSRamesh Iyyar     std::string unstructuredName("unstructuredName");
1143cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
1144cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
11458a09b52aSRamesh Iyyar     auto event = sdeventplus::Event::get_default();
11468a09b52aSRamesh Iyyar     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
11478a09b52aSRamesh Iyyar                     std::move(installPath));
11488a09b52aSRamesh Iyyar     Status status;
1149e3d47cd4SNan Zhou     CSR csr(bus, objPath.c_str(), csrPath.c_str(), status);
11508a09b52aSRamesh Iyyar     MainApp mainApp(&manager, &csr);
11518a09b52aSRamesh Iyyar     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
11528a09b52aSRamesh Iyyar                         contactPerson, country, email, givenName, initials,
11538a09b52aSRamesh Iyyar                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
11548a09b52aSRamesh Iyyar                         organization, organizationalUnit, state, surname,
11558a09b52aSRamesh Iyyar                         unstructuredName);
1156e3d47cd4SNan Zhou     EXPECT_FALSE(fs::exists(csrPath));
1157f4682712SMarri Devender Rao     EXPECT_FALSE(fs::exists(privateKeyPath));
1158f4682712SMarri Devender Rao }
11598a09b52aSRamesh Iyyar 
11608a09b52aSRamesh Iyyar /** @brief Check if error is thrown when NID_undef is returned for given key
11618a09b52aSRamesh Iyyar  * curve id
11628a09b52aSRamesh Iyyar  */
TEST_F(TestCertificates,TestECKeyGenerationwithNIDundefCase)11638a09b52aSRamesh Iyyar TEST_F(TestCertificates, TestECKeyGenerationwithNIDundefCase)
11648a09b52aSRamesh Iyyar {
11658a09b52aSRamesh Iyyar     std::string endpoint("https");
1166cf06ccdcSNan Zhou     std::string unit;
1167e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
11688a09b52aSRamesh Iyyar     std::string installPath(certDir + "/" + certificateFile);
11698a09b52aSRamesh Iyyar     std::string verifyPath(installPath);
1170e3d47cd4SNan Zhou     std::string csrPath(certDir + "/" + CSRFile);
11718a09b52aSRamesh Iyyar     std::string privateKeyPath(certDir + "/" + privateKeyFile);
11728a09b52aSRamesh Iyyar     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
11738a09b52aSRamesh Iyyar     std::string challengePassword("Password");
11748a09b52aSRamesh Iyyar     std::string city("BLR");
11758a09b52aSRamesh Iyyar     std::string commonName("abc.com");
11768a09b52aSRamesh Iyyar     std::string contactPerson("Admin");
11778a09b52aSRamesh Iyyar     std::string country("IN");
11788a09b52aSRamesh Iyyar     std::string email("admin@in.ibm.com");
11798a09b52aSRamesh Iyyar     std::string givenName("givenName");
11808a09b52aSRamesh Iyyar     std::string initials("G");
11818a09b52aSRamesh Iyyar     int64_t keyBitLength(2048);
11828a09b52aSRamesh Iyyar     std::string keyCurveId("DummyCurveName");
11838a09b52aSRamesh Iyyar     std::string keyPairAlgorithm("EC");
11848a09b52aSRamesh Iyyar     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
11858a09b52aSRamesh Iyyar     std::string organization("IBM");
11868a09b52aSRamesh Iyyar     std::string organizationalUnit("orgUnit");
11878a09b52aSRamesh Iyyar     std::string state("TS");
11888a09b52aSRamesh Iyyar     std::string surname("surname");
11898a09b52aSRamesh Iyyar     std::string unstructuredName("unstructuredName");
1190cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
1191cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
11928a09b52aSRamesh Iyyar     auto event = sdeventplus::Event::get_default();
11938a09b52aSRamesh Iyyar     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
11948a09b52aSRamesh Iyyar                     std::move(installPath));
11958a09b52aSRamesh Iyyar     Status status;
1196e3d47cd4SNan Zhou     CSR csr(bus, objPath.c_str(), csrPath.c_str(), status);
11978a09b52aSRamesh Iyyar     MainApp mainApp(&manager, &csr);
11988a09b52aSRamesh Iyyar     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
11998a09b52aSRamesh Iyyar                         contactPerson, country, email, givenName, initials,
12008a09b52aSRamesh Iyyar                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
12018a09b52aSRamesh Iyyar                         organization, organizationalUnit, state, surname,
12028a09b52aSRamesh Iyyar                         unstructuredName);
1203e3d47cd4SNan Zhou     EXPECT_FALSE(fs::exists(csrPath));
12048a09b52aSRamesh Iyyar     EXPECT_FALSE(fs::exists(privateKeyPath));
12058a09b52aSRamesh Iyyar }
12068a09b52aSRamesh Iyyar 
12078a09b52aSRamesh Iyyar /** @brief Check default Key Curve Id is used if given curve id is empty
12088a09b52aSRamesh Iyyar  */
TEST_F(TestCertificates,TestECKeyGenerationwithDefaultKeyCurveId)12098a09b52aSRamesh Iyyar TEST_F(TestCertificates, TestECKeyGenerationwithDefaultKeyCurveId)
12108a09b52aSRamesh Iyyar {
12118a09b52aSRamesh Iyyar     std::string endpoint("https");
1212cf06ccdcSNan Zhou     std::string unit;
1213e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
12148a09b52aSRamesh Iyyar     std::string installPath(certDir + "/" + certificateFile);
12158a09b52aSRamesh Iyyar     std::string verifyPath(installPath);
1216e3d47cd4SNan Zhou     std::string csrPath(certDir + "/" + CSRFile);
12178a09b52aSRamesh Iyyar     std::string privateKeyPath(certDir + "/" + privateKeyFile);
12188a09b52aSRamesh Iyyar     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
12198a09b52aSRamesh Iyyar     std::string challengePassword("Password");
12208a09b52aSRamesh Iyyar     std::string city("BLR");
12218a09b52aSRamesh Iyyar     std::string commonName("abc.com");
12228a09b52aSRamesh Iyyar     std::string contactPerson("Admin");
12238a09b52aSRamesh Iyyar     std::string country("IN");
12248a09b52aSRamesh Iyyar     std::string email("admin@in.ibm.com");
12258a09b52aSRamesh Iyyar     std::string givenName("givenName");
12268a09b52aSRamesh Iyyar     std::string initials("G");
12278a09b52aSRamesh Iyyar     int64_t keyBitLength(2048);
12288a09b52aSRamesh Iyyar     std::string keyCurveId("");
12298a09b52aSRamesh Iyyar     std::string keyPairAlgorithm("EC");
12308a09b52aSRamesh Iyyar     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
12318a09b52aSRamesh Iyyar     std::string organization("IBM");
12328a09b52aSRamesh Iyyar     std::string organizationalUnit("orgUnit");
12338a09b52aSRamesh Iyyar     std::string state("TS");
12348a09b52aSRamesh Iyyar     std::string surname("surname");
12358a09b52aSRamesh Iyyar     std::string unstructuredName("unstructuredName");
1236cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
1237cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
12388a09b52aSRamesh Iyyar     auto event = sdeventplus::Event::get_default();
12398a09b52aSRamesh Iyyar     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
12408a09b52aSRamesh Iyyar                     std::move(installPath));
12418a09b52aSRamesh Iyyar     Status status;
1242e3d47cd4SNan Zhou     CSR csr(bus, objPath.c_str(), csrPath.c_str(), status);
12438a09b52aSRamesh Iyyar     MainApp mainApp(&manager, &csr);
12448a09b52aSRamesh Iyyar     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
12458a09b52aSRamesh Iyyar                         contactPerson, country, email, givenName, initials,
12468a09b52aSRamesh Iyyar                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
12478a09b52aSRamesh Iyyar                         organization, organizationalUnit, state, surname,
12488a09b52aSRamesh Iyyar                         unstructuredName);
12498a09b52aSRamesh Iyyar     sleep(10);
1250e3d47cd4SNan Zhou     EXPECT_TRUE(fs::exists(csrPath));
12518a09b52aSRamesh Iyyar     EXPECT_TRUE(fs::exists(privateKeyPath));
12528a09b52aSRamesh Iyyar }
12538a09b52aSRamesh Iyyar 
12548a09b52aSRamesh Iyyar /** @brief Check if error is not thrown to generate EC key pair
12558a09b52aSRamesh Iyyar  */
TEST_F(TestCertificates,TestECKeyGeneration)12568a09b52aSRamesh Iyyar TEST_F(TestCertificates, TestECKeyGeneration)
12578a09b52aSRamesh Iyyar {
12588a09b52aSRamesh Iyyar     std::string endpoint("https");
1259cf06ccdcSNan Zhou     std::string unit;
1260e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
12618a09b52aSRamesh Iyyar     std::string installPath(certDir + "/" + certificateFile);
12628a09b52aSRamesh Iyyar     std::string verifyPath(installPath);
1263e3d47cd4SNan Zhou     std::string csrPath(certDir + "/" + CSRFile);
12648a09b52aSRamesh Iyyar     std::string privateKeyPath(certDir + "/" + privateKeyFile);
12658a09b52aSRamesh Iyyar     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
12668a09b52aSRamesh Iyyar     std::string challengePassword("Password");
12678a09b52aSRamesh Iyyar     std::string city("BLR");
12688a09b52aSRamesh Iyyar     std::string commonName("abc.com");
12698a09b52aSRamesh Iyyar     std::string contactPerson("Admin");
12708a09b52aSRamesh Iyyar     std::string country("IN");
12718a09b52aSRamesh Iyyar     std::string email("admin@in.ibm.com");
12728a09b52aSRamesh Iyyar     std::string givenName("givenName");
12738a09b52aSRamesh Iyyar     std::string initials("G");
12748a09b52aSRamesh Iyyar     int64_t keyBitLength(2048);
12758a09b52aSRamesh Iyyar     std::string keyCurveId("secp521r1");
12768a09b52aSRamesh Iyyar     std::string keyPairAlgorithm("EC");
12778a09b52aSRamesh Iyyar     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
12788a09b52aSRamesh Iyyar     std::string organization("IBM");
12798a09b52aSRamesh Iyyar     std::string organizationalUnit("orgUnit");
12808a09b52aSRamesh Iyyar     std::string state("TS");
12818a09b52aSRamesh Iyyar     std::string surname("surname");
12828a09b52aSRamesh Iyyar     std::string unstructuredName("unstructuredName");
1283cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
1284cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
12858a09b52aSRamesh Iyyar     auto event = sdeventplus::Event::get_default();
12868a09b52aSRamesh Iyyar     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
12878a09b52aSRamesh Iyyar                     std::move(installPath));
1288*887ba5bfSRavi Teja     Status status = Status::success;
1289e3d47cd4SNan Zhou     CSR csr(bus, objPath.c_str(), csrPath.c_str(), status);
12908a09b52aSRamesh Iyyar     MainApp mainApp(&manager, &csr);
12918a09b52aSRamesh Iyyar     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
12928a09b52aSRamesh Iyyar                         contactPerson, country, email, givenName, initials,
12938a09b52aSRamesh Iyyar                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
12948a09b52aSRamesh Iyyar                         organization, organizationalUnit, state, surname,
12958a09b52aSRamesh Iyyar                         unstructuredName);
1296e3d47cd4SNan Zhou     std::cout << "CSRPath: " << csrPath << std::endl
12978a09b52aSRamesh Iyyar               << "privateKeyPath: " << privateKeyPath << std::endl;
12988a09b52aSRamesh Iyyar     sleep(10);
1299e3d47cd4SNan Zhou     EXPECT_TRUE(fs::exists(csrPath));
13008a09b52aSRamesh Iyyar     EXPECT_TRUE(fs::exists(privateKeyPath));
13018a09b52aSRamesh Iyyar }
1302c6e58c7eSRamesh Iyyar 
1303bf3cf751SNan Zhou /** @brief Check error is thrown if giving unsupported key bit length to
1304c6e58c7eSRamesh Iyyar  * generate rsa key
1305c6e58c7eSRamesh Iyyar  */
TEST_F(TestCertificates,TestRSAKeyWithUnsupportedKeyBitLength)1306c6e58c7eSRamesh Iyyar TEST_F(TestCertificates, TestRSAKeyWithUnsupportedKeyBitLength)
1307c6e58c7eSRamesh Iyyar {
1308c6e58c7eSRamesh Iyyar     std::string endpoint("https");
1309cf06ccdcSNan Zhou     std::string unit;
1310e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
1311c6e58c7eSRamesh Iyyar     std::string installPath(certDir + "/" + certificateFile);
1312c6e58c7eSRamesh Iyyar     std::string verifyPath(installPath);
1313e3d47cd4SNan Zhou     std::string csrPath(certDir + "/" + CSRFile);
1314c6e58c7eSRamesh Iyyar     std::string privateKeyPath(certDir + "/" + privateKeyFile);
1315c6e58c7eSRamesh Iyyar     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1316c6e58c7eSRamesh Iyyar     std::string challengePassword("Password");
1317c6e58c7eSRamesh Iyyar     std::string city("BLR");
1318c6e58c7eSRamesh Iyyar     std::string commonName("abc.com");
1319c6e58c7eSRamesh Iyyar     std::string contactPerson("Admin");
1320c6e58c7eSRamesh Iyyar     std::string country("IN");
1321c6e58c7eSRamesh Iyyar     std::string email("admin@in.ibm.com");
1322c6e58c7eSRamesh Iyyar     std::string givenName("givenName");
1323c6e58c7eSRamesh Iyyar     std::string initials("G");
1324c6e58c7eSRamesh Iyyar     int64_t keyBitLength(4096);
1325c6e58c7eSRamesh Iyyar     std::string keyCurveId("secp521r1");
1326c6e58c7eSRamesh Iyyar     std::string keyPairAlgorithm("RSA");
1327c6e58c7eSRamesh Iyyar     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1328c6e58c7eSRamesh Iyyar     std::string organization("IBM");
1329c6e58c7eSRamesh Iyyar     std::string organizationalUnit("orgUnit");
1330c6e58c7eSRamesh Iyyar     std::string state("TS");
1331c6e58c7eSRamesh Iyyar     std::string surname("surname");
1332c6e58c7eSRamesh Iyyar     std::string unstructuredName("unstructuredName");
1333cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
1334cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
1335c6e58c7eSRamesh Iyyar     auto event = sdeventplus::Event::get_default();
1336c6e58c7eSRamesh Iyyar     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1337c6e58c7eSRamesh Iyyar                     std::move(installPath));
1338c6e58c7eSRamesh Iyyar     Status status;
1339e3d47cd4SNan Zhou     CSR csr(bus, objPath.c_str(), csrPath.c_str(), status);
1340c6e58c7eSRamesh Iyyar     MainApp mainApp(&manager, &csr);
1341c6e58c7eSRamesh Iyyar     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1342c6e58c7eSRamesh Iyyar                         contactPerson, country, email, givenName, initials,
1343c6e58c7eSRamesh Iyyar                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1344c6e58c7eSRamesh Iyyar                         organization, organizationalUnit, state, surname,
1345c6e58c7eSRamesh Iyyar                         unstructuredName);
1346e3d47cd4SNan Zhou     EXPECT_FALSE(fs::exists(csrPath));
1347c6e58c7eSRamesh Iyyar     EXPECT_FALSE(fs::exists(privateKeyPath));
1348c6e58c7eSRamesh Iyyar }
1349c6e58c7eSRamesh Iyyar 
1350c6e58c7eSRamesh Iyyar /** @brief Check error is thrown if generated rsa key file is not present
1351c6e58c7eSRamesh Iyyar  */
TEST_F(TestCertificates,TestRSAKeyFileNotPresentCase)1352c6e58c7eSRamesh Iyyar TEST_F(TestCertificates, TestRSAKeyFileNotPresentCase)
1353c6e58c7eSRamesh Iyyar {
1354c6e58c7eSRamesh Iyyar     std::string endpoint("https");
1355cf06ccdcSNan Zhou     std::string unit;
1356e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
1357c6e58c7eSRamesh Iyyar     std::string installPath(certDir + "/" + certificateFile);
1358c6e58c7eSRamesh Iyyar     std::string verifyPath(installPath);
1359e3d47cd4SNan Zhou     std::string csrPath(certDir + "/" + CSRFile);
1360c6e58c7eSRamesh Iyyar     std::string privateKeyPath(certDir + "/" + privateKeyFile);
1361c6e58c7eSRamesh Iyyar     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1362c6e58c7eSRamesh Iyyar     std::string challengePassword("Password");
1363c6e58c7eSRamesh Iyyar     std::string city("BLR");
1364c6e58c7eSRamesh Iyyar     std::string commonName("abc.com");
1365c6e58c7eSRamesh Iyyar     std::string contactPerson("Admin");
1366c6e58c7eSRamesh Iyyar     std::string country("IN");
1367c6e58c7eSRamesh Iyyar     std::string email("admin@in.ibm.com");
1368c6e58c7eSRamesh Iyyar     std::string givenName("givenName");
1369c6e58c7eSRamesh Iyyar     std::string initials("G");
1370c6e58c7eSRamesh Iyyar     int64_t keyBitLength(2048);
1371c6e58c7eSRamesh Iyyar     std::string keyCurveId("secp521r1");
1372c6e58c7eSRamesh Iyyar     std::string keyPairAlgorithm("RSA");
1373c6e58c7eSRamesh Iyyar     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1374c6e58c7eSRamesh Iyyar     std::string organization("IBM");
1375c6e58c7eSRamesh Iyyar     std::string organizationalUnit("orgUnit");
1376c6e58c7eSRamesh Iyyar     std::string state("TS");
1377c6e58c7eSRamesh Iyyar     std::string surname("surname");
1378c6e58c7eSRamesh Iyyar     std::string unstructuredName("unstructuredName");
1379cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
1380cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
1381c6e58c7eSRamesh Iyyar     auto event = sdeventplus::Event::get_default();
1382c6e58c7eSRamesh Iyyar     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1383c6e58c7eSRamesh Iyyar                     std::move(installPath));
1384c6e58c7eSRamesh Iyyar 
1385c6e58c7eSRamesh Iyyar     // Removing generated RSA key file
1386c6e58c7eSRamesh Iyyar     fs::remove(rsaPrivateKeyFilePath);
1387c6e58c7eSRamesh Iyyar 
1388c6e58c7eSRamesh Iyyar     Status status;
1389e3d47cd4SNan Zhou     CSR csr(bus, objPath.c_str(), csrPath.c_str(), status);
1390c6e58c7eSRamesh Iyyar     MainApp mainApp(&manager, &csr);
1391c6e58c7eSRamesh Iyyar     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1392c6e58c7eSRamesh Iyyar                         contactPerson, country, email, givenName, initials,
1393c6e58c7eSRamesh Iyyar                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1394c6e58c7eSRamesh Iyyar                         organization, organizationalUnit, state, surname,
1395c6e58c7eSRamesh Iyyar                         unstructuredName);
1396e3d47cd4SNan Zhou     EXPECT_FALSE(fs::exists(csrPath));
1397c6e58c7eSRamesh Iyyar     EXPECT_FALSE(fs::exists(privateKeyPath));
1398c6e58c7eSRamesh Iyyar }
1399c6e58c7eSRamesh Iyyar 
1400c6e58c7eSRamesh Iyyar /** @brief Check private key file is created from generated rsa key file is
1401c6e58c7eSRamesh Iyyar  * `present
1402c6e58c7eSRamesh Iyyar  */
TEST_F(TestCertificates,TestRSAKeyFromRSAKeyFileIsWrittenIntoPrivateKeyFile)1403c6e58c7eSRamesh Iyyar TEST_F(TestCertificates, TestRSAKeyFromRSAKeyFileIsWrittenIntoPrivateKeyFile)
1404c6e58c7eSRamesh Iyyar {
1405c6e58c7eSRamesh Iyyar     std::string endpoint("https");
1406cf06ccdcSNan Zhou     std::string unit;
1407e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
1408c6e58c7eSRamesh Iyyar     std::string installPath(certDir + "/" + certificateFile);
1409c6e58c7eSRamesh Iyyar     std::string verifyPath(installPath);
1410e3d47cd4SNan Zhou     std::string csrPath(certDir + "/" + CSRFile);
1411c6e58c7eSRamesh Iyyar     std::string privateKeyPath(certDir + "/" + privateKeyFile);
1412c6e58c7eSRamesh Iyyar     std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
1413c6e58c7eSRamesh Iyyar     std::string challengePassword("Password");
1414c6e58c7eSRamesh Iyyar     std::string city("BLR");
1415c6e58c7eSRamesh Iyyar     std::string commonName("abc.com");
1416c6e58c7eSRamesh Iyyar     std::string contactPerson("Admin");
1417c6e58c7eSRamesh Iyyar     std::string country("IN");
1418c6e58c7eSRamesh Iyyar     std::string email("admin@in.ibm.com");
1419c6e58c7eSRamesh Iyyar     std::string givenName("givenName");
1420c6e58c7eSRamesh Iyyar     std::string initials("G");
1421c6e58c7eSRamesh Iyyar     int64_t keyBitLength(2048);
1422c6e58c7eSRamesh Iyyar     std::string keyCurveId("secp521r1");
1423c6e58c7eSRamesh Iyyar     std::string keyPairAlgorithm("RSA");
1424c6e58c7eSRamesh Iyyar     std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
1425c6e58c7eSRamesh Iyyar     std::string organization("IBM");
1426c6e58c7eSRamesh Iyyar     std::string organizationalUnit("orgUnit");
1427c6e58c7eSRamesh Iyyar     std::string state("TS");
1428c6e58c7eSRamesh Iyyar     std::string surname("surname");
1429c6e58c7eSRamesh Iyyar     std::string unstructuredName("unstructuredName");
1430cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
1431cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
1432c6e58c7eSRamesh Iyyar     auto event = sdeventplus::Event::get_default();
1433c6e58c7eSRamesh Iyyar     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
1434c6e58c7eSRamesh Iyyar                     std::move(installPath));
1435c6e58c7eSRamesh Iyyar     Status status;
1436e3d47cd4SNan Zhou     CSR csr(bus, objPath.c_str(), csrPath.c_str(), status);
1437c6e58c7eSRamesh Iyyar     MainApp mainApp(&manager, &csr);
1438c6e58c7eSRamesh Iyyar     mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
1439c6e58c7eSRamesh Iyyar                         contactPerson, country, email, givenName, initials,
1440c6e58c7eSRamesh Iyyar                         keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
1441c6e58c7eSRamesh Iyyar                         organization, organizationalUnit, state, surname,
1442c6e58c7eSRamesh Iyyar                         unstructuredName);
1443c6e58c7eSRamesh Iyyar     sleep(10);
1444e3d47cd4SNan Zhou     EXPECT_TRUE(fs::exists(csrPath));
1445c6e58c7eSRamesh Iyyar     EXPECT_TRUE(fs::exists(privateKeyPath));
1446c6e58c7eSRamesh Iyyar }
1447c6e58c7eSRamesh Iyyar 
1448bf3cf751SNan Zhou /** @brief Check RSA key is generated during application startup*/
TEST_F(TestCertificates,TestGenerateRSAPrivateKeyFile)1449c6e58c7eSRamesh Iyyar TEST_F(TestCertificates, TestGenerateRSAPrivateKeyFile)
1450c6e58c7eSRamesh Iyyar {
1451c6e58c7eSRamesh Iyyar     std::string endpoint("https");
1452e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
1453c6e58c7eSRamesh Iyyar     std::string installPath(certDir + "/" + certificateFile);
14546ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
1455cf06ccdcSNan Zhou     auto objPath = std::string(objectNamePrefix) + '/' +
1456cf06ccdcSNan Zhou                    certificateTypeToString(type) + '/' + endpoint;
1457c6e58c7eSRamesh Iyyar     auto event = sdeventplus::Event::get_default();
1458c6e58c7eSRamesh Iyyar 
1459c6e58c7eSRamesh Iyyar     EXPECT_FALSE(fs::exists(rsaPrivateKeyFilePath));
14606ec13c8fSNan Zhou     Manager manager(bus, event, objPath.c_str(), type, verifyUnit, installPath);
1461c6e58c7eSRamesh Iyyar     EXPECT_TRUE(fs::exists(rsaPrivateKeyFilePath));
1462c6e58c7eSRamesh Iyyar }
14636ec13c8fSNan Zhou 
14646ec13c8fSNan Zhou /**
14656ec13c8fSNan Zhou  * Class to test Authorities List installation and replacement
14666ec13c8fSNan Zhou  */
14676ec13c8fSNan Zhou class AuthoritiesListTest : public testing::Test
14686ec13c8fSNan Zhou {
14696ec13c8fSNan Zhou   public:
AuthoritiesListTest()14706ec13c8fSNan Zhou     AuthoritiesListTest() :
14716ec13c8fSNan Zhou         bus(sdbusplus::bus::new_default()),
14726ec13c8fSNan Zhou         authoritiesListFolder(
14736ec13c8fSNan Zhou             Certificate::generateUniqueFilePath(fs::temp_directory_path()))
14746ec13c8fSNan Zhou     {
14756ec13c8fSNan Zhou         fs::create_directory(authoritiesListFolder);
14766ec13c8fSNan Zhou         createAuthoritiesList(maxNumAuthorityCertificates);
14776ec13c8fSNan Zhou     }
~AuthoritiesListTest()14786ec13c8fSNan Zhou     ~AuthoritiesListTest() override
14796ec13c8fSNan Zhou     {
14806ec13c8fSNan Zhou         fs::remove_all(authoritiesListFolder);
14816ec13c8fSNan Zhou     }
14826ec13c8fSNan Zhou 
14836ec13c8fSNan Zhou   protected:
14846ec13c8fSNan Zhou     // Creates a testing authorities list which consists of |count| root
14856ec13c8fSNan Zhou     // certificates
createAuthoritiesList(int count)14866ec13c8fSNan Zhou     void createAuthoritiesList(int count)
14876ec13c8fSNan Zhou     {
14886ec13c8fSNan Zhou         fs::path srcFolder = fs::temp_directory_path();
14896ec13c8fSNan Zhou         srcFolder = Certificate::generateUniqueFilePath(srcFolder);
14906ec13c8fSNan Zhou         fs::create_directory(srcFolder);
14916ec13c8fSNan Zhou         createSingleAuthority(srcFolder, "root_0");
14926ec13c8fSNan Zhou         sourceAuthoritiesListFile = srcFolder / "root_0_cert";
14936ec13c8fSNan Zhou         for (int i = 1; i < count; ++i)
14946ec13c8fSNan Zhou         {
14956ec13c8fSNan Zhou             std::string name = "root_" + std::to_string(i);
14966ec13c8fSNan Zhou             createSingleAuthority(srcFolder, name);
14976ec13c8fSNan Zhou             appendContentFromFile(sourceAuthoritiesListFile,
14986ec13c8fSNan Zhou                                   srcFolder / (name + "_cert"));
14996ec13c8fSNan Zhou         }
15006ec13c8fSNan Zhou     }
15016ec13c8fSNan Zhou 
15026ec13c8fSNan Zhou     // Creates a single self-signed root certificate in given |path|; the key
15036ec13c8fSNan Zhou     // will be |path|/|cn|_key, the cert will be |path|/|cn|_cert, and the cn
15046ec13c8fSNan Zhou     // will be "/O=openbmc-project.xyz/C=US/ST=CA/CN=|cn|"
createSingleAuthority(const std::string & path,const std::string & cn)15056ec13c8fSNan Zhou     static void createSingleAuthority(const std::string& path,
15066ec13c8fSNan Zhou                                       const std::string& cn)
15076ec13c8fSNan Zhou     {
15086ec13c8fSNan Zhou         std::string key = fs::path(path) / (cn + "_key");
15096ec13c8fSNan Zhou         std::string cert = fs::path(path) / (cn + "_cert");
15106ec13c8fSNan Zhou         std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 -keyout ";
15116ec13c8fSNan Zhou         cmd += key + " -out " + cert + " -nodes --days 365000 ";
15126ec13c8fSNan Zhou         cmd += "-subj /O=openbmc-project.xyz/CN=" + cn;
15136ec13c8fSNan Zhou         ASSERT_EQ(std::system(cmd.c_str()), 0);
15146ec13c8fSNan Zhou     }
15156ec13c8fSNan Zhou 
15166ec13c8fSNan Zhou     // Appends the content of the |from| file to the |to| file.
appendContentFromFile(const std::string & to,const std::string & from)15176ec13c8fSNan Zhou     static void appendContentFromFile(const std::string& to,
15186ec13c8fSNan Zhou                                       const std::string& from)
15196ec13c8fSNan Zhou     {
15206ec13c8fSNan Zhou         ASSERT_NO_THROW({
15216ec13c8fSNan Zhou             std::ifstream inputCertFileStream;
15226ec13c8fSNan Zhou             std::ofstream outputCertFileStream;
15236ec13c8fSNan Zhou             inputCertFileStream.exceptions(std::ifstream::failbit |
15246ec13c8fSNan Zhou                                            std::ifstream::badbit |
15256ec13c8fSNan Zhou                                            std::ifstream::eofbit);
15266ec13c8fSNan Zhou             outputCertFileStream.exceptions(std::ofstream::failbit |
15276ec13c8fSNan Zhou                                             std::ofstream::badbit |
15286ec13c8fSNan Zhou                                             std::ofstream::eofbit);
15296ec13c8fSNan Zhou             inputCertFileStream.open(from);
15306ec13c8fSNan Zhou             outputCertFileStream.open(to, std::ios::app);
15316ec13c8fSNan Zhou             outputCertFileStream << inputCertFileStream.rdbuf() << std::flush;
15326ec13c8fSNan Zhou             inputCertFileStream.close();
15336ec13c8fSNan Zhou             outputCertFileStream.close();
15346ec13c8fSNan Zhou         });
15356ec13c8fSNan Zhou     }
15366ec13c8fSNan Zhou 
15376ec13c8fSNan Zhou     // Appends the content of the |from| buffer to the |to| file.
setContentFromString(const std::string & to,const std::string & from)15386ec13c8fSNan Zhou     static void setContentFromString(const std::string& to,
15396ec13c8fSNan Zhou                                      const std::string& from)
15406ec13c8fSNan Zhou     {
15416ec13c8fSNan Zhou         ASSERT_NO_THROW({
15426ec13c8fSNan Zhou             std::ofstream outputCertFileStream;
15436ec13c8fSNan Zhou             outputCertFileStream.exceptions(std::ofstream::failbit |
15446ec13c8fSNan Zhou                                             std::ofstream::badbit |
15456ec13c8fSNan Zhou                                             std::ofstream::eofbit);
15466ec13c8fSNan Zhou             outputCertFileStream.open(to, std::ios::out);
15476ec13c8fSNan Zhou             outputCertFileStream << from << std::flush;
15486ec13c8fSNan Zhou             outputCertFileStream.close();
15496ec13c8fSNan Zhou         });
15506ec13c8fSNan Zhou     }
15516ec13c8fSNan Zhou 
15526ec13c8fSNan Zhou     // Verifies the effect of InstallAll or ReplaceAll
verifyCertificates(std::vector<std::unique_ptr<Certificate>> & certs)15536ec13c8fSNan Zhou     void verifyCertificates(std::vector<std::unique_ptr<Certificate>>& certs)
15546ec13c8fSNan Zhou     {
15556ec13c8fSNan Zhou         // The trust bundle file has been copied over
15566ec13c8fSNan Zhou         EXPECT_FALSE(fs::is_empty(authoritiesListFolder));
15576ec13c8fSNan Zhou         EXPECT_TRUE(
15586ec13c8fSNan Zhou             compareFiles(authoritiesListFolder / defaultAuthoritiesListFileName,
15596ec13c8fSNan Zhou                          sourceAuthoritiesListFile));
15606ec13c8fSNan Zhou 
15616ec13c8fSNan Zhou         ASSERT_EQ(certs.size(), maxNumAuthorityCertificates);
15626ec13c8fSNan Zhou         // Check attributes and alias
15636ec13c8fSNan Zhou         for (size_t i = 0; i < certs.size(); ++i)
15646ec13c8fSNan Zhou         {
15656ec13c8fSNan Zhou             std::string name = "root_" + std::to_string(i);
15666ec13c8fSNan Zhou             EXPECT_EQ(certs[i]->subject(), "O=openbmc-project.xyz,CN=" + name);
15676ec13c8fSNan Zhou             EXPECT_EQ(certs[i]->issuer(), "O=openbmc-project.xyz,CN=" + name);
15686ec13c8fSNan Zhou             std::string symbolLink =
15696ec13c8fSNan Zhou                 authoritiesListFolder /
15706ec13c8fSNan Zhou                 (certs[i]->getCertId().substr(0, 8) + ".0");
15716ec13c8fSNan Zhou             ASSERT_TRUE(fs::exists(symbolLink));
15726ec13c8fSNan Zhou             compareFileAgainstString(symbolLink, certs[i]->certificateString());
15736ec13c8fSNan Zhou         }
15746ec13c8fSNan Zhou     }
15756ec13c8fSNan Zhou 
15766ec13c8fSNan Zhou     // Expects that the content of |path| file is |buffer|.
compareFileAgainstString(const std::string & path,const std::string & buffer)15776ec13c8fSNan Zhou     static void compareFileAgainstString(const std::string& path,
15786ec13c8fSNan Zhou                                          const std::string& buffer)
15796ec13c8fSNan Zhou     {
15806ec13c8fSNan Zhou         ASSERT_NO_THROW({
15816ec13c8fSNan Zhou             std::ifstream inputCertFileStream;
15826ec13c8fSNan Zhou             inputCertFileStream.exceptions(std::ifstream::failbit |
15836ec13c8fSNan Zhou                                            std::ifstream::badbit |
15846ec13c8fSNan Zhou                                            std::ifstream::eofbit);
15856ec13c8fSNan Zhou             inputCertFileStream.open(path);
15866ec13c8fSNan Zhou             std::stringstream read;
15876ec13c8fSNan Zhou             read << inputCertFileStream.rdbuf();
15886ec13c8fSNan Zhou             inputCertFileStream.close();
15896ec13c8fSNan Zhou             EXPECT_EQ(read.str(), buffer);
15906ec13c8fSNan Zhou         });
15916ec13c8fSNan Zhou     };
15926ec13c8fSNan Zhou 
1593b3dbfb37SPatrick Williams     sdbusplus::bus_t bus;
15946ec13c8fSNan Zhou     fs::path authoritiesListFolder;
15956ec13c8fSNan Zhou     fs::path sourceAuthoritiesListFile;
15966ec13c8fSNan Zhou };
15976ec13c8fSNan Zhou 
15986ec13c8fSNan Zhou // Tests that the Authority Manager installs all the certificates in an
15996ec13c8fSNan Zhou // authorities list
TEST_F(AuthoritiesListTest,InstallAll)16006ec13c8fSNan Zhou TEST_F(AuthoritiesListTest, InstallAll)
16016ec13c8fSNan Zhou {
16022e8fa88eSMichal Orzel     std::string endpoint("truststore");
16036ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
1604e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
16056ec13c8fSNan Zhou 
16066ec13c8fSNan Zhou     std::string object = std::string(objectNamePrefix) + '/' +
16076ec13c8fSNan Zhou                          certificateTypeToString(type) + '/' + endpoint;
16086ec13c8fSNan Zhou     auto event = sdeventplus::Event::get_default();
16096ec13c8fSNan Zhou     // Attach the bus to sd_event to service user requests
16106ec13c8fSNan Zhou     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
16116ec13c8fSNan Zhou     ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
16126ec13c8fSNan Zhou                           authoritiesListFolder);
16136ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
16146ec13c8fSNan Zhou         .WillOnce(Return());
16156ec13c8fSNan Zhou     ASSERT_TRUE(manager.getCertificates().empty());
16166ec13c8fSNan Zhou 
16176ec13c8fSNan Zhou     std::vector<sdbusplus::message::object_path> objects =
16186ec13c8fSNan Zhou         manager.installAll(sourceAuthoritiesListFile);
16196ec13c8fSNan Zhou     for (size_t i = 0; i < manager.getCertificates().size(); ++i)
16206ec13c8fSNan Zhou     {
16216ec13c8fSNan Zhou         EXPECT_EQ(manager.getCertificates()[i]->getObjectPath(), objects[i]);
16226ec13c8fSNan Zhou     }
16236ec13c8fSNan Zhou     verifyCertificates(manager.getCertificates());
16246ec13c8fSNan Zhou }
16256ec13c8fSNan Zhou 
16266ec13c8fSNan Zhou // Tests that the Authority Manager recovers from the authorities list persisted
16276ec13c8fSNan Zhou // in the installation path at boot up
TEST_F(AuthoritiesListTest,RecoverAtBootUp)16286ec13c8fSNan Zhou TEST_F(AuthoritiesListTest, RecoverAtBootUp)
16296ec13c8fSNan Zhou {
16302e8fa88eSMichal Orzel     std::string endpoint("truststore");
16316ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
1632e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
16336ec13c8fSNan Zhou 
16346ec13c8fSNan Zhou     std::string object = std::string(objectNamePrefix) + '/' +
16356ec13c8fSNan Zhou                          certificateTypeToString(type) + '/' + endpoint;
16366ec13c8fSNan Zhou     auto event = sdeventplus::Event::get_default();
16376ec13c8fSNan Zhou     // Attach the bus to sd_event to service user requests
16386ec13c8fSNan Zhou     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
16396ec13c8fSNan Zhou 
16406ec13c8fSNan Zhou     // Copy the trust bundle into the installation path before creating an
16416ec13c8fSNan Zhou     // Authority Manager
16426ec13c8fSNan Zhou     fs::copy_file(/*from=*/sourceAuthoritiesListFile,
16436ec13c8fSNan Zhou                   authoritiesListFolder / defaultAuthoritiesListFileName);
16446ec13c8fSNan Zhou     // Create some noise as well
16456ec13c8fSNan Zhou     fs::copy_file(/*from=*/sourceAuthoritiesListFile,
16466ec13c8fSNan Zhou                   authoritiesListFolder / "should_be_deleted");
16476ec13c8fSNan Zhou 
16486ec13c8fSNan Zhou     ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
16496ec13c8fSNan Zhou                           authoritiesListFolder);
16506ec13c8fSNan Zhou 
16516ec13c8fSNan Zhou     ASSERT_EQ(manager.getCertificates().size(), maxNumAuthorityCertificates);
16526ec13c8fSNan Zhou 
16536ec13c8fSNan Zhou     // Check attributes and alias
16546ec13c8fSNan Zhou     std::unordered_set<std::string> expectedFiles = {authoritiesListFolder /
16556ec13c8fSNan Zhou                                                      "trust_bundle"};
16566ec13c8fSNan Zhou     std::vector<std::unique_ptr<Certificate>>& certs =
16576ec13c8fSNan Zhou         manager.getCertificates();
16586ec13c8fSNan Zhou     for (size_t i = 0; i < certs.size(); ++i)
16596ec13c8fSNan Zhou     {
16606ec13c8fSNan Zhou         std::string name = "root_" + std::to_string(i);
16616ec13c8fSNan Zhou         EXPECT_EQ(certs[i]->subject(), "O=openbmc-project.xyz,CN=" + name);
16626ec13c8fSNan Zhou         EXPECT_EQ(certs[i]->issuer(), "O=openbmc-project.xyz,CN=" + name);
1663223e4604SPatrick Williams         std::string symbolLink = authoritiesListFolder /
1664223e4604SPatrick Williams                                  (certs[i]->getCertId().substr(0, 8) + ".0");
16656ec13c8fSNan Zhou         expectedFiles.insert(symbolLink);
16666ec13c8fSNan Zhou         expectedFiles.insert(certs[i]->getCertFilePath());
16676ec13c8fSNan Zhou         ASSERT_TRUE(fs::exists(symbolLink));
16686ec13c8fSNan Zhou         compareFileAgainstString(symbolLink, certs[i]->certificateString());
16696ec13c8fSNan Zhou     }
16706ec13c8fSNan Zhou 
16716ec13c8fSNan Zhou     // Check folder content
16726ec13c8fSNan Zhou     for (auto& path : fs::directory_iterator(authoritiesListFolder))
16736ec13c8fSNan Zhou     {
16746ec13c8fSNan Zhou         EXPECT_NE(path, authoritiesListFolder / "should_be_deleted");
16756ec13c8fSNan Zhou         expectedFiles.erase(path.path());
16766ec13c8fSNan Zhou     }
16776ec13c8fSNan Zhou     EXPECT_TRUE(expectedFiles.empty());
16786ec13c8fSNan Zhou }
16796ec13c8fSNan Zhou 
TEST_F(AuthoritiesListTest,InstallAndDelete)16806ec13c8fSNan Zhou TEST_F(AuthoritiesListTest, InstallAndDelete)
16816ec13c8fSNan Zhou {
16822e8fa88eSMichal Orzel     std::string endpoint("truststore");
16836ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
1684e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
16856ec13c8fSNan Zhou 
16866ec13c8fSNan Zhou     std::string object = std::string(objectNamePrefix) + '/' +
16876ec13c8fSNan Zhou                          certificateTypeToString(type) + '/' + endpoint;
16886ec13c8fSNan Zhou 
16896ec13c8fSNan Zhou     auto event = sdeventplus::Event::get_default();
16906ec13c8fSNan Zhou     // Attach the bus to sd_event to service user requests
16916ec13c8fSNan Zhou     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
16926ec13c8fSNan Zhou     ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
16936ec13c8fSNan Zhou                           authoritiesListFolder);
16946ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
16956ec13c8fSNan Zhou         .WillOnce(Return())
16966ec13c8fSNan Zhou         .WillOnce(Return());
16976ec13c8fSNan Zhou     ASSERT_TRUE(manager.getCertificates().empty());
16986ec13c8fSNan Zhou     ASSERT_EQ(manager.installAll(sourceAuthoritiesListFile).size(),
16996ec13c8fSNan Zhou               maxNumAuthorityCertificates);
17006ec13c8fSNan Zhou     manager.deleteAll();
17016ec13c8fSNan Zhou     EXPECT_TRUE(manager.getCertificates().empty());
17026ec13c8fSNan Zhou     // Check folder content
17036ec13c8fSNan Zhou     for (const fs::path& f : fs::directory_iterator(authoritiesListFolder))
17046ec13c8fSNan Zhou     {
17056ec13c8fSNan Zhou         EXPECT_THAT(f.filename(), testing::AnyOf(".", ".."));
17066ec13c8fSNan Zhou     }
17076ec13c8fSNan Zhou }
17086ec13c8fSNan Zhou 
TEST_F(AuthoritiesListTest,InstallAllWrongManagerType)17096ec13c8fSNan Zhou TEST_F(AuthoritiesListTest, InstallAllWrongManagerType)
17106ec13c8fSNan Zhou {
17116ec13c8fSNan Zhou     std::string endpoint("ldap");
1712e3d47cd4SNan Zhou     CertificateType type = CertificateType::server;
17136ec13c8fSNan Zhou 
17146ec13c8fSNan Zhou     std::string object = std::string(objectNamePrefix) + '/' +
17156ec13c8fSNan Zhou                          certificateTypeToString(type) + '/' + endpoint;
17166ec13c8fSNan Zhou 
17176ec13c8fSNan Zhou     auto event = sdeventplus::Event::get_default();
17186ec13c8fSNan Zhou     // Attach the bus to sd_event to service user requests
17196ec13c8fSNan Zhou     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
17206ec13c8fSNan Zhou     ManagerInTest serverManager(bus, event, object.c_str(), type, "",
17216ec13c8fSNan Zhou                                 authoritiesListFolder);
17226ec13c8fSNan Zhou     EXPECT_THROW(serverManager.installAll(sourceAuthoritiesListFile),
17236ec13c8fSNan Zhou                  sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed);
17246ec13c8fSNan Zhou 
1725e3d47cd4SNan Zhou     type = CertificateType::client;
17266ec13c8fSNan Zhou     object = std::string(objectNamePrefix) + '/' +
17276ec13c8fSNan Zhou              certificateTypeToString(type) + '/' + endpoint;
17286ec13c8fSNan Zhou     ManagerInTest clientManager(bus, event, object.c_str(), type, "",
17296ec13c8fSNan Zhou                                 authoritiesListFolder);
17306ec13c8fSNan Zhou     EXPECT_THROW(clientManager.installAll(sourceAuthoritiesListFile),
17316ec13c8fSNan Zhou                  sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed);
17326ec13c8fSNan Zhou }
17336ec13c8fSNan Zhou 
TEST_F(AuthoritiesListTest,InstallAllTwice)17346ec13c8fSNan Zhou TEST_F(AuthoritiesListTest, InstallAllTwice)
17356ec13c8fSNan Zhou {
17362e8fa88eSMichal Orzel     std::string endpoint("truststore");
17376ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
1738e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
17396ec13c8fSNan Zhou 
17406ec13c8fSNan Zhou     std::string object = std::string(objectNamePrefix) + '/' +
17416ec13c8fSNan Zhou                          certificateTypeToString(type) + '/' + endpoint;
17426ec13c8fSNan Zhou 
17436ec13c8fSNan Zhou     auto event = sdeventplus::Event::get_default();
17446ec13c8fSNan Zhou     // Attach the bus to sd_event to service user requests
17456ec13c8fSNan Zhou     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
17466ec13c8fSNan Zhou     ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
17476ec13c8fSNan Zhou                           authoritiesListFolder);
17486ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
17496ec13c8fSNan Zhou         .WillOnce(Return());
17506ec13c8fSNan Zhou     ASSERT_TRUE(manager.getCertificates().empty());
17516ec13c8fSNan Zhou 
17526ec13c8fSNan Zhou     ASSERT_EQ(manager.installAll(sourceAuthoritiesListFile).size(),
17536ec13c8fSNan Zhou               maxNumAuthorityCertificates);
175456bfa731SNan Zhou     EXPECT_THROW(manager.installAll(sourceAuthoritiesListFile),
17556ec13c8fSNan Zhou                  sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed);
17566ec13c8fSNan Zhou }
17576ec13c8fSNan Zhou 
TEST_F(AuthoritiesListTest,InstallAllMissSourceFile)17586ec13c8fSNan Zhou TEST_F(AuthoritiesListTest, InstallAllMissSourceFile)
17596ec13c8fSNan Zhou {
17602e8fa88eSMichal Orzel     std::string endpoint("truststore");
17616ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
1762e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
17636ec13c8fSNan Zhou 
17646ec13c8fSNan Zhou     std::string object = std::string(objectNamePrefix) + '/' +
17656ec13c8fSNan Zhou                          certificateTypeToString(type) + '/' + endpoint;
17666ec13c8fSNan Zhou 
17676ec13c8fSNan Zhou     auto event = sdeventplus::Event::get_default();
17686ec13c8fSNan Zhou     // Attach the bus to sd_event to service user requests
17696ec13c8fSNan Zhou     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
17706ec13c8fSNan Zhou     ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
17716ec13c8fSNan Zhou                           authoritiesListFolder);
17726ec13c8fSNan Zhou 
17736ec13c8fSNan Zhou     EXPECT_THROW(manager.installAll(authoritiesListFolder / "trust_bundle"),
17746ec13c8fSNan Zhou                  InternalFailure);
17756ec13c8fSNan Zhou }
17766ec13c8fSNan Zhou 
TEST_F(AuthoritiesListTest,TooManyRootCertificates)17776ec13c8fSNan Zhou TEST_F(AuthoritiesListTest, TooManyRootCertificates)
17786ec13c8fSNan Zhou {
17792e8fa88eSMichal Orzel     std::string endpoint("truststore");
17806ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
1781e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
17826ec13c8fSNan Zhou 
17836ec13c8fSNan Zhou     std::string object = std::string(objectNamePrefix) + '/' +
17846ec13c8fSNan Zhou                          certificateTypeToString(type) + '/' + endpoint;
17856ec13c8fSNan Zhou 
17866ec13c8fSNan Zhou     auto event = sdeventplus::Event::get_default();
17876ec13c8fSNan Zhou     // Attach the bus to sd_event to service user requests
17886ec13c8fSNan Zhou     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
17896ec13c8fSNan Zhou     ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
17906ec13c8fSNan Zhou                           authoritiesListFolder);
17916ec13c8fSNan Zhou     createAuthoritiesList(maxNumAuthorityCertificates + 1);
17926ec13c8fSNan Zhou     EXPECT_THROW(manager.installAll(sourceAuthoritiesListFile),
17936ec13c8fSNan Zhou                  sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed);
17946ec13c8fSNan Zhou }
17956ec13c8fSNan Zhou 
TEST_F(AuthoritiesListTest,CertInWrongFormat)17966ec13c8fSNan Zhou TEST_F(AuthoritiesListTest, CertInWrongFormat)
17976ec13c8fSNan Zhou {
17982e8fa88eSMichal Orzel     std::string endpoint("truststore");
17996ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
1800e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
18016ec13c8fSNan Zhou 
18026ec13c8fSNan Zhou     std::string object = std::string(objectNamePrefix) + '/' +
18036ec13c8fSNan Zhou                          certificateTypeToString(type) + '/' + endpoint;
18046ec13c8fSNan Zhou 
18056ec13c8fSNan Zhou     auto event = sdeventplus::Event::get_default();
18066ec13c8fSNan Zhou     // Attach the bus to sd_event to service user requests
18076ec13c8fSNan Zhou     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
18086ec13c8fSNan Zhou 
18096ec13c8fSNan Zhou     ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
18106ec13c8fSNan Zhou                           authoritiesListFolder);
18116ec13c8fSNan Zhou 
18126ec13c8fSNan Zhou     // Replace the authorities list with non-valid PEM encoded x509 certificate
18136ec13c8fSNan Zhou     setContentFromString(sourceAuthoritiesListFile, "blah-blah");
18146ec13c8fSNan Zhou     EXPECT_THROW(manager.installAll(sourceAuthoritiesListFile),
18156ec13c8fSNan Zhou                  InvalidCertificate);
18166ec13c8fSNan Zhou     setContentFromString(sourceAuthoritiesListFile,
18176ec13c8fSNan Zhou                          "-----BEGIN CERTIFICATE-----");
18186ec13c8fSNan Zhou     EXPECT_THROW(manager.installAll(sourceAuthoritiesListFile),
18196ec13c8fSNan Zhou                  InvalidCertificate);
18206ec13c8fSNan Zhou }
18216ec13c8fSNan Zhou 
TEST_F(AuthoritiesListTest,ReplaceAll)18226ec13c8fSNan Zhou TEST_F(AuthoritiesListTest, ReplaceAll)
18236ec13c8fSNan Zhou {
18242e8fa88eSMichal Orzel     std::string endpoint("truststore");
18256ec13c8fSNan Zhou     std::string verifyUnit(ManagerInTest::unitToRestartInTest);
1826e3d47cd4SNan Zhou     CertificateType type = CertificateType::authority;
18276ec13c8fSNan Zhou 
18286ec13c8fSNan Zhou     std::string object = std::string(objectNamePrefix) + '/' +
18296ec13c8fSNan Zhou                          certificateTypeToString(type) + '/' + endpoint;
18306ec13c8fSNan Zhou 
18316ec13c8fSNan Zhou     auto event = sdeventplus::Event::get_default();
18326ec13c8fSNan Zhou     // Attach the bus to sd_event to service user requests
18336ec13c8fSNan Zhou     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
18346ec13c8fSNan Zhou     ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
18356ec13c8fSNan Zhou                           authoritiesListFolder);
18366ec13c8fSNan Zhou     EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
18376ec13c8fSNan Zhou         .WillOnce(Return())
18386ec13c8fSNan Zhou         .WillOnce(Return());
18396ec13c8fSNan Zhou     manager.installAll(sourceAuthoritiesListFile);
18406ec13c8fSNan Zhou 
18416ec13c8fSNan Zhou     // Replace the current list with a different list
18426ec13c8fSNan Zhou     fs::remove_all(sourceAuthoritiesListFile.parent_path());
18436ec13c8fSNan Zhou     createAuthoritiesList(maxNumAuthorityCertificates);
18446ec13c8fSNan Zhou     std::vector<sdbusplus::message::object_path> objects =
18456ec13c8fSNan Zhou         manager.replaceAll(sourceAuthoritiesListFile);
18466ec13c8fSNan Zhou 
18476ec13c8fSNan Zhou     for (size_t i = 0; i < manager.getCertificates().size(); ++i)
18486ec13c8fSNan Zhou     {
18496ec13c8fSNan Zhou         EXPECT_EQ(manager.getCertificates()[i]->getObjectPath(), objects[i]);
18506ec13c8fSNan Zhou     }
18516ec13c8fSNan Zhou     verifyCertificates(manager.getCertificates());
18526ec13c8fSNan Zhou }
18536ec13c8fSNan Zhou 
1854e1289adfSNan Zhou } // namespace
1855e1289adfSNan Zhou } // namespace phosphor::certs
1856