blob: 6e7f8784a1407cdd996f7cff9f2ea00688baad14 [file] [log] [blame]
Marri Devender Rao13bf74e2019-03-26 01:52:17 -05001#include "config.h"
2
Marri Devender Rao8841dbd2019-03-04 05:43:55 -06003#include "certificate.hpp"
Marri Devender Rao947258d2018-09-25 10:52:24 -05004#include "certs_manager.hpp"
5
6#include <algorithm>
Marri Devender Rao8841dbd2019-03-04 05:43:55 -06007#include <filesystem>
Marri Devender Rao947258d2018-09-25 10:52:24 -05008#include <fstream>
9#include <iterator>
Marri Devender Raof4682712019-03-19 05:00:28 -050010#include <sdeventplus/event.hpp>
Marri Devender Rao947258d2018-09-25 10:52:24 -050011#include <string>
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050012#include <xyz/openbmc_project/Certs/error.hpp>
Marri Devender Rao947258d2018-09-25 10:52:24 -050013#include <xyz/openbmc_project/Common/error.hpp>
14
Marri Devender Rao947258d2018-09-25 10:52:24 -050015#include <gtest/gtest.h>
Marri Devender Rao8841dbd2019-03-04 05:43:55 -060016namespace fs = std::filesystem;
Marri Devender Rao947258d2018-09-25 10:52:24 -050017using InternalFailure =
18 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
Marri Devender Raoe6597c52018-10-01 06:36:55 -050019using InvalidCertificate =
Marri Devender Rao13bf74e2019-03-26 01:52:17 -050020 sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -060021using namespace phosphor::certs;
Marri Devender Raoe6597c52018-10-01 06:36:55 -050022
Marri Devender Raoddf64862018-10-03 07:11:02 -050023/**
24 * Class to generate certificate file and test verification of certificate file
25 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -060026class TestCertificates : public ::testing::Test
Marri Devender Rao947258d2018-09-25 10:52:24 -050027{
28 public:
Marri Devender Rao8841dbd2019-03-04 05:43:55 -060029 TestCertificates() : bus(sdbusplus::bus::new_default())
Marri Devender Rao947258d2018-09-25 10:52:24 -050030 {
31 }
32 void SetUp() override
33 {
34 char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
35 auto dirPtr = mkdtemp(dirTemplate);
36 if (dirPtr == NULL)
37 {
38 throw std::bad_alloc();
39 }
40 certDir = dirPtr;
41 certificateFile = "cert.pem";
Marri Devender Raof4682712019-03-19 05:00:28 -050042 CSRFile = "domain.csr";
43 privateKeyFile = "privkey.pem";
Marri Devender Rao947258d2018-09-25 10:52:24 -050044 std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
45 cmd += "-keyout cert.pem -out cert.pem -days 3650 ";
46 cmd += "-subj "
47 "/O=openbmc-project.xyz/CN=localhost"
48 " -nodes";
49 auto val = std::system(cmd.c_str());
50 if (val)
51 {
52 std::cout << "COMMAND Error: " << val << std::endl;
53 }
54 }
55 void TearDown() override
56 {
57 fs::remove_all(certDir);
58 fs::remove(certificateFile);
Marri Devender Raof4682712019-03-19 05:00:28 -050059 fs::remove(CSRFile);
60 fs::remove(privateKeyFile);
Marri Devender Rao947258d2018-09-25 10:52:24 -050061 }
62
63 bool compareFiles(const std::string& file1, const std::string& file2)
64 {
65 std::ifstream f1(file1, std::ifstream::binary | std::ifstream::ate);
66 std::ifstream f2(file2, std::ifstream::binary | std::ifstream::ate);
67
68 if (f1.fail() || f2.fail())
69 {
70 return false; // file problem
71 }
72
73 if (f1.tellg() != f2.tellg())
74 {
75 return false; // size mismatch
76 }
77
78 // seek back to beginning and use std::equal to compare contents
79 f1.seekg(0, std::ifstream::beg);
80 f2.seekg(0, std::ifstream::beg);
81 return std::equal(std::istreambuf_iterator<char>(f1.rdbuf()),
82 std::istreambuf_iterator<char>(),
83 std::istreambuf_iterator<char>(f2.rdbuf()));
84 }
85
86 protected:
87 sdbusplus::bus::bus bus;
Marri Devender Raof4682712019-03-19 05:00:28 -050088 std::string certificateFile, CSRFile, privateKeyFile;
Marri Devender Rao947258d2018-09-25 10:52:24 -050089
90 std::string certDir;
91};
92
93class MainApp
94{
95 public:
Marri Devender Raof4682712019-03-19 05:00:28 -050096 MainApp(phosphor::certs::Manager* manager,
97 phosphor::certs::CSR* csr = nullptr) :
98 manager(manager),
99 csr(csr)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500100 {
101 }
102 void install(std::string& path)
103 {
104 manager->install(path);
105 }
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500106 void delete_()
107 {
108 manager->delete_();
109 }
Marri Devender Raof4682712019-03-19 05:00:28 -0500110
111 std::string generateCSR(std::vector<std::string> alternativeNames,
112 std::string challengePassword, std::string city,
113 std::string commonName, std::string contactPerson,
114 std::string country, std::string email,
115 std::string givenName, std::string initials,
116 int64_t keyBitLength, std::string keyCurveId,
117 std::string keyPairAlgorithm,
118 std::vector<std::string> keyUsage,
119 std::string organization,
120 std::string organizationalUnit, std::string state,
121 std::string surname, std::string unstructuredName)
122 {
123 return (manager->generateCSR(
124 alternativeNames, challengePassword, city, commonName,
125 contactPerson, country, email, givenName, initials, keyBitLength,
126 keyCurveId, keyPairAlgorithm, keyUsage, organization,
127 organizationalUnit, state, surname, unstructuredName));
128 }
129 std::string cSR()
130 {
131 return (csr->cSR());
132 }
Marri Devender Rao947258d2018-09-25 10:52:24 -0500133 phosphor::certs::Manager* manager;
Marri Devender Raof4682712019-03-19 05:00:28 -0500134 phosphor::certs::CSR* csr;
Marri Devender Rao947258d2018-09-25 10:52:24 -0500135};
136
Marri Devender Rao947258d2018-09-25 10:52:24 -0500137/** @brief Check if server install routine is invoked for server setup
138 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600139TEST_F(TestCertificates, InvokeServerInstall)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500140{
141 std::string endpoint("https");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600142 std::string unit("");
Marri Devender Rao947258d2018-09-25 10:52:24 -0500143 std::string type("server");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600144 std::string installPath(certDir + "/" + certificateFile);
145 std::string verifyPath(installPath);
146 UnitsToRestart verifyUnit(unit);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500147 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500148 auto event = sdeventplus::Event::get_default();
149 // Attach the bus to sd_event to service user requests
150 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
151 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
152 std::move(installPath));
153 MainApp mainApp(&manager);
154 mainApp.install(certificateFile);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500155 EXPECT_TRUE(fs::exists(verifyPath));
156}
157
158/** @brief Check if client install routine is invoked for client setup
159 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600160TEST_F(TestCertificates, InvokeClientInstall)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500161{
162 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600163 std::string unit("");
164 std::string type("server");
165 std::string installPath(certDir + "/" + certificateFile);
166 std::string verifyPath(installPath);
167 UnitsToRestart verifyUnit(unit);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500168 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500169 auto event = sdeventplus::Event::get_default();
170 // Attach the bus to sd_event to service user requests
171 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
172 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
173 std::move(installPath));
174 MainApp mainApp(&manager);
175 mainApp.install(certificateFile);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500176 EXPECT_TRUE(fs::exists(verifyPath));
177}
178
179/** @brief Check if authority install routine is invoked for authority setup
180 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600181TEST_F(TestCertificates, InvokeAuthorityInstall)
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500182{
183 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600184 std::string unit("");
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500185 std::string type("authority");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600186 std::string installPath(certDir + "/" + certificateFile);
187 std::string verifyPath(installPath);
188 UnitsToRestart verifyUnit(unit);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500189 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500190 auto event = sdeventplus::Event::get_default();
191 // Attach the bus to sd_event to service user requests
192 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
193 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
194 std::move(installPath));
195 MainApp mainApp(&manager);
196 mainApp.install(certificateFile);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500197 EXPECT_TRUE(fs::exists(verifyPath));
198}
199
200/** @brief Compare the installed certificate with the copied certificate
201 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600202TEST_F(TestCertificates, CompareInstalledCertificate)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500203{
204 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600205 std::string unit("");
Marri Devender Rao947258d2018-09-25 10:52:24 -0500206 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600207 std::string installPath(certDir + "/" + certificateFile);
208 std::string verifyPath(installPath);
209 UnitsToRestart verifyUnit(unit);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500210 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500211 auto event = sdeventplus::Event::get_default();
212 // Attach the bus to sd_event to service user requests
213 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
214 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
215 std::move(installPath));
216 MainApp mainApp(&manager);
217 mainApp.install(certificateFile);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500218 EXPECT_TRUE(fs::exists(verifyPath));
219 EXPECT_TRUE(compareFiles(verifyPath, certificateFile));
220}
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500221
222/** @brief Check if install fails if certificate file is not found
223 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600224TEST_F(TestCertificates, TestNoCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500225{
226 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600227 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500228 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600229 std::string installPath(certDir + "/" + certificateFile);
230 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500231 std::string verifyUnit(unit);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500232 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600233 std::string uploadFile = "nofile.pem";
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500234 EXPECT_THROW(
235 {
236 try
237 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500238 auto event = sdeventplus::Event::get_default();
239 // Attach the bus to sd_event to service user requests
240 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
241 Manager manager(bus, event, objPath.c_str(), type,
242 std::move(unit), std::move(installPath));
243 MainApp mainApp(&manager);
244 mainApp.install(uploadFile);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500245 }
246 catch (const InternalFailure& e)
247 {
248 throw;
249 }
250 },
251 InternalFailure);
252 EXPECT_FALSE(fs::exists(verifyPath));
253}
254
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500255/** @brief Test replacing existing certificate
256 */
257TEST_F(TestCertificates, TestReplaceCertificate)
258{
259 std::string endpoint("ldap");
260 std::string unit("");
261 std::string type("server");
262 std::string installPath(certDir + "/" + certificateFile);
263 std::string verifyPath(installPath);
264 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
265 auto event = sdeventplus::Event::get_default();
266 // Attach the bus to sd_event to service user requests
267 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
268 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
269 std::move(installPath));
270 MainApp mainApp(&manager);
271 mainApp.install(certificateFile);
272 EXPECT_TRUE(fs::exists(verifyPath));
273 EXPECT_TRUE(fs::exists(verifyPath));
274 CertificatePtr& ptr = manager.getCertificate();
275 EXPECT_NE(ptr, nullptr);
276 ptr->replace(certificateFile);
277 EXPECT_TRUE(fs::exists(verifyPath));
278}
279
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500280/** @brief Check if install fails if certificate file is empty
281 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600282TEST_F(TestCertificates, TestEmptyCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500283{
284 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600285 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500286 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600287 std::string installPath(certDir + "/" + certificateFile);
288 std::string verifyPath(installPath);
289 std::string verifyUnit(unit);
290 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500291 std::string emptyFile("emptycert.pem");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500292 std::ofstream ofs;
293 ofs.open(emptyFile, std::ofstream::out);
294 ofs.close();
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500295 EXPECT_THROW(
296 {
297 try
298 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500299 auto event = sdeventplus::Event::get_default();
300 // Attach the bus to sd_event to service user requests
301 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
302 Manager manager(bus, event, objPath.c_str(), type,
303 std::move(unit), std::move(installPath));
304 MainApp mainApp(&manager);
305 mainApp.install(emptyFile);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500306 }
307 catch (const InvalidCertificate& e)
308 {
309 throw;
310 }
311 },
312 InvalidCertificate);
313 EXPECT_FALSE(fs::exists(verifyPath));
314 fs::remove(emptyFile);
315}
316
Marri Devender Raoddf64862018-10-03 07:11:02 -0500317/** @brief Check if install fails if certificate file is corrupted
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500318 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600319TEST_F(TestCertificates, TestInvalidCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500320{
321 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600322 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500323 std::string type("client");
324
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500325 std::ofstream ofs;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500326 ofs.open(certificateFile, std::ofstream::out);
327 ofs << "-----BEGIN CERTIFICATE-----";
328 ofs << "ADD_SOME_INVALID_DATA_INTO_FILE";
329 ofs << "-----END CERTIFICATE-----";
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500330 ofs.close();
331
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600332 std::string installPath(certDir + "/" + certificateFile);
333 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500334 std::string verifyUnit(unit);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500335 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500336 EXPECT_THROW(
337 {
338 try
339 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500340 auto event = sdeventplus::Event::get_default();
341 // Attach the bus to sd_event to service user requests
342 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
343 Manager manager(bus, event, objPath.c_str(), type,
344 std::move(unit), std::move(installPath));
345 MainApp mainApp(&manager);
346 mainApp.install(certificateFile);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500347 }
348 catch (const InvalidCertificate& e)
349 {
350 throw;
351 }
352 },
353 InvalidCertificate);
354 EXPECT_FALSE(fs::exists(verifyPath));
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500355}
Marri Devender Raoddf64862018-10-03 07:11:02 -0500356
357/**
358 * Class to generate private and certificate only file and test verification
359 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600360class TestInvalidCertificate : public ::testing::Test
Marri Devender Raoddf64862018-10-03 07:11:02 -0500361{
362 public:
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600363 TestInvalidCertificate() : bus(sdbusplus::bus::new_default())
Marri Devender Raoddf64862018-10-03 07:11:02 -0500364 {
365 }
366 void SetUp() override
367 {
368 char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
369 auto dirPtr = mkdtemp(dirTemplate);
370 if (dirPtr == NULL)
371 {
372 throw std::bad_alloc();
373 }
374 certDir = dirPtr;
375 certificateFile = "cert.pem";
376 keyFile = "key.pem";
377 std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
378 cmd += "-keyout key.pem -out cert.pem -days 3650 ";
379 cmd += "-subj "
380 "/O=openbmc-project.xyz/CN=localhost"
381 " -nodes";
382
383 auto val = std::system(cmd.c_str());
384 if (val)
385 {
386 std::cout << "command Error: " << val << std::endl;
387 }
388 }
389 void TearDown() override
390 {
391 fs::remove_all(certDir);
392 fs::remove(certificateFile);
393 fs::remove(keyFile);
394 }
395
396 protected:
397 sdbusplus::bus::bus bus;
398 std::string certificateFile;
399 std::string keyFile;
400 std::string certDir;
401};
402
403/** @brief Check install fails if private key is missing in certificate file
404 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600405TEST_F(TestInvalidCertificate, TestMissingPrivateKey)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500406{
407 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600408 std::string unit("");
Marri Devender Raoddf64862018-10-03 07:11:02 -0500409 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600410 std::string installPath(certDir + "/" + certificateFile);
411 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500412 std::string verifyUnit(unit);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500413 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600414 EXPECT_THROW(
415 {
416 try
417 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500418 auto event = sdeventplus::Event::get_default();
419 // Attach the bus to sd_event to service user requests
420 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
421 Manager manager(bus, event, objPath.c_str(), type,
422 std::move(unit), std::move(installPath));
423 MainApp mainApp(&manager);
424 mainApp.install(certificateFile);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600425 }
Marri Devender Raocd30c492019-06-12 01:40:17 -0500426 catch (const InternalFailure& e)
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600427 {
428 throw;
429 }
430 },
Marri Devender Raocd30c492019-06-12 01:40:17 -0500431 InternalFailure);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600432 EXPECT_FALSE(fs::exists(verifyPath));
433}
434
435/** @brief Check install fails if ceritificate is missing in certificate file
436 */
437TEST_F(TestInvalidCertificate, TestMissingCeritificate)
438{
439 std::string endpoint("ldap");
440 std::string unit("");
441 std::string type("client");
442 std::string installPath(certDir + "/" + keyFile);
443 std::string verifyPath(installPath);
444 std::string verifyUnit(unit);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600445 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
446 EXPECT_THROW(
447 {
448 try
449 {
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500450 auto event = sdeventplus::Event::get_default();
451 // Attach the bus to sd_event to service user requests
452 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
453 Manager manager(bus, event, objPath.c_str(), type,
454 std::move(unit), std::move(installPath));
455 MainApp mainApp(&manager);
456 mainApp.install(keyFile);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500457 }
Marri Devender Raocd30c492019-06-12 01:40:17 -0500458 catch (const InternalFailure& e)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500459 {
460 throw;
461 }
462 },
463 InvalidCertificate);
464 EXPECT_FALSE(fs::exists(verifyPath));
465}
466
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600467/** @brief Check if error is thrown when multiple certificates are installed
468 * At present only one certificate per service is allowed
Marri Devender Raoddf64862018-10-03 07:11:02 -0500469 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600470TEST_F(TestCertificates, TestCertInstallNotAllowed)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500471{
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600472 using NotAllowed =
473 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500474 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600475 std::string unit("");
Marri Devender Raoddf64862018-10-03 07:11:02 -0500476 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600477 std::string installPath(certDir + "/" + certificateFile);
478 std::string verifyPath(installPath);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500479 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raof4682712019-03-19 05:00:28 -0500480 auto event = sdeventplus::Event::get_default();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500481 // Attach the bus to sd_event to service user requests
482 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
Marri Devender Raof4682712019-03-19 05:00:28 -0500483 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600484 std::move(installPath));
Marri Devender Raoddf64862018-10-03 07:11:02 -0500485 MainApp mainApp(&manager);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600486 mainApp.install(certificateFile);
487 EXPECT_TRUE(fs::exists(verifyPath));
Marri Devender Raoddf64862018-10-03 07:11:02 -0500488 EXPECT_THROW(
489 {
490 try
491 {
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600492 // install second certificate
493 mainApp.install(certificateFile);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500494 }
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600495 catch (const NotAllowed& e)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500496 {
497 throw;
498 }
499 },
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600500 NotAllowed);
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500501}
Marri Devender Raof4682712019-03-19 05:00:28 -0500502
503TEST_F(TestCertificates, TestGenerateCSR)
504{
505 std::string endpoint("https");
506 std::string unit("");
507 std::string type("Server");
508 std::string installPath(certDir + "/" + certificateFile);
509 std::string verifyPath(installPath);
510 std::string CSRPath(certDir + "/" + CSRFile);
511 std::string privateKeyPath(certDir + "/" + privateKeyFile);
512 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500513 std::string challengePassword("Password");
Marri Devender Raof4682712019-03-19 05:00:28 -0500514 std::string city("HYB");
515 std::string commonName("abc.com");
516 std::string contactPerson("Admin");
517 std::string country("IN");
518 std::string email("admin@in.ibm.com");
519 std::string givenName("givenName");
520 std::string initials("G");
521 int64_t keyBitLength(2048);
522 std::string keyCurveId("0");
523 std::string keyPairAlgorithm("RSA");
524 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
525 std::string organization("IBM");
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500526 std::string organizationalUnit("orgUnit");
Marri Devender Raof4682712019-03-19 05:00:28 -0500527 std::string state("TS");
528 std::string surname("surname");
529 std::string unstructuredName("unstructuredName");
530 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
531 auto event = sdeventplus::Event::get_default();
Marri Devender Raoffad1ef2019-06-03 04:54:12 -0500532 // Attach the bus to sd_event to service user requests
533 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
Marri Devender Raof4682712019-03-19 05:00:28 -0500534 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
535 std::move(installPath));
536 Status status;
537 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
538 MainApp mainApp(&manager, &csr);
539 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
540 contactPerson, country, email, givenName, initials,
541 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
542 organization, organizationalUnit, state, surname,
543 unstructuredName);
544 std::string csrData("");
545 // generateCSR takes considerable time to create CSR and privateKey Files
546 EXPECT_FALSE(fs::exists(CSRPath));
547 EXPECT_FALSE(fs::exists(privateKeyPath));
548 EXPECT_THROW(
549 {
550 try
551 {
552 csrData = csr.cSR();
553 }
554 catch (const InternalFailure& e)
555 {
556 throw;
557 }
558 },
559 InternalFailure);
560 // wait for 10 sec to get CSR and privateKey Files generated
561 sleep(10);
562 EXPECT_TRUE(fs::exists(CSRPath));
563 EXPECT_TRUE(fs::exists(privateKeyPath));
564 csrData = csr.cSR();
565 ASSERT_NE("", csrData.c_str());
566}
567
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500568/** @brief Check default KeyBitLength is used if Key bit length is not given*/
569TEST_F(TestCertificates, TestGenerateCSRwithDefaultKeyBitLength)
Marri Devender Raof4682712019-03-19 05:00:28 -0500570{
571 std::string endpoint("https");
572 std::string unit("");
573 std::string type("Server");
574 std::string installPath(certDir + "/" + certificateFile);
575 std::string verifyPath(installPath);
576 std::string CSRPath(certDir + "/" + CSRFile);
577 std::string privateKeyPath(certDir + "/" + privateKeyFile);
578 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500579 std::string challengePassword("Password");
580 std::string city("HYB");
581 std::string commonName("abc.com");
582 std::string contactPerson("Admin");
583 std::string country("IN");
584 std::string email("admin@in.ibm.com");
585 std::string givenName("givenName");
586 std::string initials("G");
587 int64_t keyBitLength = 0;
588 std::string keyCurveId("0");
589 std::string keyPairAlgorithm("RSA");
Marri Devender Raof4682712019-03-19 05:00:28 -0500590 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500591 std::string organization("IBM");
592 std::string organizationalUnit("orgUnit");
593 std::string state("TS");
594 std::string surname("surname");
595 std::string unstructuredName("unstructuredName");
596 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
597 auto event = sdeventplus::Event::get_default();
598 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
599 std::move(installPath));
600 Status status;
601 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
602 MainApp mainApp(&manager, &csr);
603 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
604 contactPerson, country, email, givenName, initials,
605 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
606 organization, organizationalUnit, state, surname,
607 unstructuredName);
608 std::string csrData("");
609 // generateCSR takes considerable time to create CSR and privateKey Files
610 EXPECT_FALSE(fs::exists(CSRPath));
611 EXPECT_FALSE(fs::exists(privateKeyPath));
612 EXPECT_THROW(
613 {
614 try
615 {
616 csrData = csr.cSR();
617 }
618 catch (const InternalFailure& e)
619 {
620 throw;
621 }
622 },
623 InternalFailure);
624 // wait for 10 sec to get CSR and privateKey Files generated
625 sleep(10);
626 EXPECT_TRUE(fs::exists(CSRPath));
627 EXPECT_TRUE(fs::exists(privateKeyPath));
628 csrData = csr.cSR();
629 ASSERT_NE("", csrData.c_str());
630}
631
632/** @brief Check if ECC key pair is generated when user is not given algorithm
633 * type. At present RSA and EC key pair algorithm are supported
634 */
635TEST_F(TestCertificates, TestGenerateCSRwithEmptyKeyPairAlgorithm)
636{
637 std::string endpoint("https");
638 std::string unit("");
639 std::string type("Server");
640 std::string installPath(certDir + "/" + certificateFile);
641 std::string verifyPath(installPath);
642 std::string CSRPath(certDir + "/" + CSRFile);
643 std::string privateKeyPath(certDir + "/" + privateKeyFile);
644 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
645 std::string challengePassword("Password");
646 std::string city("HYB");
647 std::string commonName("abc.com");
648 std::string contactPerson("Admin");
649 std::string country("IN");
650 std::string email("admin@in.ibm.com");
651 std::string givenName("givenName");
652 std::string initials("G");
653 int64_t keyBitLength(2048);
654 std::string keyCurveId("");
655 std::string keyPairAlgorithm("");
656 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
657 std::string organization("IBM");
658 std::string organizationalUnit("orgUnit");
659 std::string state("TS");
660 std::string surname("surname");
661 std::string unstructuredName("unstructuredName");
Marri Devender Raof4682712019-03-19 05:00:28 -0500662 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
663 auto event = sdeventplus::Event::get_default();
664 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
665 std::move(installPath));
666 Status status;
667 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
668 MainApp mainApp(&manager, &csr);
669 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
670 contactPerson, country, email, givenName, initials,
671 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
672 organization, organizationalUnit, state, surname,
673 unstructuredName);
674 sleep(10);
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500675 EXPECT_TRUE(fs::exists(CSRPath));
676 EXPECT_TRUE(fs::exists(privateKeyPath));
677}
678
679/** @brief Check if error is thrown when giving un supported key pair
680 * algorithm. At present RSA and EC key pair algorithm are supported
681 */
682TEST_F(TestCertificates, TestGenerateCSRwithUnsupportedKeyPairAlgorithm)
683{
684 std::string endpoint("https");
685 std::string unit("");
686 std::string type("Server");
687 std::string installPath(certDir + "/" + certificateFile);
688 std::string verifyPath(installPath);
689 std::string CSRPath(certDir + "/" + CSRFile);
690 std::string privateKeyPath(certDir + "/" + privateKeyFile);
691 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
692 std::string challengePassword("Password");
693 std::string city("HYB");
694 std::string commonName("abc.com");
695 std::string contactPerson("Admin");
696 std::string country("IN");
697 std::string email("admin@in.ibm.com");
698 std::string givenName("givenName");
699 std::string initials("G");
700 int64_t keyBitLength(2048);
701 std::string keyCurveId("secp521r1");
702 std::string keyPairAlgorithm("UnSupportedAlgorithm");
703 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
704 std::string organization("IBM");
705 std::string organizationalUnit("orgUnit");
706 std::string state("TS");
707 std::string surname("surname");
708 std::string unstructuredName("unstructuredName");
709 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
710 auto event = sdeventplus::Event::get_default();
711 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
712 std::move(installPath));
713 Status status;
714 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
715 MainApp mainApp(&manager, &csr);
716 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
717 contactPerson, country, email, givenName, initials,
718 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
719 organization, organizationalUnit, state, surname,
720 unstructuredName);
Marri Devender Raof4682712019-03-19 05:00:28 -0500721 EXPECT_FALSE(fs::exists(CSRPath));
722 EXPECT_FALSE(fs::exists(privateKeyPath));
723}
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500724
725/** @brief Check if error is thrown when NID_undef is returned for given key
726 * curve id
727 */
728TEST_F(TestCertificates, TestECKeyGenerationwithNIDundefCase)
729{
730 std::string endpoint("https");
731 std::string unit("");
732 std::string type("Server");
733 std::string installPath(certDir + "/" + certificateFile);
734 std::string verifyPath(installPath);
735 std::string CSRPath(certDir + "/" + CSRFile);
736 std::string privateKeyPath(certDir + "/" + privateKeyFile);
737 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
738 std::string challengePassword("Password");
739 std::string city("BLR");
740 std::string commonName("abc.com");
741 std::string contactPerson("Admin");
742 std::string country("IN");
743 std::string email("admin@in.ibm.com");
744 std::string givenName("givenName");
745 std::string initials("G");
746 int64_t keyBitLength(2048);
747 std::string keyCurveId("DummyCurveName");
748 std::string keyPairAlgorithm("EC");
749 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
750 std::string organization("IBM");
751 std::string organizationalUnit("orgUnit");
752 std::string state("TS");
753 std::string surname("surname");
754 std::string unstructuredName("unstructuredName");
755 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
756 auto event = sdeventplus::Event::get_default();
757 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
758 std::move(installPath));
759 Status status;
760 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
761 MainApp mainApp(&manager, &csr);
762 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
763 contactPerson, country, email, givenName, initials,
764 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
765 organization, organizationalUnit, state, surname,
766 unstructuredName);
767 EXPECT_FALSE(fs::exists(CSRPath));
768 EXPECT_FALSE(fs::exists(privateKeyPath));
769}
770
771/** @brief Check default Key Curve Id is used if given curve id is empty
772 */
773TEST_F(TestCertificates, TestECKeyGenerationwithDefaultKeyCurveId)
774{
775 std::string endpoint("https");
776 std::string unit("");
777 std::string type("Server");
778 std::string installPath(certDir + "/" + certificateFile);
779 std::string verifyPath(installPath);
780 std::string CSRPath(certDir + "/" + CSRFile);
781 std::string privateKeyPath(certDir + "/" + privateKeyFile);
782 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
783 std::string challengePassword("Password");
784 std::string city("BLR");
785 std::string commonName("abc.com");
786 std::string contactPerson("Admin");
787 std::string country("IN");
788 std::string email("admin@in.ibm.com");
789 std::string givenName("givenName");
790 std::string initials("G");
791 int64_t keyBitLength(2048);
792 std::string keyCurveId("");
793 std::string keyPairAlgorithm("EC");
794 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
795 std::string organization("IBM");
796 std::string organizationalUnit("orgUnit");
797 std::string state("TS");
798 std::string surname("surname");
799 std::string unstructuredName("unstructuredName");
800 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
801 auto event = sdeventplus::Event::get_default();
802 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
803 std::move(installPath));
804 Status status;
805 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
806 MainApp mainApp(&manager, &csr);
807 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
808 contactPerson, country, email, givenName, initials,
809 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
810 organization, organizationalUnit, state, surname,
811 unstructuredName);
812 sleep(10);
813 EXPECT_TRUE(fs::exists(CSRPath));
814 EXPECT_TRUE(fs::exists(privateKeyPath));
815}
816
817/** @brief Check if error is not thrown to generate EC key pair
818 */
819TEST_F(TestCertificates, TestECKeyGeneration)
820{
821 std::string endpoint("https");
822 std::string unit("");
823 std::string type("Server");
824 std::string installPath(certDir + "/" + certificateFile);
825 std::string verifyPath(installPath);
826 std::string CSRPath(certDir + "/" + CSRFile);
827 std::string privateKeyPath(certDir + "/" + privateKeyFile);
828 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
829 std::string challengePassword("Password");
830 std::string city("BLR");
831 std::string commonName("abc.com");
832 std::string contactPerson("Admin");
833 std::string country("IN");
834 std::string email("admin@in.ibm.com");
835 std::string givenName("givenName");
836 std::string initials("G");
837 int64_t keyBitLength(2048);
838 std::string keyCurveId("secp521r1");
839 std::string keyPairAlgorithm("EC");
840 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
841 std::string organization("IBM");
842 std::string organizationalUnit("orgUnit");
843 std::string state("TS");
844 std::string surname("surname");
845 std::string unstructuredName("unstructuredName");
846 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
847 auto event = sdeventplus::Event::get_default();
848 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
849 std::move(installPath));
850 Status status;
851 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
852 MainApp mainApp(&manager, &csr);
853 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
854 contactPerson, country, email, givenName, initials,
855 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
856 organization, organizationalUnit, state, surname,
857 unstructuredName);
858 std::cout << "CSRPath: " << CSRPath << std::endl
859 << "privateKeyPath: " << privateKeyPath << std::endl;
860 sleep(10);
861 EXPECT_TRUE(fs::exists(CSRPath));
862 EXPECT_TRUE(fs::exists(privateKeyPath));
863}