1947258dcSMarri Devender Rao #include "certs_manager.hpp"
2947258dcSMarri Devender Rao 
3947258dcSMarri Devender Rao #include <algorithm>
4947258dcSMarri Devender Rao #include <experimental/filesystem>
5947258dcSMarri Devender Rao #include <fstream>
6947258dcSMarri Devender Rao #include <iterator>
7947258dcSMarri Devender Rao #include <string>
8947258dcSMarri Devender Rao #include <xyz/openbmc_project/Certs/Install/error.hpp>
9947258dcSMarri Devender Rao #include <xyz/openbmc_project/Common/error.hpp>
10947258dcSMarri Devender Rao 
11947258dcSMarri Devender Rao #include <gmock/gmock.h>
12947258dcSMarri Devender Rao #include <gtest/gtest.h>
13947258dcSMarri Devender Rao 
14947258dcSMarri Devender Rao namespace fs = std::experimental::filesystem;
15947258dcSMarri Devender Rao static constexpr auto BUSNAME = "xyz.openbmc_project.Certs.Manager";
16947258dcSMarri Devender Rao static constexpr auto OBJPATH = "/xyz/openbmc_project/certs";
17947258dcSMarri Devender Rao using InternalFailure =
18947258dcSMarri Devender Rao     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
19947258dcSMarri Devender Rao 
20e6597c5bSMarri Devender Rao using InvalidCertificate =
21e6597c5bSMarri Devender Rao     sdbusplus::xyz::openbmc_project::Certs::Install::Error::InvalidCertificate;
22e6597c5bSMarri Devender Rao 
23ddf64866SMarri Devender Rao /**
24ddf64866SMarri Devender Rao  * Class to generate certificate file and test verification of certificate file
25ddf64866SMarri Devender Rao  */
26947258dcSMarri Devender Rao class TestCertsManager : public ::testing::Test
27947258dcSMarri Devender Rao {
28947258dcSMarri Devender Rao   public:
29947258dcSMarri Devender Rao     TestCertsManager() : bus(sdbusplus::bus::new_default())
30947258dcSMarri Devender Rao     {
31947258dcSMarri Devender Rao     }
32947258dcSMarri Devender Rao     void SetUp() override
33947258dcSMarri Devender Rao     {
34947258dcSMarri Devender Rao         char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
35947258dcSMarri Devender Rao         auto dirPtr = mkdtemp(dirTemplate);
36947258dcSMarri Devender Rao         if (dirPtr == NULL)
37947258dcSMarri Devender Rao         {
38947258dcSMarri Devender Rao             throw std::bad_alloc();
39947258dcSMarri Devender Rao         }
40947258dcSMarri Devender Rao         certDir = dirPtr;
41947258dcSMarri Devender Rao         certificateFile = "cert.pem";
42947258dcSMarri Devender Rao         std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
43947258dcSMarri Devender Rao         cmd += "-keyout cert.pem -out cert.pem -days 3650 ";
44947258dcSMarri Devender Rao         cmd += "-subj "
45947258dcSMarri Devender Rao                "/O=openbmc-project.xyz/CN=localhost"
46947258dcSMarri Devender Rao                " -nodes";
47947258dcSMarri Devender Rao         auto val = std::system(cmd.c_str());
48947258dcSMarri Devender Rao         if (val)
49947258dcSMarri Devender Rao         {
50947258dcSMarri Devender Rao             std::cout << "COMMAND Error: " << val << std::endl;
51947258dcSMarri Devender Rao         }
52947258dcSMarri Devender Rao     }
53947258dcSMarri Devender Rao     void TearDown() override
54947258dcSMarri Devender Rao     {
55947258dcSMarri Devender Rao         fs::remove_all(certDir);
56947258dcSMarri Devender Rao         fs::remove(certificateFile);
57947258dcSMarri Devender Rao     }
58947258dcSMarri Devender Rao 
59947258dcSMarri Devender Rao     bool compareFiles(const std::string& file1, const std::string& file2)
60947258dcSMarri Devender Rao     {
61947258dcSMarri Devender Rao         std::ifstream f1(file1, std::ifstream::binary | std::ifstream::ate);
62947258dcSMarri Devender Rao         std::ifstream f2(file2, std::ifstream::binary | std::ifstream::ate);
63947258dcSMarri Devender Rao 
64947258dcSMarri Devender Rao         if (f1.fail() || f2.fail())
65947258dcSMarri Devender Rao         {
66947258dcSMarri Devender Rao             return false; // file problem
67947258dcSMarri Devender Rao         }
68947258dcSMarri Devender Rao 
69947258dcSMarri Devender Rao         if (f1.tellg() != f2.tellg())
70947258dcSMarri Devender Rao         {
71947258dcSMarri Devender Rao             return false; // size mismatch
72947258dcSMarri Devender Rao         }
73947258dcSMarri Devender Rao 
74947258dcSMarri Devender Rao         // seek back to beginning and use std::equal to compare contents
75947258dcSMarri Devender Rao         f1.seekg(0, std::ifstream::beg);
76947258dcSMarri Devender Rao         f2.seekg(0, std::ifstream::beg);
77947258dcSMarri Devender Rao         return std::equal(std::istreambuf_iterator<char>(f1.rdbuf()),
78947258dcSMarri Devender Rao                           std::istreambuf_iterator<char>(),
79947258dcSMarri Devender Rao                           std::istreambuf_iterator<char>(f2.rdbuf()));
80947258dcSMarri Devender Rao     }
81947258dcSMarri Devender Rao 
82947258dcSMarri Devender Rao   protected:
83947258dcSMarri Devender Rao     sdbusplus::bus::bus bus;
84947258dcSMarri Devender Rao     std::string certificateFile;
85947258dcSMarri Devender Rao 
86947258dcSMarri Devender Rao     std::string certDir;
87947258dcSMarri Devender Rao };
88947258dcSMarri Devender Rao 
89947258dcSMarri Devender Rao class MainApp
90947258dcSMarri Devender Rao {
91947258dcSMarri Devender Rao   public:
92947258dcSMarri Devender Rao     MainApp(phosphor::certs::Manager* manager) : manager(manager)
93947258dcSMarri Devender Rao     {
94947258dcSMarri Devender Rao     }
95947258dcSMarri Devender Rao     void install(std::string& path)
96947258dcSMarri Devender Rao     {
97947258dcSMarri Devender Rao         manager->install(path);
98947258dcSMarri Devender Rao     }
999abfae88SMarri Devender Rao     void delete_()
1009abfae88SMarri Devender Rao     {
1019abfae88SMarri Devender Rao         manager->delete_();
1029abfae88SMarri Devender Rao     }
103947258dcSMarri Devender Rao     phosphor::certs::Manager* manager;
104947258dcSMarri Devender Rao };
105947258dcSMarri Devender Rao 
106947258dcSMarri Devender Rao class MockCertManager : public phosphor::certs::Manager
107947258dcSMarri Devender Rao {
108947258dcSMarri Devender Rao   public:
109947258dcSMarri Devender Rao     MockCertManager(sdbusplus::bus::bus& bus, const char* path,
110947258dcSMarri Devender Rao                     std::string& type, std::string&& unit,
111947258dcSMarri Devender Rao                     std::string&& certPath) :
112947258dcSMarri Devender Rao         Manager(bus, path, type, std::forward<std::string>(unit),
113947258dcSMarri Devender Rao                 std::forward<std::string>(certPath))
114947258dcSMarri Devender Rao     {
115947258dcSMarri Devender Rao     }
116947258dcSMarri Devender Rao     virtual ~MockCertManager()
117947258dcSMarri Devender Rao     {
118947258dcSMarri Devender Rao     }
119947258dcSMarri Devender Rao 
120*b50789ceSJayanth Othayoth     MOCK_METHOD1(reloadOrReset, void(const std::string& unit));
121947258dcSMarri Devender Rao };
122947258dcSMarri Devender Rao 
123947258dcSMarri Devender Rao /** @brief Check if server install routine is invoked for server setup
124947258dcSMarri Devender Rao  */
125947258dcSMarri Devender Rao TEST_F(TestCertsManager, InvokeServerInstall)
126947258dcSMarri Devender Rao {
127947258dcSMarri Devender Rao     std::string endpoint("https");
128947258dcSMarri Devender Rao     std::string unit("nginx.service");
129947258dcSMarri Devender Rao     std::string type("server");
130947258dcSMarri Devender Rao     std::string path(certDir + "/" + certificateFile);
131947258dcSMarri Devender Rao     std::string verifyPath(path);
132*b50789ceSJayanth Othayoth     std::string verifyUnit(unit);
133947258dcSMarri Devender Rao     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
134947258dcSMarri Devender Rao     MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
135947258dcSMarri Devender Rao                             std::move(path));
136*b50789ceSJayanth Othayoth     EXPECT_CALL(manager, reloadOrReset(verifyUnit)).Times(1);
137947258dcSMarri Devender Rao 
138947258dcSMarri Devender Rao     MainApp mainApp(&manager);
139947258dcSMarri Devender Rao     EXPECT_NO_THROW({ mainApp.install(certificateFile); });
140947258dcSMarri Devender Rao     EXPECT_TRUE(fs::exists(verifyPath));
141947258dcSMarri Devender Rao }
142947258dcSMarri Devender Rao 
143947258dcSMarri Devender Rao /** @brief Check if client install routine is invoked for client setup
144947258dcSMarri Devender Rao  */
145947258dcSMarri Devender Rao TEST_F(TestCertsManager, InvokeClientInstall)
146947258dcSMarri Devender Rao {
147947258dcSMarri Devender Rao     std::string endpoint("ldap");
148947258dcSMarri Devender Rao     std::string unit("nslcd.service");
149947258dcSMarri Devender Rao     std::string type("client");
150947258dcSMarri Devender Rao     std::string path(certDir + "/" + certificateFile);
151947258dcSMarri Devender Rao     std::string verifyPath(path);
152*b50789ceSJayanth Othayoth     std::string verifyUnit(unit);
153947258dcSMarri Devender Rao     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
154947258dcSMarri Devender Rao     MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
155947258dcSMarri Devender Rao                             std::move(path));
156*b50789ceSJayanth Othayoth     EXPECT_CALL(manager, reloadOrReset(verifyUnit)).Times(1);
157*b50789ceSJayanth Othayoth     MainApp mainApp(&manager);
158*b50789ceSJayanth Othayoth     EXPECT_NO_THROW({ mainApp.install(certificateFile); });
159*b50789ceSJayanth Othayoth     EXPECT_TRUE(fs::exists(verifyPath));
160*b50789ceSJayanth Othayoth }
161*b50789ceSJayanth Othayoth 
162*b50789ceSJayanth Othayoth /** @brief Check if authority install routine is invoked for authority setup
163*b50789ceSJayanth Othayoth  */
164*b50789ceSJayanth Othayoth TEST_F(TestCertsManager, InvokeAuthorityInstall)
165*b50789ceSJayanth Othayoth {
166*b50789ceSJayanth Othayoth     std::string endpoint("ldap");
167*b50789ceSJayanth Othayoth     std::string unit("nslcd.service");
168*b50789ceSJayanth Othayoth     std::string type("authority");
169*b50789ceSJayanth Othayoth     std::string path(certDir + "/" + certificateFile);
170*b50789ceSJayanth Othayoth     std::string verifyPath(path);
171*b50789ceSJayanth Othayoth     std::string verifyUnit(unit);
172*b50789ceSJayanth Othayoth     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
173*b50789ceSJayanth Othayoth     MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
174*b50789ceSJayanth Othayoth                             std::move(path));
175*b50789ceSJayanth Othayoth     EXPECT_CALL(manager, reloadOrReset(verifyUnit)).Times(1);
176*b50789ceSJayanth Othayoth 
177947258dcSMarri Devender Rao     MainApp mainApp(&manager);
178947258dcSMarri Devender Rao     EXPECT_NO_THROW({ mainApp.install(certificateFile); });
179947258dcSMarri Devender Rao     EXPECT_TRUE(fs::exists(verifyPath));
180947258dcSMarri Devender Rao }
181947258dcSMarri Devender Rao 
182947258dcSMarri Devender Rao /** @brief Compare the installed certificate with the copied certificate
183947258dcSMarri Devender Rao  */
184947258dcSMarri Devender Rao TEST_F(TestCertsManager, CompareInstalledCertificate)
185947258dcSMarri Devender Rao {
186947258dcSMarri Devender Rao     std::string endpoint("ldap");
187947258dcSMarri Devender Rao     std::string unit("nslcd.service");
188947258dcSMarri Devender Rao     std::string type("client");
189947258dcSMarri Devender Rao     std::string path(certDir + "/" + certificateFile);
190947258dcSMarri Devender Rao     std::string verifyPath(path);
191*b50789ceSJayanth Othayoth     std::string verifyUnit(unit);
192947258dcSMarri Devender Rao     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
193947258dcSMarri Devender Rao     MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
194947258dcSMarri Devender Rao                             std::move(path));
195*b50789ceSJayanth Othayoth     EXPECT_CALL(manager, reloadOrReset(verifyUnit)).Times(1);
196947258dcSMarri Devender Rao     MainApp mainApp(&manager);
197947258dcSMarri Devender Rao     EXPECT_NO_THROW({ mainApp.install(certificateFile); });
198947258dcSMarri Devender Rao     EXPECT_TRUE(fs::exists(verifyPath));
199947258dcSMarri Devender Rao     EXPECT_TRUE(compareFiles(verifyPath, certificateFile));
200947258dcSMarri Devender Rao }
201e6597c5bSMarri Devender Rao 
202e6597c5bSMarri Devender Rao /** @brief Check if install fails if certificate file is not found
203e6597c5bSMarri Devender Rao  */
204e6597c5bSMarri Devender Rao TEST_F(TestCertsManager, TestNoCertificateFile)
205e6597c5bSMarri Devender Rao {
206e6597c5bSMarri Devender Rao     std::string endpoint("ldap");
207e6597c5bSMarri Devender Rao     std::string unit("nslcd.service");
208e6597c5bSMarri Devender Rao     std::string type("client");
209e6597c5bSMarri Devender Rao     std::string path(certDir + "/" + certificateFile);
210e6597c5bSMarri Devender Rao     std::string verifyPath(path);
211*b50789ceSJayanth Othayoth     std::string verifyUnit(unit);
212e6597c5bSMarri Devender Rao     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
213e6597c5bSMarri Devender Rao     MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
214e6597c5bSMarri Devender Rao                             std::move(path));
215*b50789ceSJayanth Othayoth     EXPECT_CALL(manager, reloadOrReset(verifyUnit)).Times(0);
216e6597c5bSMarri Devender Rao     MainApp mainApp(&manager);
217e6597c5bSMarri Devender Rao     std::string certpath = "nofile.pem";
218e6597c5bSMarri Devender Rao     EXPECT_THROW(
219e6597c5bSMarri Devender Rao         {
220e6597c5bSMarri Devender Rao             try
221e6597c5bSMarri Devender Rao             {
222e6597c5bSMarri Devender Rao                 mainApp.install(certpath);
223e6597c5bSMarri Devender Rao             }
224e6597c5bSMarri Devender Rao             catch (const InternalFailure& e)
225e6597c5bSMarri Devender Rao             {
226e6597c5bSMarri Devender Rao                 throw;
227e6597c5bSMarri Devender Rao             }
228e6597c5bSMarri Devender Rao         },
229e6597c5bSMarri Devender Rao         InternalFailure);
230e6597c5bSMarri Devender Rao     EXPECT_FALSE(fs::exists(verifyPath));
231e6597c5bSMarri Devender Rao }
232e6597c5bSMarri Devender Rao 
233e6597c5bSMarri Devender Rao /** @brief Check if install fails if certificate file is empty
234e6597c5bSMarri Devender Rao  */
235e6597c5bSMarri Devender Rao TEST_F(TestCertsManager, TestEmptyCertificateFile)
236e6597c5bSMarri Devender Rao {
237e6597c5bSMarri Devender Rao     std::string endpoint("ldap");
238e6597c5bSMarri Devender Rao     std::string unit("nslcd.service");
239e6597c5bSMarri Devender Rao     std::string type("client");
240e6597c5bSMarri Devender Rao 
241ddf64866SMarri Devender Rao     std::string emptyFile("emptycert.pem");
242e6597c5bSMarri Devender Rao     std::ofstream ofs;
243e6597c5bSMarri Devender Rao     ofs.open(emptyFile, std::ofstream::out);
244e6597c5bSMarri Devender Rao     ofs.close();
245e6597c5bSMarri Devender Rao 
246e6597c5bSMarri Devender Rao     std::string path(certDir + "/" + emptyFile);
247e6597c5bSMarri Devender Rao     std::string verifyPath(path);
248*b50789ceSJayanth Othayoth     std::string verifyUnit(unit);
249e6597c5bSMarri Devender Rao     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
250e6597c5bSMarri Devender Rao     MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
251e6597c5bSMarri Devender Rao                             std::move(path));
252*b50789ceSJayanth Othayoth     EXPECT_CALL(manager, reloadOrReset(verifyUnit)).Times(0);
253e6597c5bSMarri Devender Rao     MainApp mainApp(&manager);
254e6597c5bSMarri Devender Rao     EXPECT_THROW(
255e6597c5bSMarri Devender Rao         {
256e6597c5bSMarri Devender Rao             try
257e6597c5bSMarri Devender Rao             {
258e6597c5bSMarri Devender Rao                 mainApp.install(emptyFile);
259e6597c5bSMarri Devender Rao             }
260e6597c5bSMarri Devender Rao             catch (const InvalidCertificate& e)
261e6597c5bSMarri Devender Rao             {
262e6597c5bSMarri Devender Rao                 throw;
263e6597c5bSMarri Devender Rao             }
264e6597c5bSMarri Devender Rao         },
265e6597c5bSMarri Devender Rao         InvalidCertificate);
266e6597c5bSMarri Devender Rao     EXPECT_FALSE(fs::exists(verifyPath));
267e6597c5bSMarri Devender Rao     fs::remove(emptyFile);
268e6597c5bSMarri Devender Rao }
269e6597c5bSMarri Devender Rao 
270ddf64866SMarri Devender Rao /** @brief Check if install fails if certificate file is corrupted
271e6597c5bSMarri Devender Rao  */
272e6597c5bSMarri Devender Rao TEST_F(TestCertsManager, TestInvalidCertificateFile)
273e6597c5bSMarri Devender Rao {
274e6597c5bSMarri Devender Rao     std::string endpoint("ldap");
275e6597c5bSMarri Devender Rao     std::string unit("nslcd.service");
276e6597c5bSMarri Devender Rao     std::string type("client");
277e6597c5bSMarri Devender Rao 
278e6597c5bSMarri Devender Rao     std::ofstream ofs;
279ddf64866SMarri Devender Rao     ofs.open(certificateFile, std::ofstream::out);
280ddf64866SMarri Devender Rao     ofs << "-----BEGIN CERTIFICATE-----";
281ddf64866SMarri Devender Rao     ofs << "ADD_SOME_INVALID_DATA_INTO_FILE";
282ddf64866SMarri Devender Rao     ofs << "-----END CERTIFICATE-----";
283e6597c5bSMarri Devender Rao     ofs.close();
284e6597c5bSMarri Devender Rao 
285ddf64866SMarri Devender Rao     std::string path(certDir + "/" + certificateFile);
286e6597c5bSMarri Devender Rao     std::string verifyPath(path);
287*b50789ceSJayanth Othayoth     std::string verifyUnit(unit);
288e6597c5bSMarri Devender Rao     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
289e6597c5bSMarri Devender Rao     MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
290e6597c5bSMarri Devender Rao                             std::move(path));
291*b50789ceSJayanth Othayoth     EXPECT_CALL(manager, reloadOrReset(verifyUnit)).Times(0);
292e6597c5bSMarri Devender Rao     MainApp mainApp(&manager);
293e6597c5bSMarri Devender Rao     EXPECT_THROW(
294e6597c5bSMarri Devender Rao         {
295e6597c5bSMarri Devender Rao             try
296e6597c5bSMarri Devender Rao             {
297ddf64866SMarri Devender Rao                 mainApp.install(certificateFile);
298e6597c5bSMarri Devender Rao             }
299e6597c5bSMarri Devender Rao             catch (const InvalidCertificate& e)
300e6597c5bSMarri Devender Rao             {
301e6597c5bSMarri Devender Rao                 throw;
302e6597c5bSMarri Devender Rao             }
303e6597c5bSMarri Devender Rao         },
304e6597c5bSMarri Devender Rao         InvalidCertificate);
305e6597c5bSMarri Devender Rao     EXPECT_FALSE(fs::exists(verifyPath));
306ddf64866SMarri Devender Rao }
307ddf64866SMarri Devender Rao 
3089abfae88SMarri Devender Rao TEST_F(TestCertsManager, TestDeleteCertificate)
3099abfae88SMarri Devender Rao {
3109abfae88SMarri Devender Rao     std::string endpoint("ldap");
3119abfae88SMarri Devender Rao     std::string unit("nslcd.service");
3129abfae88SMarri Devender Rao     std::string type("client");
3139abfae88SMarri Devender Rao     std::string path(certDir + "/" + certificateFile);
3149abfae88SMarri Devender Rao     std::string verifyPath(path);
3159abfae88SMarri Devender Rao     std::string verifyUnit(unit);
3169abfae88SMarri Devender Rao     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
317*b50789ceSJayanth Othayoth     MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
3189abfae88SMarri Devender Rao                             std::move(path));
3199abfae88SMarri Devender Rao     EXPECT_CALL(manager, reloadOrReset(verifyUnit)).Times(2);
3209abfae88SMarri Devender Rao     MainApp mainApp(&manager);
3219abfae88SMarri Devender Rao     EXPECT_NO_THROW({ mainApp.install(certificateFile); });
3229abfae88SMarri Devender Rao     EXPECT_TRUE(fs::exists(verifyPath));
3239abfae88SMarri Devender Rao 
3249abfae88SMarri Devender Rao     // delete certificate file and verify file is deleted
3259abfae88SMarri Devender Rao     mainApp.delete_();
3269abfae88SMarri Devender Rao     EXPECT_FALSE(fs::exists(verifyPath));
3279abfae88SMarri Devender Rao }
3289abfae88SMarri Devender Rao 
329ddf64866SMarri Devender Rao /**
330ddf64866SMarri Devender Rao  * Class to generate private and certificate only file and test verification
331ddf64866SMarri Devender Rao  */
332ddf64866SMarri Devender Rao class TestInvalidCertsManager : public ::testing::Test
333ddf64866SMarri Devender Rao {
334ddf64866SMarri Devender Rao   public:
335ddf64866SMarri Devender Rao     TestInvalidCertsManager() : bus(sdbusplus::bus::new_default())
336ddf64866SMarri Devender Rao     {
337ddf64866SMarri Devender Rao     }
338ddf64866SMarri Devender Rao     void SetUp() override
339ddf64866SMarri Devender Rao     {
340ddf64866SMarri Devender Rao         char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
341ddf64866SMarri Devender Rao         auto dirPtr = mkdtemp(dirTemplate);
342ddf64866SMarri Devender Rao         if (dirPtr == NULL)
343ddf64866SMarri Devender Rao         {
344ddf64866SMarri Devender Rao             throw std::bad_alloc();
345ddf64866SMarri Devender Rao         }
346ddf64866SMarri Devender Rao         certDir = dirPtr;
347ddf64866SMarri Devender Rao         certificateFile = "cert.pem";
348ddf64866SMarri Devender Rao         keyFile = "key.pem";
349ddf64866SMarri Devender Rao         std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
350ddf64866SMarri Devender Rao         cmd += "-keyout key.pem -out cert.pem -days 3650 ";
351ddf64866SMarri Devender Rao         cmd += "-subj "
352ddf64866SMarri Devender Rao                "/O=openbmc-project.xyz/CN=localhost"
353ddf64866SMarri Devender Rao                " -nodes";
354ddf64866SMarri Devender Rao 
355ddf64866SMarri Devender Rao         auto val = std::system(cmd.c_str());
356ddf64866SMarri Devender Rao         if (val)
357ddf64866SMarri Devender Rao         {
358ddf64866SMarri Devender Rao             std::cout << "command Error: " << val << std::endl;
359ddf64866SMarri Devender Rao         }
360ddf64866SMarri Devender Rao     }
361ddf64866SMarri Devender Rao     void TearDown() override
362ddf64866SMarri Devender Rao     {
363ddf64866SMarri Devender Rao         fs::remove_all(certDir);
364ddf64866SMarri Devender Rao         fs::remove(certificateFile);
365ddf64866SMarri Devender Rao         fs::remove(keyFile);
366ddf64866SMarri Devender Rao     }
367ddf64866SMarri Devender Rao 
368ddf64866SMarri Devender Rao   protected:
369ddf64866SMarri Devender Rao     sdbusplus::bus::bus bus;
370ddf64866SMarri Devender Rao     std::string certificateFile;
371ddf64866SMarri Devender Rao     std::string keyFile;
372ddf64866SMarri Devender Rao     std::string certDir;
373ddf64866SMarri Devender Rao };
374ddf64866SMarri Devender Rao 
375ddf64866SMarri Devender Rao /** @brief Check install fails if private key is missing in certificate file
376ddf64866SMarri Devender Rao  */
377ddf64866SMarri Devender Rao TEST_F(TestInvalidCertsManager, TestMissingPrivateKey)
378ddf64866SMarri Devender Rao {
379ddf64866SMarri Devender Rao     std::string endpoint("ldap");
380ddf64866SMarri Devender Rao     std::string unit("nslcd.service");
381ddf64866SMarri Devender Rao     std::string type("client");
382ddf64866SMarri Devender Rao     std::string path(certDir + "/" + certificateFile);
383ddf64866SMarri Devender Rao     std::string verifyPath(path);
384*b50789ceSJayanth Othayoth     std::string verifyUnit(unit);
385ddf64866SMarri Devender Rao     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
386ddf64866SMarri Devender Rao     MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
387ddf64866SMarri Devender Rao                             std::move(path));
388*b50789ceSJayanth Othayoth     EXPECT_CALL(manager, reloadOrReset(verifyUnit)).Times(0);
389ddf64866SMarri Devender Rao     MainApp mainApp(&manager);
390ddf64866SMarri Devender Rao     EXPECT_THROW(
391ddf64866SMarri Devender Rao         {
392ddf64866SMarri Devender Rao             try
393ddf64866SMarri Devender Rao             {
394ddf64866SMarri Devender Rao                 mainApp.install(certificateFile);
395ddf64866SMarri Devender Rao             }
396ddf64866SMarri Devender Rao             catch (const InvalidCertificate& e)
397ddf64866SMarri Devender Rao             {
398ddf64866SMarri Devender Rao                 throw;
399ddf64866SMarri Devender Rao             }
400ddf64866SMarri Devender Rao         },
401ddf64866SMarri Devender Rao         InvalidCertificate);
402ddf64866SMarri Devender Rao     EXPECT_FALSE(fs::exists(verifyPath));
403ddf64866SMarri Devender Rao }
404ddf64866SMarri Devender Rao 
405ddf64866SMarri Devender Rao /** @brief Check install fails if ceritificate is missing in certificate file
406ddf64866SMarri Devender Rao  */
407ddf64866SMarri Devender Rao TEST_F(TestInvalidCertsManager, TestMissingCeritificate)
408ddf64866SMarri Devender Rao {
409ddf64866SMarri Devender Rao     std::string endpoint("ldap");
410ddf64866SMarri Devender Rao     std::string unit("nslcd.service");
411ddf64866SMarri Devender Rao     std::string type("client");
412ddf64866SMarri Devender Rao     std::string path(certDir + "/" + keyFile);
413ddf64866SMarri Devender Rao     std::string verifyPath(path);
414*b50789ceSJayanth Othayoth     std::string verifyUnit(unit);
415ddf64866SMarri Devender Rao 
416ddf64866SMarri Devender Rao     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
417ddf64866SMarri Devender Rao     MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
418ddf64866SMarri Devender Rao                             std::move(path));
419*b50789ceSJayanth Othayoth     EXPECT_CALL(manager, reloadOrReset(verifyUnit)).Times(0);
420ddf64866SMarri Devender Rao     MainApp mainApp(&manager);
421ddf64866SMarri Devender Rao     EXPECT_THROW(
422ddf64866SMarri Devender Rao         {
423ddf64866SMarri Devender Rao             try
424ddf64866SMarri Devender Rao             {
425ddf64866SMarri Devender Rao                 mainApp.install(keyFile);
426ddf64866SMarri Devender Rao             }
427ddf64866SMarri Devender Rao             catch (const InvalidCertificate& e)
428ddf64866SMarri Devender Rao             {
429ddf64866SMarri Devender Rao                 throw;
430ddf64866SMarri Devender Rao             }
431ddf64866SMarri Devender Rao         },
432ddf64866SMarri Devender Rao         InvalidCertificate);
433ddf64866SMarri Devender Rao     EXPECT_FALSE(fs::exists(verifyPath));
434e6597c5bSMarri Devender Rao }
435