blob: aaf491cd401f3fe173f12b0f3641cbb64a858bdd [file] [log] [blame]
Marri Devender Rao947258d2018-09-25 10:52:24 -05001#include "certs_manager.hpp"
2
3#include <algorithm>
4#include <experimental/filesystem>
5#include <fstream>
6#include <iterator>
7#include <string>
8#include <xyz/openbmc_project/Certs/Install/error.hpp>
9#include <xyz/openbmc_project/Common/error.hpp>
10
11#include <gmock/gmock.h>
12#include <gtest/gtest.h>
13
14namespace fs = std::experimental::filesystem;
15static constexpr auto BUSNAME = "xyz.openbmc_project.Certs.Manager";
16static constexpr auto OBJPATH = "/xyz/openbmc_project/certs";
17using InternalFailure =
18 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
19
20class TestCertsManager : public ::testing::Test
21{
22 public:
23 TestCertsManager() : bus(sdbusplus::bus::new_default())
24 {
25 }
26 void SetUp() override
27 {
28 char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
29 auto dirPtr = mkdtemp(dirTemplate);
30 if (dirPtr == NULL)
31 {
32 throw std::bad_alloc();
33 }
34 certDir = dirPtr;
35 certificateFile = "cert.pem";
36 std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
37 cmd += "-keyout cert.pem -out cert.pem -days 3650 ";
38 cmd += "-subj "
39 "/O=openbmc-project.xyz/CN=localhost"
40 " -nodes";
41 auto val = std::system(cmd.c_str());
42 if (val)
43 {
44 std::cout << "COMMAND Error: " << val << std::endl;
45 }
46 }
47 void TearDown() override
48 {
49 fs::remove_all(certDir);
50 fs::remove(certificateFile);
51 }
52
53 bool compareFiles(const std::string& file1, const std::string& file2)
54 {
55 std::ifstream f1(file1, std::ifstream::binary | std::ifstream::ate);
56 std::ifstream f2(file2, std::ifstream::binary | std::ifstream::ate);
57
58 if (f1.fail() || f2.fail())
59 {
60 return false; // file problem
61 }
62
63 if (f1.tellg() != f2.tellg())
64 {
65 return false; // size mismatch
66 }
67
68 // seek back to beginning and use std::equal to compare contents
69 f1.seekg(0, std::ifstream::beg);
70 f2.seekg(0, std::ifstream::beg);
71 return std::equal(std::istreambuf_iterator<char>(f1.rdbuf()),
72 std::istreambuf_iterator<char>(),
73 std::istreambuf_iterator<char>(f2.rdbuf()));
74 }
75
76 protected:
77 sdbusplus::bus::bus bus;
78 std::string certificateFile;
79
80 std::string certDir;
81};
82
83class MainApp
84{
85 public:
86 MainApp(phosphor::certs::Manager* manager) : manager(manager)
87 {
88 }
89 void install(std::string& path)
90 {
91 manager->install(path);
92 }
93 phosphor::certs::Manager* manager;
94};
95
96class MockCertManager : public phosphor::certs::Manager
97{
98 public:
99 MockCertManager(sdbusplus::bus::bus& bus, const char* path,
100 std::string& type, std::string&& unit,
101 std::string&& certPath) :
102 Manager(bus, path, type, std::forward<std::string>(unit),
103 std::forward<std::string>(certPath))
104 {
105 }
106 virtual ~MockCertManager()
107 {
108 }
109
110 MOCK_METHOD0(clientInstall, void());
111 MOCK_METHOD0(serverInstall, void());
112};
113
114/** @brief Check if server install routine is invoked for server setup
115 */
116TEST_F(TestCertsManager, InvokeServerInstall)
117{
118 std::string endpoint("https");
119 std::string unit("nginx.service");
120 std::string type("server");
121 std::string path(certDir + "/" + certificateFile);
122 std::string verifyPath(path);
123 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
124 MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
125 std::move(path));
126 EXPECT_CALL(manager, serverInstall()).Times(1);
127
128 MainApp mainApp(&manager);
129 EXPECT_NO_THROW({ mainApp.install(certificateFile); });
130 EXPECT_TRUE(fs::exists(verifyPath));
131}
132
133/** @brief Check if client install routine is invoked for client setup
134 */
135TEST_F(TestCertsManager, InvokeClientInstall)
136{
137 std::string endpoint("ldap");
138 std::string unit("nslcd.service");
139 std::string type("client");
140 std::string path(certDir + "/" + certificateFile);
141 std::string verifyPath(path);
142 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
143 MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
144 std::move(path));
145 EXPECT_CALL(manager, clientInstall()).Times(1);
146 MainApp mainApp(&manager);
147 EXPECT_NO_THROW({ mainApp.install(certificateFile); });
148 EXPECT_TRUE(fs::exists(verifyPath));
149}
150
151/** @brief Compare the installed certificate with the copied certificate
152 */
153TEST_F(TestCertsManager, CompareInstalledCertificate)
154{
155 std::string endpoint("ldap");
156 std::string unit("nslcd.service");
157 std::string type("client");
158 std::string path(certDir + "/" + certificateFile);
159 std::string verifyPath(path);
160 auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
161 MockCertManager manager(bus, objPath.c_str(), type, std::move(unit),
162 std::move(path));
163 EXPECT_CALL(manager, clientInstall()).Times(1);
164 MainApp mainApp(&manager);
165 EXPECT_NO_THROW({ mainApp.install(certificateFile); });
166 EXPECT_TRUE(fs::exists(verifyPath));
167 EXPECT_TRUE(compareFiles(verifyPath, certificateFile));
168}