113bf74e4SMarri Devender Rao #include "config.h" 213bf74e4SMarri Devender Rao 38841dbd6SMarri Devender Rao #include "certificate.hpp" 4947258dcSMarri Devender Rao #include "certs_manager.hpp" 5947258dcSMarri Devender Rao 6947258dcSMarri Devender Rao #include <algorithm> 78841dbd6SMarri Devender Rao #include <filesystem> 8947258dcSMarri Devender Rao #include <fstream> 9947258dcSMarri Devender Rao #include <iterator> 10*f4682712SMarri Devender Rao #include <sdeventplus/event.hpp> 11947258dcSMarri Devender Rao #include <string> 1213bf74e4SMarri Devender Rao #include <xyz/openbmc_project/Certs/error.hpp> 13947258dcSMarri Devender Rao #include <xyz/openbmc_project/Common/error.hpp> 14947258dcSMarri Devender Rao 15947258dcSMarri Devender Rao #include <gtest/gtest.h> 168841dbd6SMarri Devender Rao namespace fs = std::filesystem; 17947258dcSMarri Devender Rao using InternalFailure = 18947258dcSMarri Devender Rao sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 19e6597c5bSMarri Devender Rao using InvalidCertificate = 2013bf74e4SMarri Devender Rao sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate; 218841dbd6SMarri Devender Rao using namespace phosphor::certs; 22e6597c5bSMarri Devender Rao 23ddf64866SMarri Devender Rao /** 24ddf64866SMarri Devender Rao * Class to generate certificate file and test verification of certificate file 25ddf64866SMarri Devender Rao */ 268841dbd6SMarri Devender Rao class TestCertificates : public ::testing::Test 27947258dcSMarri Devender Rao { 28947258dcSMarri Devender Rao public: 298841dbd6SMarri Devender Rao TestCertificates() : 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"; 42*f4682712SMarri Devender Rao CSRFile = "domain.csr"; 43*f4682712SMarri Devender Rao privateKeyFile = "privkey.pem"; 44947258dcSMarri Devender Rao std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 "; 45947258dcSMarri Devender Rao cmd += "-keyout cert.pem -out cert.pem -days 3650 "; 46947258dcSMarri Devender Rao cmd += "-subj " 47947258dcSMarri Devender Rao "/O=openbmc-project.xyz/CN=localhost" 48947258dcSMarri Devender Rao " -nodes"; 49947258dcSMarri Devender Rao auto val = std::system(cmd.c_str()); 50947258dcSMarri Devender Rao if (val) 51947258dcSMarri Devender Rao { 52947258dcSMarri Devender Rao std::cout << "COMMAND Error: " << val << std::endl; 53947258dcSMarri Devender Rao } 54947258dcSMarri Devender Rao } 55947258dcSMarri Devender Rao void TearDown() override 56947258dcSMarri Devender Rao { 57947258dcSMarri Devender Rao fs::remove_all(certDir); 58947258dcSMarri Devender Rao fs::remove(certificateFile); 59*f4682712SMarri Devender Rao fs::remove(CSRFile); 60*f4682712SMarri Devender Rao fs::remove(privateKeyFile); 61947258dcSMarri Devender Rao } 62947258dcSMarri Devender Rao 63947258dcSMarri Devender Rao bool compareFiles(const std::string& file1, const std::string& file2) 64947258dcSMarri Devender Rao { 65947258dcSMarri Devender Rao std::ifstream f1(file1, std::ifstream::binary | std::ifstream::ate); 66947258dcSMarri Devender Rao std::ifstream f2(file2, std::ifstream::binary | std::ifstream::ate); 67947258dcSMarri Devender Rao 68947258dcSMarri Devender Rao if (f1.fail() || f2.fail()) 69947258dcSMarri Devender Rao { 70947258dcSMarri Devender Rao return false; // file problem 71947258dcSMarri Devender Rao } 72947258dcSMarri Devender Rao 73947258dcSMarri Devender Rao if (f1.tellg() != f2.tellg()) 74947258dcSMarri Devender Rao { 75947258dcSMarri Devender Rao return false; // size mismatch 76947258dcSMarri Devender Rao } 77947258dcSMarri Devender Rao 78947258dcSMarri Devender Rao // seek back to beginning and use std::equal to compare contents 79947258dcSMarri Devender Rao f1.seekg(0, std::ifstream::beg); 80947258dcSMarri Devender Rao f2.seekg(0, std::ifstream::beg); 81947258dcSMarri Devender Rao return std::equal(std::istreambuf_iterator<char>(f1.rdbuf()), 82947258dcSMarri Devender Rao std::istreambuf_iterator<char>(), 83947258dcSMarri Devender Rao std::istreambuf_iterator<char>(f2.rdbuf())); 84947258dcSMarri Devender Rao } 85947258dcSMarri Devender Rao 86947258dcSMarri Devender Rao protected: 87947258dcSMarri Devender Rao sdbusplus::bus::bus bus; 88*f4682712SMarri Devender Rao std::string certificateFile, CSRFile, privateKeyFile; 89947258dcSMarri Devender Rao 90947258dcSMarri Devender Rao std::string certDir; 91947258dcSMarri Devender Rao }; 92947258dcSMarri Devender Rao 93947258dcSMarri Devender Rao class MainApp 94947258dcSMarri Devender Rao { 95947258dcSMarri Devender Rao public: 96*f4682712SMarri Devender Rao MainApp(phosphor::certs::Manager* manager, 97*f4682712SMarri Devender Rao phosphor::certs::CSR* csr = nullptr) : 98*f4682712SMarri Devender Rao manager(manager), 99*f4682712SMarri Devender Rao csr(csr) 100947258dcSMarri Devender Rao { 101947258dcSMarri Devender Rao } 102947258dcSMarri Devender Rao void install(std::string& path) 103947258dcSMarri Devender Rao { 104947258dcSMarri Devender Rao manager->install(path); 105947258dcSMarri Devender Rao } 1069abfae88SMarri Devender Rao void delete_() 1079abfae88SMarri Devender Rao { 1089abfae88SMarri Devender Rao manager->delete_(); 1099abfae88SMarri Devender Rao } 110*f4682712SMarri Devender Rao 111*f4682712SMarri Devender Rao std::string generateCSR(std::vector<std::string> alternativeNames, 112*f4682712SMarri Devender Rao std::string challengePassword, std::string city, 113*f4682712SMarri Devender Rao std::string commonName, std::string contactPerson, 114*f4682712SMarri Devender Rao std::string country, std::string email, 115*f4682712SMarri Devender Rao std::string givenName, std::string initials, 116*f4682712SMarri Devender Rao int64_t keyBitLength, std::string keyCurveId, 117*f4682712SMarri Devender Rao std::string keyPairAlgorithm, 118*f4682712SMarri Devender Rao std::vector<std::string> keyUsage, 119*f4682712SMarri Devender Rao std::string organization, 120*f4682712SMarri Devender Rao std::string organizationalUnit, std::string state, 121*f4682712SMarri Devender Rao std::string surname, std::string unstructuredName) 122*f4682712SMarri Devender Rao { 123*f4682712SMarri Devender Rao return (manager->generateCSR( 124*f4682712SMarri Devender Rao alternativeNames, challengePassword, city, commonName, 125*f4682712SMarri Devender Rao contactPerson, country, email, givenName, initials, keyBitLength, 126*f4682712SMarri Devender Rao keyCurveId, keyPairAlgorithm, keyUsage, organization, 127*f4682712SMarri Devender Rao organizationalUnit, state, surname, unstructuredName)); 128*f4682712SMarri Devender Rao } 129*f4682712SMarri Devender Rao std::string cSR() 130*f4682712SMarri Devender Rao { 131*f4682712SMarri Devender Rao return (csr->cSR()); 132*f4682712SMarri Devender Rao } 133947258dcSMarri Devender Rao phosphor::certs::Manager* manager; 134*f4682712SMarri Devender Rao phosphor::certs::CSR* csr; 135947258dcSMarri Devender Rao }; 136947258dcSMarri Devender Rao 137947258dcSMarri Devender Rao /** @brief Check if server install routine is invoked for server setup 138947258dcSMarri Devender Rao */ 1398841dbd6SMarri Devender Rao TEST_F(TestCertificates, InvokeServerInstall) 140947258dcSMarri Devender Rao { 141947258dcSMarri Devender Rao std::string endpoint("https"); 1428841dbd6SMarri Devender Rao std::string unit(""); 143947258dcSMarri Devender Rao std::string type("server"); 1448841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 1458841dbd6SMarri Devender Rao std::string verifyPath(installPath); 1468841dbd6SMarri Devender Rao UnitsToRestart verifyUnit(unit); 147947258dcSMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 1488841dbd6SMarri Devender Rao Certificate certificate(bus, objPath, type, unit, installPath, 1498f80c35bSMarri Devender Rao certificateFile, false); 150947258dcSMarri Devender Rao EXPECT_TRUE(fs::exists(verifyPath)); 151947258dcSMarri Devender Rao } 152947258dcSMarri Devender Rao 153947258dcSMarri Devender Rao /** @brief Check if client install routine is invoked for client setup 154947258dcSMarri Devender Rao */ 1558841dbd6SMarri Devender Rao TEST_F(TestCertificates, InvokeClientInstall) 156947258dcSMarri Devender Rao { 157947258dcSMarri Devender Rao std::string endpoint("ldap"); 1588841dbd6SMarri Devender Rao std::string unit(""); 1598841dbd6SMarri Devender Rao std::string type("server"); 1608841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 1618841dbd6SMarri Devender Rao std::string verifyPath(installPath); 1628841dbd6SMarri Devender Rao UnitsToRestart verifyUnit(unit); 163947258dcSMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 1648841dbd6SMarri Devender Rao Certificate certificate(bus, objPath, type, unit, installPath, 1658f80c35bSMarri Devender Rao certificateFile, false); 166b50789ceSJayanth Othayoth EXPECT_TRUE(fs::exists(verifyPath)); 167b50789ceSJayanth Othayoth } 168b50789ceSJayanth Othayoth 169b50789ceSJayanth Othayoth /** @brief Check if authority install routine is invoked for authority setup 170b50789ceSJayanth Othayoth */ 1718841dbd6SMarri Devender Rao TEST_F(TestCertificates, InvokeAuthorityInstall) 172b50789ceSJayanth Othayoth { 173b50789ceSJayanth Othayoth std::string endpoint("ldap"); 1748841dbd6SMarri Devender Rao std::string unit(""); 175b50789ceSJayanth Othayoth std::string type("authority"); 1768841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 1778841dbd6SMarri Devender Rao std::string verifyPath(installPath); 1788841dbd6SMarri Devender Rao UnitsToRestart verifyUnit(unit); 179b50789ceSJayanth Othayoth auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 1808841dbd6SMarri Devender Rao Certificate certificate(bus, objPath, type, unit, installPath, 1818f80c35bSMarri Devender Rao certificateFile, false); 182947258dcSMarri Devender Rao EXPECT_TRUE(fs::exists(verifyPath)); 183947258dcSMarri Devender Rao } 184947258dcSMarri Devender Rao 185947258dcSMarri Devender Rao /** @brief Compare the installed certificate with the copied certificate 186947258dcSMarri Devender Rao */ 1878841dbd6SMarri Devender Rao TEST_F(TestCertificates, CompareInstalledCertificate) 188947258dcSMarri Devender Rao { 189947258dcSMarri Devender Rao std::string endpoint("ldap"); 1908841dbd6SMarri Devender Rao std::string unit(""); 191947258dcSMarri Devender Rao std::string type("client"); 1928841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 1938841dbd6SMarri Devender Rao std::string verifyPath(installPath); 1948841dbd6SMarri Devender Rao UnitsToRestart verifyUnit(unit); 195947258dcSMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 1968841dbd6SMarri Devender Rao Certificate certificate(bus, objPath, type, unit, installPath, 1978f80c35bSMarri Devender Rao certificateFile, false); 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 */ 2048841dbd6SMarri Devender Rao TEST_F(TestCertificates, TestNoCertificateFile) 205e6597c5bSMarri Devender Rao { 206e6597c5bSMarri Devender Rao std::string endpoint("ldap"); 2078841dbd6SMarri Devender Rao std::string unit(""); 208e6597c5bSMarri Devender Rao std::string type("client"); 2098841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 2108841dbd6SMarri Devender Rao std::string verifyPath(installPath); 211b50789ceSJayanth Othayoth std::string verifyUnit(unit); 212e6597c5bSMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 2138841dbd6SMarri Devender Rao std::string uploadFile = "nofile.pem"; 214e6597c5bSMarri Devender Rao EXPECT_THROW( 215e6597c5bSMarri Devender Rao { 216e6597c5bSMarri Devender Rao try 217e6597c5bSMarri Devender Rao { 2188841dbd6SMarri Devender Rao Certificate certificate(bus, objPath, type, unit, installPath, 2198f80c35bSMarri Devender Rao uploadFile, false); 220e6597c5bSMarri Devender Rao } 221e6597c5bSMarri Devender Rao catch (const InternalFailure& e) 222e6597c5bSMarri Devender Rao { 223e6597c5bSMarri Devender Rao throw; 224e6597c5bSMarri Devender Rao } 225e6597c5bSMarri Devender Rao }, 226e6597c5bSMarri Devender Rao InternalFailure); 227e6597c5bSMarri Devender Rao EXPECT_FALSE(fs::exists(verifyPath)); 228e6597c5bSMarri Devender Rao } 229e6597c5bSMarri Devender Rao 230e6597c5bSMarri Devender Rao /** @brief Check if install fails if certificate file is empty 231e6597c5bSMarri Devender Rao */ 2328841dbd6SMarri Devender Rao TEST_F(TestCertificates, TestEmptyCertificateFile) 233e6597c5bSMarri Devender Rao { 234e6597c5bSMarri Devender Rao std::string endpoint("ldap"); 2358841dbd6SMarri Devender Rao std::string unit(""); 236e6597c5bSMarri Devender Rao std::string type("client"); 2378841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 2388841dbd6SMarri Devender Rao std::string verifyPath(installPath); 2398841dbd6SMarri Devender Rao std::string verifyUnit(unit); 2408841dbd6SMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 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 EXPECT_THROW( 246e6597c5bSMarri Devender Rao { 247e6597c5bSMarri Devender Rao try 248e6597c5bSMarri Devender Rao { 2498841dbd6SMarri Devender Rao Certificate certificate(bus, objPath, type, unit, installPath, 2508f80c35bSMarri Devender Rao emptyFile, false); 251e6597c5bSMarri Devender Rao } 252e6597c5bSMarri Devender Rao catch (const InvalidCertificate& e) 253e6597c5bSMarri Devender Rao { 254e6597c5bSMarri Devender Rao throw; 255e6597c5bSMarri Devender Rao } 256e6597c5bSMarri Devender Rao }, 257e6597c5bSMarri Devender Rao InvalidCertificate); 258e6597c5bSMarri Devender Rao EXPECT_FALSE(fs::exists(verifyPath)); 259e6597c5bSMarri Devender Rao fs::remove(emptyFile); 260e6597c5bSMarri Devender Rao } 261e6597c5bSMarri Devender Rao 262ddf64866SMarri Devender Rao /** @brief Check if install fails if certificate file is corrupted 263e6597c5bSMarri Devender Rao */ 2648841dbd6SMarri Devender Rao TEST_F(TestCertificates, TestInvalidCertificateFile) 265e6597c5bSMarri Devender Rao { 266e6597c5bSMarri Devender Rao std::string endpoint("ldap"); 2678841dbd6SMarri Devender Rao std::string unit(""); 268e6597c5bSMarri Devender Rao std::string type("client"); 269e6597c5bSMarri Devender Rao 270e6597c5bSMarri Devender Rao std::ofstream ofs; 271ddf64866SMarri Devender Rao ofs.open(certificateFile, std::ofstream::out); 272ddf64866SMarri Devender Rao ofs << "-----BEGIN CERTIFICATE-----"; 273ddf64866SMarri Devender Rao ofs << "ADD_SOME_INVALID_DATA_INTO_FILE"; 274ddf64866SMarri Devender Rao ofs << "-----END CERTIFICATE-----"; 275e6597c5bSMarri Devender Rao ofs.close(); 276e6597c5bSMarri Devender Rao 2778841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 2788841dbd6SMarri Devender Rao std::string verifyPath(installPath); 279b50789ceSJayanth Othayoth std::string verifyUnit(unit); 280e6597c5bSMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 281e6597c5bSMarri Devender Rao EXPECT_THROW( 282e6597c5bSMarri Devender Rao { 283e6597c5bSMarri Devender Rao try 284e6597c5bSMarri Devender Rao { 2858841dbd6SMarri Devender Rao Certificate certificate(bus, objPath, type, unit, installPath, 2868f80c35bSMarri Devender Rao certificateFile, false); 287e6597c5bSMarri Devender Rao } 288e6597c5bSMarri Devender Rao catch (const InvalidCertificate& e) 289e6597c5bSMarri Devender Rao { 290e6597c5bSMarri Devender Rao throw; 291e6597c5bSMarri Devender Rao } 292e6597c5bSMarri Devender Rao }, 293e6597c5bSMarri Devender Rao InvalidCertificate); 294e6597c5bSMarri Devender Rao EXPECT_FALSE(fs::exists(verifyPath)); 295ddf64866SMarri Devender Rao } 296ddf64866SMarri Devender Rao 2978841dbd6SMarri Devender Rao /** @brief check certificate delete at manager level 2988841dbd6SMarri Devender Rao */ 2998841dbd6SMarri Devender Rao TEST_F(TestCertificates, TestCertManagerDelete) 3009abfae88SMarri Devender Rao { 3019abfae88SMarri Devender Rao std::string endpoint("ldap"); 3028841dbd6SMarri Devender Rao std::string unit(""); 3039abfae88SMarri Devender Rao std::string type("client"); 3048841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 3058841dbd6SMarri Devender Rao std::string verifyPath(installPath); 3069abfae88SMarri Devender Rao std::string verifyUnit(unit); 307*f4682712SMarri Devender Rao // Get default event loop 3089abfae88SMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 309*f4682712SMarri Devender Rao auto event = sdeventplus::Event::get_default(); 310*f4682712SMarri Devender Rao Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 3118841dbd6SMarri Devender Rao std::move(installPath)); 3129abfae88SMarri Devender Rao MainApp mainApp(&manager); 3139abfae88SMarri Devender Rao // delete certificate file and verify file is deleted 3149abfae88SMarri Devender Rao mainApp.delete_(); 3159abfae88SMarri Devender Rao EXPECT_FALSE(fs::exists(verifyPath)); 3168841dbd6SMarri Devender Rao } 3178841dbd6SMarri Devender Rao 3188841dbd6SMarri Devender Rao /** @brief check certificate install at manager level 3196ceec40bSMarri Devender Rao */ 3208841dbd6SMarri Devender Rao TEST_F(TestCertificates, TestCertManagerInstall) 3218841dbd6SMarri Devender Rao { 3228841dbd6SMarri Devender Rao std::string endpoint("ldap"); 3238841dbd6SMarri Devender Rao std::string unit(""); 3248841dbd6SMarri Devender Rao std::string type("client"); 3258841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 3268841dbd6SMarri Devender Rao std::string verifyPath(installPath); 3278841dbd6SMarri Devender Rao std::string verifyUnit(unit); 3288841dbd6SMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 329*f4682712SMarri Devender Rao auto event = sdeventplus::Event::get_default(); 330*f4682712SMarri Devender Rao Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 3318841dbd6SMarri Devender Rao std::move(installPath)); 3328841dbd6SMarri Devender Rao MainApp mainApp(&manager); 3338841dbd6SMarri Devender Rao mainApp.install(certificateFile); 3348841dbd6SMarri Devender Rao EXPECT_TRUE(fs::exists(verifyPath)); 3359abfae88SMarri Devender Rao } 3369abfae88SMarri Devender Rao 337ddf64866SMarri Devender Rao /** 338ddf64866SMarri Devender Rao * Class to generate private and certificate only file and test verification 339ddf64866SMarri Devender Rao */ 3408841dbd6SMarri Devender Rao class TestInvalidCertificate : public ::testing::Test 341ddf64866SMarri Devender Rao { 342ddf64866SMarri Devender Rao public: 3438841dbd6SMarri Devender Rao TestInvalidCertificate() : bus(sdbusplus::bus::new_default()) 344ddf64866SMarri Devender Rao { 345ddf64866SMarri Devender Rao } 346ddf64866SMarri Devender Rao void SetUp() override 347ddf64866SMarri Devender Rao { 348ddf64866SMarri Devender Rao char dirTemplate[] = "/tmp/FakeCerts.XXXXXX"; 349ddf64866SMarri Devender Rao auto dirPtr = mkdtemp(dirTemplate); 350ddf64866SMarri Devender Rao if (dirPtr == NULL) 351ddf64866SMarri Devender Rao { 352ddf64866SMarri Devender Rao throw std::bad_alloc(); 353ddf64866SMarri Devender Rao } 354ddf64866SMarri Devender Rao certDir = dirPtr; 355ddf64866SMarri Devender Rao certificateFile = "cert.pem"; 356ddf64866SMarri Devender Rao keyFile = "key.pem"; 357ddf64866SMarri Devender Rao std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 "; 358ddf64866SMarri Devender Rao cmd += "-keyout key.pem -out cert.pem -days 3650 "; 359ddf64866SMarri Devender Rao cmd += "-subj " 360ddf64866SMarri Devender Rao "/O=openbmc-project.xyz/CN=localhost" 361ddf64866SMarri Devender Rao " -nodes"; 362ddf64866SMarri Devender Rao 363ddf64866SMarri Devender Rao auto val = std::system(cmd.c_str()); 364ddf64866SMarri Devender Rao if (val) 365ddf64866SMarri Devender Rao { 366ddf64866SMarri Devender Rao std::cout << "command Error: " << val << std::endl; 367ddf64866SMarri Devender Rao } 368ddf64866SMarri Devender Rao } 369ddf64866SMarri Devender Rao void TearDown() override 370ddf64866SMarri Devender Rao { 371ddf64866SMarri Devender Rao fs::remove_all(certDir); 372ddf64866SMarri Devender Rao fs::remove(certificateFile); 373ddf64866SMarri Devender Rao fs::remove(keyFile); 374ddf64866SMarri Devender Rao } 375ddf64866SMarri Devender Rao 376ddf64866SMarri Devender Rao protected: 377ddf64866SMarri Devender Rao sdbusplus::bus::bus bus; 378ddf64866SMarri Devender Rao std::string certificateFile; 379ddf64866SMarri Devender Rao std::string keyFile; 380ddf64866SMarri Devender Rao std::string certDir; 381ddf64866SMarri Devender Rao }; 382ddf64866SMarri Devender Rao 383ddf64866SMarri Devender Rao /** @brief Check install fails if private key is missing in certificate file 384ddf64866SMarri Devender Rao */ 3858841dbd6SMarri Devender Rao TEST_F(TestInvalidCertificate, TestMissingPrivateKey) 386ddf64866SMarri Devender Rao { 387ddf64866SMarri Devender Rao std::string endpoint("ldap"); 3888841dbd6SMarri Devender Rao std::string unit(""); 389ddf64866SMarri Devender Rao std::string type("client"); 3908841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 3918841dbd6SMarri Devender Rao std::string verifyPath(installPath); 392b50789ceSJayanth Othayoth std::string verifyUnit(unit); 393ddf64866SMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 3948841dbd6SMarri Devender Rao EXPECT_THROW( 3958841dbd6SMarri Devender Rao { 3968841dbd6SMarri Devender Rao try 3978841dbd6SMarri Devender Rao { 3988841dbd6SMarri Devender Rao Certificate certificate(bus, objPath, type, unit, installPath, 3998f80c35bSMarri Devender Rao certificateFile, false); 4008841dbd6SMarri Devender Rao } 4018841dbd6SMarri Devender Rao catch (const InvalidCertificate& e) 4028841dbd6SMarri Devender Rao { 4038841dbd6SMarri Devender Rao throw; 4048841dbd6SMarri Devender Rao } 4058841dbd6SMarri Devender Rao }, 4068841dbd6SMarri Devender Rao InvalidCertificate); 4078841dbd6SMarri Devender Rao EXPECT_FALSE(fs::exists(verifyPath)); 4088841dbd6SMarri Devender Rao } 4098841dbd6SMarri Devender Rao 4108841dbd6SMarri Devender Rao /** @brief Check install fails if ceritificate is missing in certificate file 4118841dbd6SMarri Devender Rao */ 4128841dbd6SMarri Devender Rao TEST_F(TestInvalidCertificate, TestMissingCeritificate) 4138841dbd6SMarri Devender Rao { 4148841dbd6SMarri Devender Rao std::string endpoint("ldap"); 4158841dbd6SMarri Devender Rao std::string unit(""); 4168841dbd6SMarri Devender Rao std::string type("client"); 4178841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + keyFile); 4188841dbd6SMarri Devender Rao std::string verifyPath(installPath); 4198841dbd6SMarri Devender Rao std::string verifyUnit(unit); 4208841dbd6SMarri Devender Rao 4218841dbd6SMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 4228841dbd6SMarri Devender Rao EXPECT_THROW( 4238841dbd6SMarri Devender Rao { 4248841dbd6SMarri Devender Rao try 4258841dbd6SMarri Devender Rao { 4268841dbd6SMarri Devender Rao Certificate certificate(bus, objPath, type, unit, installPath, 4278f80c35bSMarri Devender Rao keyFile, false); 4288841dbd6SMarri Devender Rao } 4298841dbd6SMarri Devender Rao catch (const InvalidCertificate& e) 4308841dbd6SMarri Devender Rao { 4318841dbd6SMarri Devender Rao throw; 4328841dbd6SMarri Devender Rao } 4338841dbd6SMarri Devender Rao }, 4348841dbd6SMarri Devender Rao InvalidCertificate); 4358841dbd6SMarri Devender Rao EXPECT_FALSE(fs::exists(verifyPath)); 4368841dbd6SMarri Devender Rao } 4378841dbd6SMarri Devender Rao 4388841dbd6SMarri Devender Rao /** @brief Check if Manager install method fails for invalid certificate file 4398841dbd6SMarri Devender Rao */ 4408841dbd6SMarri Devender Rao TEST_F(TestInvalidCertificate, TestCertManagerInstall) 4418841dbd6SMarri Devender Rao { 4428841dbd6SMarri Devender Rao std::string endpoint("ldap"); 4438841dbd6SMarri Devender Rao std::string unit(""); 4448841dbd6SMarri Devender Rao std::string type("client"); 4458841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 4468841dbd6SMarri Devender Rao std::string verifyPath(installPath); 4478841dbd6SMarri Devender Rao std::string verifyUnit(unit); 4488841dbd6SMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 449*f4682712SMarri Devender Rao auto event = sdeventplus::Event::get_default(); 450*f4682712SMarri Devender Rao Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 4518841dbd6SMarri Devender Rao std::move(installPath)); 452ddf64866SMarri Devender Rao MainApp mainApp(&manager); 453ddf64866SMarri Devender Rao EXPECT_THROW( 454ddf64866SMarri Devender Rao { 455ddf64866SMarri Devender Rao try 456ddf64866SMarri Devender Rao { 457ddf64866SMarri Devender Rao mainApp.install(certificateFile); 458ddf64866SMarri Devender Rao } 459ddf64866SMarri Devender Rao catch (const InvalidCertificate& e) 460ddf64866SMarri Devender Rao { 461ddf64866SMarri Devender Rao throw; 462ddf64866SMarri Devender Rao } 463ddf64866SMarri Devender Rao }, 464ddf64866SMarri Devender Rao InvalidCertificate); 465ddf64866SMarri Devender Rao EXPECT_FALSE(fs::exists(verifyPath)); 466ddf64866SMarri Devender Rao } 467ddf64866SMarri Devender Rao 4688841dbd6SMarri Devender Rao /** @brief Check if error is thrown when multiple certificates are installed 4698841dbd6SMarri Devender Rao * At present only one certificate per service is allowed 470ddf64866SMarri Devender Rao */ 4718841dbd6SMarri Devender Rao TEST_F(TestCertificates, TestCertInstallNotAllowed) 472ddf64866SMarri Devender Rao { 4738841dbd6SMarri Devender Rao using NotAllowed = 4748841dbd6SMarri Devender Rao sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 475ddf64866SMarri Devender Rao std::string endpoint("ldap"); 4768841dbd6SMarri Devender Rao std::string unit(""); 477ddf64866SMarri Devender Rao std::string type("client"); 4788841dbd6SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 4798841dbd6SMarri Devender Rao std::string verifyPath(installPath); 480ddf64866SMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 481*f4682712SMarri Devender Rao auto event = sdeventplus::Event::get_default(); 482*f4682712SMarri Devender Rao Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 4838841dbd6SMarri Devender Rao std::move(installPath)); 484ddf64866SMarri Devender Rao MainApp mainApp(&manager); 4858841dbd6SMarri Devender Rao mainApp.install(certificateFile); 4868841dbd6SMarri Devender Rao EXPECT_TRUE(fs::exists(verifyPath)); 487ddf64866SMarri Devender Rao EXPECT_THROW( 488ddf64866SMarri Devender Rao { 489ddf64866SMarri Devender Rao try 490ddf64866SMarri Devender Rao { 4918841dbd6SMarri Devender Rao // install second certificate 4928841dbd6SMarri Devender Rao mainApp.install(certificateFile); 493ddf64866SMarri Devender Rao } 4948841dbd6SMarri Devender Rao catch (const NotAllowed& e) 495ddf64866SMarri Devender Rao { 496ddf64866SMarri Devender Rao throw; 497ddf64866SMarri Devender Rao } 498ddf64866SMarri Devender Rao }, 4998841dbd6SMarri Devender Rao NotAllowed); 500e6597c5bSMarri Devender Rao } 501*f4682712SMarri Devender Rao 502*f4682712SMarri Devender Rao TEST_F(TestCertificates, TestGenerateCSR) 503*f4682712SMarri Devender Rao { 504*f4682712SMarri Devender Rao std::string endpoint("https"); 505*f4682712SMarri Devender Rao std::string unit(""); 506*f4682712SMarri Devender Rao std::string type("Server"); 507*f4682712SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 508*f4682712SMarri Devender Rao std::string verifyPath(installPath); 509*f4682712SMarri Devender Rao std::string CSRPath(certDir + "/" + CSRFile); 510*f4682712SMarri Devender Rao std::string privateKeyPath(certDir + "/" + privateKeyFile); 511*f4682712SMarri Devender Rao std::vector<std::string> alternativeNames{"localhost1", "localhost2"}; 512*f4682712SMarri Devender Rao std::string challengePassword("0penBmc"); 513*f4682712SMarri Devender Rao std::string city("HYB"); 514*f4682712SMarri Devender Rao std::string commonName("abc.com"); 515*f4682712SMarri Devender Rao std::string contactPerson("Admin"); 516*f4682712SMarri Devender Rao std::string country("IN"); 517*f4682712SMarri Devender Rao std::string email("admin@in.ibm.com"); 518*f4682712SMarri Devender Rao std::string givenName("givenName"); 519*f4682712SMarri Devender Rao std::string initials("G"); 520*f4682712SMarri Devender Rao int64_t keyBitLength(2048); 521*f4682712SMarri Devender Rao std::string keyCurveId("0"); 522*f4682712SMarri Devender Rao std::string keyPairAlgorithm("RSA"); 523*f4682712SMarri Devender Rao std::vector<std::string> keyUsage{"serverAuth", "clientAuth"}; 524*f4682712SMarri Devender Rao std::string organization("IBM"); 525*f4682712SMarri Devender Rao std::string organizationalUnit("ISDL"); 526*f4682712SMarri Devender Rao std::string state("TS"); 527*f4682712SMarri Devender Rao std::string surname("surname"); 528*f4682712SMarri Devender Rao std::string unstructuredName("unstructuredName"); 529*f4682712SMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 530*f4682712SMarri Devender Rao auto event = sdeventplus::Event::get_default(); 531*f4682712SMarri Devender Rao Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 532*f4682712SMarri Devender Rao std::move(installPath)); 533*f4682712SMarri Devender Rao Status status; 534*f4682712SMarri Devender Rao CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status); 535*f4682712SMarri Devender Rao MainApp mainApp(&manager, &csr); 536*f4682712SMarri Devender Rao mainApp.generateCSR(alternativeNames, challengePassword, city, commonName, 537*f4682712SMarri Devender Rao contactPerson, country, email, givenName, initials, 538*f4682712SMarri Devender Rao keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage, 539*f4682712SMarri Devender Rao organization, organizationalUnit, state, surname, 540*f4682712SMarri Devender Rao unstructuredName); 541*f4682712SMarri Devender Rao std::string csrData(""); 542*f4682712SMarri Devender Rao // generateCSR takes considerable time to create CSR and privateKey Files 543*f4682712SMarri Devender Rao EXPECT_FALSE(fs::exists(CSRPath)); 544*f4682712SMarri Devender Rao EXPECT_FALSE(fs::exists(privateKeyPath)); 545*f4682712SMarri Devender Rao EXPECT_THROW( 546*f4682712SMarri Devender Rao { 547*f4682712SMarri Devender Rao try 548*f4682712SMarri Devender Rao { 549*f4682712SMarri Devender Rao csrData = csr.cSR(); 550*f4682712SMarri Devender Rao } 551*f4682712SMarri Devender Rao catch (const InternalFailure& e) 552*f4682712SMarri Devender Rao { 553*f4682712SMarri Devender Rao throw; 554*f4682712SMarri Devender Rao } 555*f4682712SMarri Devender Rao }, 556*f4682712SMarri Devender Rao InternalFailure); 557*f4682712SMarri Devender Rao // wait for 10 sec to get CSR and privateKey Files generated 558*f4682712SMarri Devender Rao sleep(10); 559*f4682712SMarri Devender Rao EXPECT_TRUE(fs::exists(CSRPath)); 560*f4682712SMarri Devender Rao EXPECT_TRUE(fs::exists(privateKeyPath)); 561*f4682712SMarri Devender Rao csrData = csr.cSR(); 562*f4682712SMarri Devender Rao ASSERT_NE("", csrData.c_str()); 563*f4682712SMarri Devender Rao } 564*f4682712SMarri Devender Rao 565*f4682712SMarri Devender Rao TEST_F(TestCertificates, TestGenerateCSRError) 566*f4682712SMarri Devender Rao { 567*f4682712SMarri Devender Rao std::string endpoint("https"); 568*f4682712SMarri Devender Rao std::string unit(""); 569*f4682712SMarri Devender Rao std::string type("Server"); 570*f4682712SMarri Devender Rao std::string installPath(certDir + "/" + certificateFile); 571*f4682712SMarri Devender Rao std::string verifyPath(installPath); 572*f4682712SMarri Devender Rao std::string CSRPath(certDir + "/" + CSRFile); 573*f4682712SMarri Devender Rao std::string privateKeyPath(certDir + "/" + privateKeyFile); 574*f4682712SMarri Devender Rao std::vector<std::string> alternativeNames{"localhost1", "localhost2"}; 575*f4682712SMarri Devender Rao std::string challengePassword("0penBmc"); 576*f4682712SMarri Devender Rao std::string city; 577*f4682712SMarri Devender Rao std::string commonName; 578*f4682712SMarri Devender Rao std::string contactPerson; 579*f4682712SMarri Devender Rao std::string country; 580*f4682712SMarri Devender Rao std::string email; 581*f4682712SMarri Devender Rao std::string givenName; 582*f4682712SMarri Devender Rao std::string initials; 583*f4682712SMarri Devender Rao int64_t keyBitLength(12); 584*f4682712SMarri Devender Rao std::string keyCurveId; 585*f4682712SMarri Devender Rao std::string keyPairAlgorithm; 586*f4682712SMarri Devender Rao std::vector<std::string> keyUsage{"serverAuth", "clientAuth"}; 587*f4682712SMarri Devender Rao std::string organization; 588*f4682712SMarri Devender Rao std::string organizationalUnit; 589*f4682712SMarri Devender Rao std::string state; 590*f4682712SMarri Devender Rao std::string surname; 591*f4682712SMarri Devender Rao std::string unstructuredName; 592*f4682712SMarri Devender Rao auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint; 593*f4682712SMarri Devender Rao auto event = sdeventplus::Event::get_default(); 594*f4682712SMarri Devender Rao Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 595*f4682712SMarri Devender Rao std::move(installPath)); 596*f4682712SMarri Devender Rao Status status; 597*f4682712SMarri Devender Rao CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status); 598*f4682712SMarri Devender Rao MainApp mainApp(&manager, &csr); 599*f4682712SMarri Devender Rao mainApp.generateCSR(alternativeNames, challengePassword, city, commonName, 600*f4682712SMarri Devender Rao contactPerson, country, email, givenName, initials, 601*f4682712SMarri Devender Rao keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage, 602*f4682712SMarri Devender Rao organization, organizationalUnit, state, surname, 603*f4682712SMarri Devender Rao unstructuredName); 604*f4682712SMarri Devender Rao sleep(10); 605*f4682712SMarri Devender Rao EXPECT_FALSE(fs::exists(CSRPath)); 606*f4682712SMarri Devender Rao EXPECT_FALSE(fs::exists(privateKeyPath)); 607*f4682712SMarri Devender Rao } 608