blob: a783ba330880c0cc4024e241d870704c424c29b5 [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 Rao8841dbd2019-03-04 05:43:55 -0600148 Certificate certificate(bus, objPath, type, unit, installPath,
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500149 certificateFile, false);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500150 EXPECT_TRUE(fs::exists(verifyPath));
151}
152
153/** @brief Check if client install routine is invoked for client setup
154 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600155TEST_F(TestCertificates, InvokeClientInstall)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500156{
157 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600158 std::string unit("");
159 std::string type("server");
160 std::string installPath(certDir + "/" + certificateFile);
161 std::string verifyPath(installPath);
162 UnitsToRestart verifyUnit(unit);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500163 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600164 Certificate certificate(bus, objPath, type, unit, installPath,
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500165 certificateFile, false);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500166 EXPECT_TRUE(fs::exists(verifyPath));
167}
168
169/** @brief Check if authority install routine is invoked for authority setup
170 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600171TEST_F(TestCertificates, InvokeAuthorityInstall)
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500172{
173 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600174 std::string unit("");
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500175 std::string type("authority");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600176 std::string installPath(certDir + "/" + certificateFile);
177 std::string verifyPath(installPath);
178 UnitsToRestart verifyUnit(unit);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500179 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600180 Certificate certificate(bus, objPath, type, unit, installPath,
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500181 certificateFile, false);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500182 EXPECT_TRUE(fs::exists(verifyPath));
183}
184
185/** @brief Compare the installed certificate with the copied certificate
186 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600187TEST_F(TestCertificates, CompareInstalledCertificate)
Marri Devender Rao947258d2018-09-25 10:52:24 -0500188{
189 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600190 std::string unit("");
Marri Devender Rao947258d2018-09-25 10:52:24 -0500191 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600192 std::string installPath(certDir + "/" + certificateFile);
193 std::string verifyPath(installPath);
194 UnitsToRestart verifyUnit(unit);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500195 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600196 Certificate certificate(bus, objPath, type, unit, installPath,
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500197 certificateFile, false);
Marri Devender Rao947258d2018-09-25 10:52:24 -0500198 EXPECT_TRUE(fs::exists(verifyPath));
199 EXPECT_TRUE(compareFiles(verifyPath, certificateFile));
200}
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500201
202/** @brief Check if install fails if certificate file is not found
203 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600204TEST_F(TestCertificates, TestNoCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500205{
206 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600207 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500208 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600209 std::string installPath(certDir + "/" + certificateFile);
210 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500211 std::string verifyUnit(unit);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500212 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600213 std::string uploadFile = "nofile.pem";
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500214 EXPECT_THROW(
215 {
216 try
217 {
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600218 Certificate certificate(bus, objPath, type, unit, installPath,
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500219 uploadFile, false);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500220 }
221 catch (const InternalFailure& e)
222 {
223 throw;
224 }
225 },
226 InternalFailure);
227 EXPECT_FALSE(fs::exists(verifyPath));
228}
229
230/** @brief Check if install fails if certificate file is empty
231 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600232TEST_F(TestCertificates, TestEmptyCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500233{
234 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600235 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500236 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600237 std::string installPath(certDir + "/" + certificateFile);
238 std::string verifyPath(installPath);
239 std::string verifyUnit(unit);
240 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500241 std::string emptyFile("emptycert.pem");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500242 std::ofstream ofs;
243 ofs.open(emptyFile, std::ofstream::out);
244 ofs.close();
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500245 EXPECT_THROW(
246 {
247 try
248 {
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600249 Certificate certificate(bus, objPath, type, unit, installPath,
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500250 emptyFile, false);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500251 }
252 catch (const InvalidCertificate& e)
253 {
254 throw;
255 }
256 },
257 InvalidCertificate);
258 EXPECT_FALSE(fs::exists(verifyPath));
259 fs::remove(emptyFile);
260}
261
Marri Devender Raoddf64862018-10-03 07:11:02 -0500262/** @brief Check if install fails if certificate file is corrupted
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500263 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600264TEST_F(TestCertificates, TestInvalidCertificateFile)
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500265{
266 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600267 std::string unit("");
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500268 std::string type("client");
269
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500270 std::ofstream ofs;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500271 ofs.open(certificateFile, std::ofstream::out);
272 ofs << "-----BEGIN CERTIFICATE-----";
273 ofs << "ADD_SOME_INVALID_DATA_INTO_FILE";
274 ofs << "-----END CERTIFICATE-----";
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500275 ofs.close();
276
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600277 std::string installPath(certDir + "/" + certificateFile);
278 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500279 std::string verifyUnit(unit);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500280 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500281 EXPECT_THROW(
282 {
283 try
284 {
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600285 Certificate certificate(bus, objPath, type, unit, installPath,
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500286 certificateFile, false);
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500287 }
288 catch (const InvalidCertificate& e)
289 {
290 throw;
291 }
292 },
293 InvalidCertificate);
294 EXPECT_FALSE(fs::exists(verifyPath));
Marri Devender Raoe6597c52018-10-01 06:36:55 -0500295}
Marri Devender Raoddf64862018-10-03 07:11:02 -0500296
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600297/** @brief check certificate delete at manager level
298 */
299TEST_F(TestCertificates, TestCertManagerDelete)
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500300{
301 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600302 std::string unit("");
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500303 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600304 std::string installPath(certDir + "/" + certificateFile);
305 std::string verifyPath(installPath);
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500306 std::string verifyUnit(unit);
Marri Devender Raof4682712019-03-19 05:00:28 -0500307 // Get default event loop
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500308 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raof4682712019-03-19 05:00:28 -0500309 auto event = sdeventplus::Event::get_default();
310 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600311 std::move(installPath));
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500312 MainApp mainApp(&manager);
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500313 // delete certificate file and verify file is deleted
314 mainApp.delete_();
315 EXPECT_FALSE(fs::exists(verifyPath));
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600316}
317
318/** @brief check certificate install at manager level
319 */
320TEST_F(TestCertificates, TestCertManagerInstall)
321{
322 std::string endpoint("ldap");
323 std::string unit("");
324 std::string type("client");
325 std::string installPath(certDir + "/" + certificateFile);
326 std::string verifyPath(installPath);
327 std::string verifyUnit(unit);
328 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raof4682712019-03-19 05:00:28 -0500329 auto event = sdeventplus::Event::get_default();
330 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600331 std::move(installPath));
332 MainApp mainApp(&manager);
333 mainApp.install(certificateFile);
334 EXPECT_TRUE(fs::exists(verifyPath));
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500335}
336
Marri Devender Raoddf64862018-10-03 07:11:02 -0500337/**
338 * Class to generate private and certificate only file and test verification
339 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600340class TestInvalidCertificate : public ::testing::Test
Marri Devender Raoddf64862018-10-03 07:11:02 -0500341{
342 public:
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600343 TestInvalidCertificate() : bus(sdbusplus::bus::new_default())
Marri Devender Raoddf64862018-10-03 07:11:02 -0500344 {
345 }
346 void SetUp() override
347 {
348 char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
349 auto dirPtr = mkdtemp(dirTemplate);
350 if (dirPtr == NULL)
351 {
352 throw std::bad_alloc();
353 }
354 certDir = dirPtr;
355 certificateFile = "cert.pem";
356 keyFile = "key.pem";
357 std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
358 cmd += "-keyout key.pem -out cert.pem -days 3650 ";
359 cmd += "-subj "
360 "/O=openbmc-project.xyz/CN=localhost"
361 " -nodes";
362
363 auto val = std::system(cmd.c_str());
364 if (val)
365 {
366 std::cout << "command Error: " << val << std::endl;
367 }
368 }
369 void TearDown() override
370 {
371 fs::remove_all(certDir);
372 fs::remove(certificateFile);
373 fs::remove(keyFile);
374 }
375
376 protected:
377 sdbusplus::bus::bus bus;
378 std::string certificateFile;
379 std::string keyFile;
380 std::string certDir;
381};
382
383/** @brief Check install fails if private key is missing in certificate file
384 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600385TEST_F(TestInvalidCertificate, TestMissingPrivateKey)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500386{
387 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600388 std::string unit("");
Marri Devender Raoddf64862018-10-03 07:11:02 -0500389 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600390 std::string installPath(certDir + "/" + certificateFile);
391 std::string verifyPath(installPath);
Jayanth Othayothb50789c2018-10-09 07:13:54 -0500392 std::string verifyUnit(unit);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500393 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600394 EXPECT_THROW(
395 {
396 try
397 {
398 Certificate certificate(bus, objPath, type, unit, installPath,
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500399 certificateFile, false);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600400 }
401 catch (const InvalidCertificate& e)
402 {
403 throw;
404 }
405 },
406 InvalidCertificate);
407 EXPECT_FALSE(fs::exists(verifyPath));
408}
409
410/** @brief Check install fails if ceritificate is missing in certificate file
411 */
412TEST_F(TestInvalidCertificate, TestMissingCeritificate)
413{
414 std::string endpoint("ldap");
415 std::string unit("");
416 std::string type("client");
417 std::string installPath(certDir + "/" + keyFile);
418 std::string verifyPath(installPath);
419 std::string verifyUnit(unit);
420
421 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
422 EXPECT_THROW(
423 {
424 try
425 {
426 Certificate certificate(bus, objPath, type, unit, installPath,
Marri Devender Rao8f80c352019-05-13 00:53:01 -0500427 keyFile, false);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600428 }
429 catch (const InvalidCertificate& e)
430 {
431 throw;
432 }
433 },
434 InvalidCertificate);
435 EXPECT_FALSE(fs::exists(verifyPath));
436}
437
438/** @brief Check if Manager install method fails for invalid certificate file
439 */
440TEST_F(TestInvalidCertificate, TestCertManagerInstall)
441{
442 std::string endpoint("ldap");
443 std::string unit("");
444 std::string type("client");
445 std::string installPath(certDir + "/" + certificateFile);
446 std::string verifyPath(installPath);
447 std::string verifyUnit(unit);
448 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raof4682712019-03-19 05:00:28 -0500449 auto event = sdeventplus::Event::get_default();
450 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600451 std::move(installPath));
Marri Devender Raoddf64862018-10-03 07:11:02 -0500452 MainApp mainApp(&manager);
453 EXPECT_THROW(
454 {
455 try
456 {
457 mainApp.install(certificateFile);
458 }
459 catch (const InvalidCertificate& e)
460 {
461 throw;
462 }
463 },
464 InvalidCertificate);
465 EXPECT_FALSE(fs::exists(verifyPath));
466}
467
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600468/** @brief Check if error is thrown when multiple certificates are installed
469 * At present only one certificate per service is allowed
Marri Devender Raoddf64862018-10-03 07:11:02 -0500470 */
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600471TEST_F(TestCertificates, TestCertInstallNotAllowed)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500472{
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600473 using NotAllowed =
474 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
Marri Devender Raoddf64862018-10-03 07:11:02 -0500475 std::string endpoint("ldap");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600476 std::string unit("");
Marri Devender Raoddf64862018-10-03 07:11:02 -0500477 std::string type("client");
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600478 std::string installPath(certDir + "/" + certificateFile);
479 std::string verifyPath(installPath);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500480 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
Marri Devender Raof4682712019-03-19 05:00:28 -0500481 auto event = sdeventplus::Event::get_default();
482 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600483 std::move(installPath));
Marri Devender Raoddf64862018-10-03 07:11:02 -0500484 MainApp mainApp(&manager);
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600485 mainApp.install(certificateFile);
486 EXPECT_TRUE(fs::exists(verifyPath));
Marri Devender Raoddf64862018-10-03 07:11:02 -0500487 EXPECT_THROW(
488 {
489 try
490 {
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600491 // install second certificate
492 mainApp.install(certificateFile);
Marri Devender Raoddf64862018-10-03 07:11:02 -0500493 }
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600494 catch (const NotAllowed& e)
Marri Devender Raoddf64862018-10-03 07:11:02 -0500495 {
496 throw;
497 }
498 },
Marri Devender Rao8841dbd2019-03-04 05:43:55 -0600499 NotAllowed);
Marri Devender Rao9abfae82018-10-03 08:10:35 -0500500}
Marri Devender Raof4682712019-03-19 05:00:28 -0500501
502TEST_F(TestCertificates, TestGenerateCSR)
503{
504 std::string endpoint("https");
505 std::string unit("");
506 std::string type("Server");
507 std::string installPath(certDir + "/" + certificateFile);
508 std::string verifyPath(installPath);
509 std::string CSRPath(certDir + "/" + CSRFile);
510 std::string privateKeyPath(certDir + "/" + privateKeyFile);
511 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500512 std::string challengePassword("Password");
Marri Devender Raof4682712019-03-19 05:00:28 -0500513 std::string city("HYB");
514 std::string commonName("abc.com");
515 std::string contactPerson("Admin");
516 std::string country("IN");
517 std::string email("admin@in.ibm.com");
518 std::string givenName("givenName");
519 std::string initials("G");
520 int64_t keyBitLength(2048);
521 std::string keyCurveId("0");
522 std::string keyPairAlgorithm("RSA");
523 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
524 std::string organization("IBM");
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500525 std::string organizationalUnit("orgUnit");
Marri Devender Raof4682712019-03-19 05:00:28 -0500526 std::string state("TS");
527 std::string surname("surname");
528 std::string unstructuredName("unstructuredName");
529 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
530 auto event = sdeventplus::Event::get_default();
531 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
532 std::move(installPath));
533 Status status;
534 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
535 MainApp mainApp(&manager, &csr);
536 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
537 contactPerson, country, email, givenName, initials,
538 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
539 organization, organizationalUnit, state, surname,
540 unstructuredName);
541 std::string csrData("");
542 // generateCSR takes considerable time to create CSR and privateKey Files
543 EXPECT_FALSE(fs::exists(CSRPath));
544 EXPECT_FALSE(fs::exists(privateKeyPath));
545 EXPECT_THROW(
546 {
547 try
548 {
549 csrData = csr.cSR();
550 }
551 catch (const InternalFailure& e)
552 {
553 throw;
554 }
555 },
556 InternalFailure);
557 // wait for 10 sec to get CSR and privateKey Files generated
558 sleep(10);
559 EXPECT_TRUE(fs::exists(CSRPath));
560 EXPECT_TRUE(fs::exists(privateKeyPath));
561 csrData = csr.cSR();
562 ASSERT_NE("", csrData.c_str());
563}
564
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500565/** @brief Check default KeyBitLength is used if Key bit length is not given*/
566TEST_F(TestCertificates, TestGenerateCSRwithDefaultKeyBitLength)
Marri Devender Raof4682712019-03-19 05:00:28 -0500567{
568 std::string endpoint("https");
569 std::string unit("");
570 std::string type("Server");
571 std::string installPath(certDir + "/" + certificateFile);
572 std::string verifyPath(installPath);
573 std::string CSRPath(certDir + "/" + CSRFile);
574 std::string privateKeyPath(certDir + "/" + privateKeyFile);
575 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500576 std::string challengePassword("Password");
577 std::string city("HYB");
578 std::string commonName("abc.com");
579 std::string contactPerson("Admin");
580 std::string country("IN");
581 std::string email("admin@in.ibm.com");
582 std::string givenName("givenName");
583 std::string initials("G");
584 int64_t keyBitLength = 0;
585 std::string keyCurveId("0");
586 std::string keyPairAlgorithm("RSA");
Marri Devender Raof4682712019-03-19 05:00:28 -0500587 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500588 std::string organization("IBM");
589 std::string organizationalUnit("orgUnit");
590 std::string state("TS");
591 std::string surname("surname");
592 std::string unstructuredName("unstructuredName");
593 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
594 auto event = sdeventplus::Event::get_default();
595 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
596 std::move(installPath));
597 Status status;
598 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
599 MainApp mainApp(&manager, &csr);
600 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
601 contactPerson, country, email, givenName, initials,
602 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
603 organization, organizationalUnit, state, surname,
604 unstructuredName);
605 std::string csrData("");
606 // generateCSR takes considerable time to create CSR and privateKey Files
607 EXPECT_FALSE(fs::exists(CSRPath));
608 EXPECT_FALSE(fs::exists(privateKeyPath));
609 EXPECT_THROW(
610 {
611 try
612 {
613 csrData = csr.cSR();
614 }
615 catch (const InternalFailure& e)
616 {
617 throw;
618 }
619 },
620 InternalFailure);
621 // wait for 10 sec to get CSR and privateKey Files generated
622 sleep(10);
623 EXPECT_TRUE(fs::exists(CSRPath));
624 EXPECT_TRUE(fs::exists(privateKeyPath));
625 csrData = csr.cSR();
626 ASSERT_NE("", csrData.c_str());
627}
628
629/** @brief Check if ECC key pair is generated when user is not given algorithm
630 * type. At present RSA and EC key pair algorithm are supported
631 */
632TEST_F(TestCertificates, TestGenerateCSRwithEmptyKeyPairAlgorithm)
633{
634 std::string endpoint("https");
635 std::string unit("");
636 std::string type("Server");
637 std::string installPath(certDir + "/" + certificateFile);
638 std::string verifyPath(installPath);
639 std::string CSRPath(certDir + "/" + CSRFile);
640 std::string privateKeyPath(certDir + "/" + privateKeyFile);
641 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
642 std::string challengePassword("Password");
643 std::string city("HYB");
644 std::string commonName("abc.com");
645 std::string contactPerson("Admin");
646 std::string country("IN");
647 std::string email("admin@in.ibm.com");
648 std::string givenName("givenName");
649 std::string initials("G");
650 int64_t keyBitLength(2048);
651 std::string keyCurveId("");
652 std::string keyPairAlgorithm("");
653 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
654 std::string organization("IBM");
655 std::string organizationalUnit("orgUnit");
656 std::string state("TS");
657 std::string surname("surname");
658 std::string unstructuredName("unstructuredName");
Marri Devender Raof4682712019-03-19 05:00:28 -0500659 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
660 auto event = sdeventplus::Event::get_default();
661 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
662 std::move(installPath));
663 Status status;
664 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
665 MainApp mainApp(&manager, &csr);
666 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
667 contactPerson, country, email, givenName, initials,
668 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
669 organization, organizationalUnit, state, surname,
670 unstructuredName);
671 sleep(10);
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500672 EXPECT_TRUE(fs::exists(CSRPath));
673 EXPECT_TRUE(fs::exists(privateKeyPath));
674}
675
676/** @brief Check if error is thrown when giving un supported key pair
677 * algorithm. At present RSA and EC key pair algorithm are supported
678 */
679TEST_F(TestCertificates, TestGenerateCSRwithUnsupportedKeyPairAlgorithm)
680{
681 std::string endpoint("https");
682 std::string unit("");
683 std::string type("Server");
684 std::string installPath(certDir + "/" + certificateFile);
685 std::string verifyPath(installPath);
686 std::string CSRPath(certDir + "/" + CSRFile);
687 std::string privateKeyPath(certDir + "/" + privateKeyFile);
688 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
689 std::string challengePassword("Password");
690 std::string city("HYB");
691 std::string commonName("abc.com");
692 std::string contactPerson("Admin");
693 std::string country("IN");
694 std::string email("admin@in.ibm.com");
695 std::string givenName("givenName");
696 std::string initials("G");
697 int64_t keyBitLength(2048);
698 std::string keyCurveId("secp521r1");
699 std::string keyPairAlgorithm("UnSupportedAlgorithm");
700 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
701 std::string organization("IBM");
702 std::string organizationalUnit("orgUnit");
703 std::string state("TS");
704 std::string surname("surname");
705 std::string unstructuredName("unstructuredName");
706 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
707 auto event = sdeventplus::Event::get_default();
708 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
709 std::move(installPath));
710 Status status;
711 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
712 MainApp mainApp(&manager, &csr);
713 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
714 contactPerson, country, email, givenName, initials,
715 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
716 organization, organizationalUnit, state, surname,
717 unstructuredName);
Marri Devender Raof4682712019-03-19 05:00:28 -0500718 EXPECT_FALSE(fs::exists(CSRPath));
719 EXPECT_FALSE(fs::exists(privateKeyPath));
720}
Ramesh Iyyar8a09b522019-06-07 05:23:29 -0500721
722/** @brief Check if error is thrown when NID_undef is returned for given key
723 * curve id
724 */
725TEST_F(TestCertificates, TestECKeyGenerationwithNIDundefCase)
726{
727 std::string endpoint("https");
728 std::string unit("");
729 std::string type("Server");
730 std::string installPath(certDir + "/" + certificateFile);
731 std::string verifyPath(installPath);
732 std::string CSRPath(certDir + "/" + CSRFile);
733 std::string privateKeyPath(certDir + "/" + privateKeyFile);
734 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
735 std::string challengePassword("Password");
736 std::string city("BLR");
737 std::string commonName("abc.com");
738 std::string contactPerson("Admin");
739 std::string country("IN");
740 std::string email("admin@in.ibm.com");
741 std::string givenName("givenName");
742 std::string initials("G");
743 int64_t keyBitLength(2048);
744 std::string keyCurveId("DummyCurveName");
745 std::string keyPairAlgorithm("EC");
746 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
747 std::string organization("IBM");
748 std::string organizationalUnit("orgUnit");
749 std::string state("TS");
750 std::string surname("surname");
751 std::string unstructuredName("unstructuredName");
752 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
753 auto event = sdeventplus::Event::get_default();
754 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
755 std::move(installPath));
756 Status status;
757 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
758 MainApp mainApp(&manager, &csr);
759 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
760 contactPerson, country, email, givenName, initials,
761 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
762 organization, organizationalUnit, state, surname,
763 unstructuredName);
764 EXPECT_FALSE(fs::exists(CSRPath));
765 EXPECT_FALSE(fs::exists(privateKeyPath));
766}
767
768/** @brief Check default Key Curve Id is used if given curve id is empty
769 */
770TEST_F(TestCertificates, TestECKeyGenerationwithDefaultKeyCurveId)
771{
772 std::string endpoint("https");
773 std::string unit("");
774 std::string type("Server");
775 std::string installPath(certDir + "/" + certificateFile);
776 std::string verifyPath(installPath);
777 std::string CSRPath(certDir + "/" + CSRFile);
778 std::string privateKeyPath(certDir + "/" + privateKeyFile);
779 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
780 std::string challengePassword("Password");
781 std::string city("BLR");
782 std::string commonName("abc.com");
783 std::string contactPerson("Admin");
784 std::string country("IN");
785 std::string email("admin@in.ibm.com");
786 std::string givenName("givenName");
787 std::string initials("G");
788 int64_t keyBitLength(2048);
789 std::string keyCurveId("");
790 std::string keyPairAlgorithm("EC");
791 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
792 std::string organization("IBM");
793 std::string organizationalUnit("orgUnit");
794 std::string state("TS");
795 std::string surname("surname");
796 std::string unstructuredName("unstructuredName");
797 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
798 auto event = sdeventplus::Event::get_default();
799 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
800 std::move(installPath));
801 Status status;
802 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
803 MainApp mainApp(&manager, &csr);
804 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
805 contactPerson, country, email, givenName, initials,
806 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
807 organization, organizationalUnit, state, surname,
808 unstructuredName);
809 sleep(10);
810 EXPECT_TRUE(fs::exists(CSRPath));
811 EXPECT_TRUE(fs::exists(privateKeyPath));
812}
813
814/** @brief Check if error is not thrown to generate EC key pair
815 */
816TEST_F(TestCertificates, TestECKeyGeneration)
817{
818 std::string endpoint("https");
819 std::string unit("");
820 std::string type("Server");
821 std::string installPath(certDir + "/" + certificateFile);
822 std::string verifyPath(installPath);
823 std::string CSRPath(certDir + "/" + CSRFile);
824 std::string privateKeyPath(certDir + "/" + privateKeyFile);
825 std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
826 std::string challengePassword("Password");
827 std::string city("BLR");
828 std::string commonName("abc.com");
829 std::string contactPerson("Admin");
830 std::string country("IN");
831 std::string email("admin@in.ibm.com");
832 std::string givenName("givenName");
833 std::string initials("G");
834 int64_t keyBitLength(2048);
835 std::string keyCurveId("secp521r1");
836 std::string keyPairAlgorithm("EC");
837 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
838 std::string organization("IBM");
839 std::string organizationalUnit("orgUnit");
840 std::string state("TS");
841 std::string surname("surname");
842 std::string unstructuredName("unstructuredName");
843 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
844 auto event = sdeventplus::Event::get_default();
845 Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
846 std::move(installPath));
847 Status status;
848 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
849 MainApp mainApp(&manager, &csr);
850 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
851 contactPerson, country, email, givenName, initials,
852 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
853 organization, organizationalUnit, state, surname,
854 unstructuredName);
855 std::cout << "CSRPath: " << CSRPath << std::endl
856 << "privateKeyPath: " << privateKeyPath << std::endl;
857 sleep(10);
858 EXPECT_TRUE(fs::exists(CSRPath));
859 EXPECT_TRUE(fs::exists(privateKeyPath));
860}