1 #include "config.h" 2 3 #include "certificate.hpp" 4 #include "certs_manager.hpp" 5 6 #include <openssl/bio.h> 7 #include <openssl/crypto.h> 8 #include <openssl/err.h> 9 #include <openssl/evp.h> 10 #include <openssl/pem.h> 11 #include <openssl/x509v3.h> 12 13 #include <algorithm> 14 #include <filesystem> 15 #include <fstream> 16 #include <iterator> 17 #include <sdeventplus/event.hpp> 18 #include <string> 19 #include <xyz/openbmc_project/Certs/error.hpp> 20 #include <xyz/openbmc_project/Common/error.hpp> 21 22 #include <gtest/gtest.h> 23 24 namespace phosphor::certs 25 { 26 namespace 27 { 28 namespace fs = std::filesystem; 29 using ::sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate; 30 using ::sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 31 32 /** 33 * Class to generate certificate file and test verification of certificate file 34 */ 35 class TestCertificates : public ::testing::Test 36 { 37 public: 38 TestCertificates() : bus(sdbusplus::bus::new_default()) 39 { 40 } 41 void SetUp() override 42 { 43 char dirTemplate[] = "/tmp/FakeCerts.XXXXXX"; 44 auto dirPtr = mkdtemp(dirTemplate); 45 if (dirPtr == nullptr) 46 { 47 throw std::bad_alloc(); 48 } 49 certDir = std::string(dirPtr) + "/certs"; 50 fs::create_directories(certDir); 51 52 createNewCertificate(); 53 } 54 55 void TearDown() override 56 { 57 fs::remove_all(certDir); 58 fs::remove(certificateFile); 59 fs::remove(CSRFile); 60 fs::remove(privateKeyFile); 61 fs::remove_all("demoCA"); 62 } 63 64 void createNewCertificate(bool setNewCertId = false) 65 { 66 certificateFile = "cert.pem"; 67 CSRFile = "domain.csr"; 68 privateKeyFile = "privkey.pem"; 69 rsaPrivateKeyFilePath = certDir + "/.rsaprivkey.pem"; 70 std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 "; 71 cmd += "-keyout cert.pem -out cert.pem -days 365000 -nodes"; 72 cmd += " -subj /O=openbmc-project.xyz/CN=localhost"; 73 74 if (setNewCertId) 75 { 76 cmd += std::to_string(certId++); 77 } 78 79 auto val = std::system(cmd.c_str()); 80 if (val) 81 { 82 std::cout << "COMMAND Error: " << val << std::endl; 83 } 84 } 85 86 void createNeverExpiredRootCertificate() 87 { 88 // remove the old cert 89 fs::remove(certificateFile); 90 91 // The following routines create a cert that has NotBefore 92 // set to 1970/01/01 and NotAfter set to 9999/12/31 via the 93 // OpenSSL CA application. 94 certificateFile = "cert.pem"; 95 ASSERT_EQ(std::system("mkdir -p demoCA"), 0); 96 ASSERT_EQ(std::system("mkdir -p demoCA/private/"), 0); 97 ASSERT_EQ(std::system("mkdir -p demoCA/newcerts/"), 0); 98 ASSERT_EQ(std::system("touch demoCA/index.txt"), 0); 99 ASSERT_EQ(std::system("echo 1000 > demoCA/serial"), 0); 100 ASSERT_EQ( 101 std::system( 102 "openssl req -x509 -sha256 -newkey rsa:2048 -keyout " 103 "demoCA/private/cakey.pem -out demoCA/cacert.pem -nodes " 104 "-subj /O=openbmc-project.xyz/C=US/ST=CA/CN=localhost-ca"), 105 0); 106 ASSERT_EQ(std::system( 107 "openssl req -new -newkey rsa:2048 -nodes -keyout " 108 "demoCA/server.key -out demoCA/server.csr -subj " 109 "/O=openbmc-project.xyz/C=US/ST=CA/CN=localhost-server"), 110 0); 111 ASSERT_EQ( 112 std::system( 113 "openssl ca -batch -startdate 19700101000000Z -enddate " 114 "99991231235959Z -out cert.pem -infiles demoCA/server.csr"), 115 0); 116 } 117 118 bool compareFiles(const std::string& file1, const std::string& file2) 119 { 120 std::ifstream f1(file1, std::ifstream::binary | std::ifstream::ate); 121 std::ifstream f2(file2, std::ifstream::binary | std::ifstream::ate); 122 123 if (f1.fail() || f2.fail()) 124 { 125 return false; // file problem 126 } 127 128 if (f1.tellg() != f2.tellg()) 129 { 130 return false; // size mismatch 131 } 132 133 // seek back to beginning and use std::equal to compare contents 134 f1.seekg(0, std::ifstream::beg); 135 f2.seekg(0, std::ifstream::beg); 136 return std::equal(std::istreambuf_iterator<char>(f1.rdbuf()), 137 std::istreambuf_iterator<char>(), 138 std::istreambuf_iterator<char>(f2.rdbuf())); 139 } 140 141 std::string getCertSubjectNameHash(const std::string& certFilePath) 142 { 143 std::unique_ptr<X509, decltype(&::X509_free)> cert(X509_new(), 144 ::X509_free); 145 if (!cert) 146 { 147 std::string(); 148 } 149 150 std::unique_ptr<BIO, decltype(&::BIO_free)> bioCert( 151 BIO_new_file(certFilePath.c_str(), "rb"), ::BIO_free); 152 if (!bioCert) 153 { 154 std::string(); 155 } 156 157 X509* x509 = cert.get(); 158 if (!PEM_read_bio_X509(bioCert.get(), &x509, nullptr, nullptr)) 159 { 160 std::string(); 161 } 162 163 unsigned long hash = X509_subject_name_hash(cert.get()); 164 static constexpr auto AUTH_CERT_HASH_LENGTH = 9; 165 char hashBuf[AUTH_CERT_HASH_LENGTH]; 166 sprintf(hashBuf, "%08lx", hash); 167 return std::string(hashBuf); 168 } 169 170 protected: 171 sdbusplus::bus::bus bus; 172 std::string certificateFile, CSRFile, privateKeyFile, rsaPrivateKeyFilePath; 173 174 std::string certDir; 175 uint64_t certId; 176 }; 177 178 class MainApp 179 { 180 public: 181 MainApp(phosphor::certs::Manager* manager, 182 phosphor::certs::CSR* csr = nullptr) : 183 manager(manager), 184 csr_(csr) 185 { 186 } 187 void install(std::string& path) 188 { 189 manager->install(path); 190 } 191 void delete_() 192 { 193 manager->deleteAll(); 194 } 195 196 std::string generateCSR(std::vector<std::string> alternativeNames, 197 std::string challengePassword, std::string city, 198 std::string commonName, std::string contactPerson, 199 std::string country, std::string email, 200 std::string givenName, std::string initials, 201 int64_t keyBitLength, std::string keyCurveId, 202 std::string keyPairAlgorithm, 203 std::vector<std::string> keyUsage, 204 std::string organization, 205 std::string organizationalUnit, std::string state, 206 std::string surname, std::string unstructuredName) 207 { 208 return (manager->generateCSR( 209 alternativeNames, challengePassword, city, commonName, 210 contactPerson, country, email, givenName, initials, keyBitLength, 211 keyCurveId, keyPairAlgorithm, keyUsage, organization, 212 organizationalUnit, state, surname, unstructuredName)); 213 } 214 std::string csr() 215 { 216 return (csr_->csr()); 217 } 218 phosphor::certs::Manager* manager; 219 phosphor::certs::CSR* csr_; 220 }; 221 222 /** @brief Check if server install routine is invoked for server setup 223 */ 224 TEST_F(TestCertificates, InvokeServerInstall) 225 { 226 std::string endpoint("https"); 227 std::string unit; 228 CertificateType type = CertificateType::Server; 229 std::string installPath(certDir + "/" + certificateFile); 230 std::string verifyPath(installPath); 231 std::string verifyUnit(unit); 232 auto objPath = std::string(objectNamePrefix) + '/' + 233 certificateTypeToString(type) + '/' + endpoint; 234 auto event = sdeventplus::Event::get_default(); 235 // Attach the bus to sd_event to service user requests 236 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 237 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 238 std::move(installPath)); 239 MainApp mainApp(&manager); 240 mainApp.install(certificateFile); 241 EXPECT_TRUE(fs::exists(verifyPath)); 242 } 243 244 /** @brief Check if client install routine is invoked for client setup 245 */ 246 TEST_F(TestCertificates, InvokeClientInstall) 247 { 248 std::string endpoint("ldap"); 249 std::string unit; 250 CertificateType type = CertificateType::Server; 251 std::string installPath(certDir + "/" + certificateFile); 252 std::string verifyPath(installPath); 253 std::string verifyUnit(unit); 254 auto objPath = std::string(objectNamePrefix) + '/' + 255 certificateTypeToString(type) + '/' + endpoint; 256 auto event = sdeventplus::Event::get_default(); 257 // Attach the bus to sd_event to service user requests 258 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 259 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 260 std::move(installPath)); 261 MainApp mainApp(&manager); 262 mainApp.install(certificateFile); 263 EXPECT_TRUE(fs::exists(verifyPath)); 264 } 265 266 /** @brief Check if storage install routine is invoked for storage setup 267 */ 268 TEST_F(TestCertificates, InvokeAuthorityInstall) 269 { 270 std::string endpoint("ldap"); 271 std::string unit; 272 CertificateType type = CertificateType::Authority; 273 std::string verifyDir(certDir); 274 std::string verifyUnit(unit); 275 auto objPath = std::string(objectNamePrefix) + '/' + 276 certificateTypeToString(type) + '/' + endpoint; 277 auto event = sdeventplus::Event::get_default(); 278 // Attach the bus to sd_event to service user requests 279 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 280 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 281 std::move(certDir)); 282 MainApp mainApp(&manager); 283 // install the default certificate that's valid from today to 100 years 284 // later 285 mainApp.install(certificateFile); 286 287 std::vector<std::unique_ptr<Certificate>>& certs = 288 manager.getCertificates(); 289 290 ASSERT_EQ(certs.size(), 1); 291 // check some attributes as well 292 EXPECT_EQ(certs.front()->validNotAfter() - certs.front()->validNotBefore(), 293 365000ULL * 24 * 3600); 294 EXPECT_EQ(certs.front()->subject(), "O=openbmc-project.xyz,CN=localhost"); 295 EXPECT_EQ(certs.front()->issuer(), "O=openbmc-project.xyz,CN=localhost"); 296 297 std::string verifyPath = 298 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0"; 299 300 // Check that certificate has been created at installation directory 301 EXPECT_FALSE(fs::is_empty(verifyDir)); 302 EXPECT_TRUE(fs::exists(verifyPath)); 303 304 // Check that installed cert is identical to input one 305 EXPECT_TRUE(compareFiles(certificateFile, verifyPath)); 306 } 307 308 /** @brief Check if storage install routine is invoked for storage setup 309 */ 310 TEST_F(TestCertificates, InvokeAuthorityInstallNeverExpiredRootCert) 311 { 312 std::string endpoint("ldap"); 313 std::string unit; 314 CertificateType type = CertificateType::Authority; 315 std::string verifyDir(certDir); 316 std::string verifyUnit(unit); 317 auto objPath = std::string(objectNamePrefix) + '/' + 318 certificateTypeToString(type) + '/' + endpoint; 319 auto event = sdeventplus::Event::get_default(); 320 // Attach the bus to sd_event to service user requests 321 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 322 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 323 std::move(certDir)); 324 MainApp mainApp(&manager); 325 326 // install the certificate that's valid from the Unix Epoch to Dec 31, 9999 327 createNeverExpiredRootCertificate(); 328 mainApp.install(certificateFile); 329 330 std::vector<std::unique_ptr<Certificate>>& certs = 331 manager.getCertificates(); 332 333 EXPECT_EQ(certs.front()->validNotBefore(), 0); 334 EXPECT_EQ(certs.front()->validNotAfter(), 253402300799ULL); 335 336 std::string verifyPath = 337 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0"; 338 339 // Check that certificate has been created at installation directory 340 EXPECT_FALSE(fs::is_empty(verifyDir)); 341 EXPECT_TRUE(fs::exists(verifyPath)); 342 343 // Check that installed cert is identical to input one 344 EXPECT_TRUE(compareFiles(certificateFile, verifyPath)); 345 } 346 347 /** @brief Check if in authority mode user can't install the same 348 * certificate twice. 349 */ 350 TEST_F(TestCertificates, InvokeInstallSameCertTwice) 351 { 352 std::string endpoint("ldap"); 353 std::string unit; 354 CertificateType type = CertificateType::Authority; 355 std::string verifyDir(certDir); 356 std::string verifyUnit(unit); 357 auto objPath = std::string(objectNamePrefix) + '/' + 358 certificateTypeToString(type) + '/' + endpoint; 359 auto event = sdeventplus::Event::get_default(); 360 // Attach the bus to sd_event to service user requests 361 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 362 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 363 std::move(certDir)); 364 MainApp mainApp(&manager); 365 mainApp.install(certificateFile); 366 367 std::vector<std::unique_ptr<Certificate>>& certs = 368 manager.getCertificates(); 369 370 EXPECT_FALSE(certs.empty()); 371 372 // Check that certificate has been created at installation directory 373 std::string verifyPath = 374 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0"; 375 EXPECT_FALSE(fs::is_empty(verifyDir)); 376 EXPECT_TRUE(fs::exists(verifyPath)); 377 378 // Check that installed cert is identical to input one 379 EXPECT_TRUE(compareFiles(certificateFile, verifyPath)); 380 381 using NotAllowed = 382 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 383 EXPECT_THROW( 384 { 385 try 386 { 387 // Try to install the same certificate second time 388 mainApp.install(certificateFile); 389 } 390 catch (const NotAllowed& e) 391 { 392 throw; 393 } 394 }, 395 NotAllowed); 396 397 // Check that the original certificate has been not removed 398 EXPECT_FALSE(fs::is_empty(verifyDir)); 399 EXPECT_TRUE(fs::exists(verifyPath)); 400 } 401 402 /** @brief Check if in authority mode user can install a certificate with 403 * certain subject hash twice. 404 */ 405 TEST_F(TestCertificates, InvokeInstallSameSubjectTwice) 406 { 407 std::string endpoint("ldap"); 408 std::string unit; 409 CertificateType type = CertificateType::Authority; 410 std::string verifyDir(certDir); 411 std::string verifyUnit(unit); 412 auto objPath = std::string(objectNamePrefix) + '/' + 413 certificateTypeToString(type) + '/' + endpoint; 414 auto event = sdeventplus::Event::get_default(); 415 // Attach the bus to sd_event to service user requests 416 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 417 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 418 std::move(certDir)); 419 MainApp mainApp(&manager); 420 mainApp.install(certificateFile); 421 422 std::vector<std::unique_ptr<Certificate>>& certs = 423 manager.getCertificates(); 424 425 EXPECT_FALSE(certs.empty()); 426 427 // Check that certificate has been created at installation directory 428 std::string verifyPath0 = 429 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0"; 430 EXPECT_FALSE(fs::is_empty(verifyDir)); 431 EXPECT_TRUE(fs::exists(verifyPath0)); 432 433 // Check that installed cert is identical to input one 434 EXPECT_TRUE(compareFiles(certificateFile, verifyPath0)); 435 436 // Prepare second certificate with the same subject 437 createNewCertificate(); 438 439 // Install second certificate 440 mainApp.install(certificateFile); 441 442 // Expect there are exactly two certificates in the collection 443 EXPECT_EQ(certs.size(), 2); 444 445 // Check that certificate has been created at installation directory 446 std::string verifyPath1 = 447 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".1"; 448 EXPECT_TRUE(fs::exists(verifyPath1)); 449 450 // Check that installed cert is identical to input one 451 EXPECT_TRUE(compareFiles(certificateFile, verifyPath1)); 452 453 // Check that the original/first certificate has been not removed 454 EXPECT_FALSE(fs::is_empty(verifyDir)); 455 EXPECT_TRUE(fs::exists(verifyPath0)); 456 } 457 458 /** @brief Check if in authority mode user can't install more than 459 * maxNumAuthorityCertificates certificates. 460 */ 461 TEST_F(TestCertificates, InvokeInstallAuthCertLimit) 462 { 463 std::string endpoint("ldap"); 464 std::string unit; 465 CertificateType type = CertificateType::Authority; 466 std::string verifyDir(certDir); 467 std::string verifyUnit(unit); 468 auto objPath = std::string(objectNamePrefix) + '/' + 469 certificateTypeToString(type) + '/' + endpoint; 470 auto event = sdeventplus::Event::get_default(); 471 // Attach the bus to sd_event to service user requests 472 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 473 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 474 std::move(certDir)); 475 MainApp mainApp(&manager); 476 477 std::vector<std::unique_ptr<Certificate>>& certs = 478 manager.getCertificates(); 479 480 std::vector<std::string> verifyPaths; 481 482 // Prepare maximum number of ceritificates 483 for (std::size_t i = 0; i < maxNumAuthorityCertificates; ++i) 484 { 485 // Prepare new certificatate 486 createNewCertificate(true); 487 488 // Install ceritificate 489 mainApp.install(certificateFile); 490 491 // Check number of certificates in the collection 492 EXPECT_EQ(certs.size(), i + 1); 493 494 // Check that certificate has been created at installation directory 495 std::string verifyPath = 496 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0"; 497 EXPECT_FALSE(fs::is_empty(verifyDir)); 498 EXPECT_TRUE(fs::exists(verifyPath)); 499 500 // Check that installed cert is identical to input one 501 EXPECT_TRUE(compareFiles(certificateFile, verifyPath)); 502 503 // Save current certificate file for later check 504 verifyPaths.push_back(verifyPath); 505 } 506 507 // Prepare new certificatate 508 createNewCertificate(true); 509 510 using NotAllowed = 511 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 512 EXPECT_THROW( 513 { 514 try 515 { 516 // Try to install one more certificate 517 mainApp.install(certificateFile); 518 } 519 catch (const NotAllowed& e) 520 { 521 throw; 522 } 523 }, 524 NotAllowed); 525 526 // Check that the original certificate has been not removed 527 EXPECT_FALSE(fs::is_empty(verifyDir)); 528 for (size_t i = 0; i < maxNumAuthorityCertificates; ++i) 529 { 530 EXPECT_TRUE(fs::exists(verifyPaths[i])); 531 } 532 } 533 534 /** @brief Compare the installed certificate with the copied certificate 535 */ 536 TEST_F(TestCertificates, CompareInstalledCertificate) 537 { 538 std::string endpoint("ldap"); 539 std::string unit; 540 CertificateType type = CertificateType::Client; 541 ; 542 std::string installPath(certDir + "/" + certificateFile); 543 std::string verifyPath(installPath); 544 std::string verifyUnit(unit); 545 auto objPath = std::string(objectNamePrefix) + '/' + 546 certificateTypeToString(type) + '/' + endpoint; 547 auto event = sdeventplus::Event::get_default(); 548 // Attach the bus to sd_event to service user requests 549 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 550 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 551 std::move(installPath)); 552 MainApp mainApp(&manager); 553 mainApp.install(certificateFile); 554 EXPECT_TRUE(fs::exists(verifyPath)); 555 EXPECT_TRUE(compareFiles(verifyPath, certificateFile)); 556 } 557 558 /** @brief Check if install fails if certificate file is not found 559 */ 560 TEST_F(TestCertificates, TestNoCertificateFile) 561 { 562 std::string endpoint("ldap"); 563 std::string unit; 564 CertificateType type = CertificateType::Client; 565 ; 566 std::string installPath(certDir + "/" + certificateFile); 567 std::string verifyPath(installPath); 568 std::string verifyUnit(unit); 569 auto objPath = std::string(objectNamePrefix) + '/' + 570 certificateTypeToString(type) + '/' + endpoint; 571 std::string uploadFile = "nofile.pem"; 572 EXPECT_THROW( 573 { 574 try 575 { 576 auto event = sdeventplus::Event::get_default(); 577 // Attach the bus to sd_event to service user requests 578 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 579 Manager manager(bus, event, objPath.c_str(), type, 580 std::move(unit), std::move(installPath)); 581 MainApp mainApp(&manager); 582 mainApp.install(uploadFile); 583 } 584 catch (const InternalFailure& e) 585 { 586 throw; 587 } 588 }, 589 InternalFailure); 590 EXPECT_FALSE(fs::exists(verifyPath)); 591 } 592 593 /** @brief Test replacing existing certificate 594 */ 595 TEST_F(TestCertificates, TestReplaceCertificate) 596 { 597 std::string endpoint("ldap"); 598 std::string unit; 599 CertificateType type = CertificateType::Server; 600 std::string installPath(certDir + "/" + certificateFile); 601 std::string verifyPath(installPath); 602 auto objPath = std::string(objectNamePrefix) + '/' + 603 certificateTypeToString(type) + '/' + endpoint; 604 auto event = sdeventplus::Event::get_default(); 605 // Attach the bus to sd_event to service user requests 606 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 607 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 608 std::move(installPath)); 609 MainApp mainApp(&manager); 610 mainApp.install(certificateFile); 611 EXPECT_TRUE(fs::exists(verifyPath)); 612 std::vector<std::unique_ptr<Certificate>>& certs = 613 manager.getCertificates(); 614 EXPECT_FALSE(certs.empty()); 615 EXPECT_NE(certs[0], nullptr); 616 certs[0]->replace(certificateFile); 617 EXPECT_TRUE(fs::exists(verifyPath)); 618 } 619 620 /** @brief Test replacing existing certificate 621 */ 622 TEST_F(TestCertificates, TestAuthorityReplaceCertificate) 623 { 624 std::string endpoint("ldap"); 625 std::string unit; 626 CertificateType type = CertificateType::Authority; 627 std::string verifyDir(certDir); 628 std::string verifyUnit(unit); 629 auto objPath = std::string(objectNamePrefix) + '/' + 630 certificateTypeToString(type) + '/' + endpoint; 631 auto event = sdeventplus::Event::get_default(); 632 // Attach the bus to sd_event to service user requests 633 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 634 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 635 std::move(certDir)); 636 MainApp mainApp(&manager); 637 mainApp.install(certificateFile); 638 639 std::vector<std::unique_ptr<Certificate>>& certs = 640 manager.getCertificates(); 641 constexpr const unsigned int REPLACE_ITERATIONS = 10; 642 643 for (unsigned int i = 0; i < REPLACE_ITERATIONS; i++) 644 { 645 // Certificate successfully installed 646 EXPECT_FALSE(certs.empty()); 647 648 std::string verifyPath = 649 verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0"; 650 651 // Check that certificate has been created at installation directory 652 EXPECT_FALSE(fs::is_empty(verifyDir)); 653 EXPECT_TRUE(fs::exists(verifyPath)); 654 655 // Check that installed cert is identical to input one 656 EXPECT_TRUE(compareFiles(certificateFile, verifyPath)); 657 658 // Create new certificate 659 createNewCertificate(true); 660 661 certs[0]->replace(certificateFile); 662 663 // Verify that old certificate has been removed 664 EXPECT_FALSE(fs::exists(verifyPath)); 665 } 666 } 667 668 /** @brief Test verifiing if delete function works. 669 */ 670 TEST_F(TestCertificates, TestStorageDeleteCertificate) 671 { 672 std::string endpoint("ldap"); 673 std::string unit; 674 CertificateType type = CertificateType::Authority; 675 std::string verifyDir(certDir); 676 std::string verifyUnit(unit); 677 auto objPath = std::string(objectNamePrefix) + '/' + 678 certificateTypeToString(type) + '/' + endpoint; 679 auto event = sdeventplus::Event::get_default(); 680 // Attach the bus to sd_event to service user requests 681 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 682 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 683 std::move(certDir)); 684 MainApp mainApp(&manager); 685 686 // Check if certificate placeholder dir is empty 687 EXPECT_TRUE(fs::is_empty(verifyDir)); 688 mainApp.install(certificateFile); 689 690 // Create new certificate 691 createNewCertificate(true); 692 mainApp.install(certificateFile); 693 694 createNewCertificate(true); 695 mainApp.install(certificateFile); 696 697 std::vector<std::unique_ptr<Certificate>>& certs = 698 manager.getCertificates(); 699 700 // All 3 certificates successfully installed and added to manager 701 EXPECT_EQ(certs.size(), 3); 702 703 // Check if certificate placeholder is not empty, there should be 3 704 // certificates 705 EXPECT_FALSE(fs::is_empty(verifyDir)); 706 707 certs[0]->delete_(); 708 EXPECT_EQ(certs.size(), 2); 709 710 certs[0]->delete_(); 711 EXPECT_EQ(certs.size(), 1); 712 713 certs[0]->delete_(); 714 EXPECT_EQ(certs.size(), 0); 715 716 // Check if certificate placeholder is empty. 717 EXPECT_TRUE(fs::is_empty(verifyDir)); 718 } 719 720 /** @brief Check if install fails if certificate file is empty 721 */ 722 TEST_F(TestCertificates, TestEmptyCertificateFile) 723 { 724 std::string endpoint("ldap"); 725 std::string unit; 726 CertificateType type = CertificateType::Client; 727 ; 728 std::string installPath(certDir + "/" + certificateFile); 729 std::string verifyPath(installPath); 730 std::string verifyUnit(unit); 731 auto objPath = std::string(objectNamePrefix) + '/' + 732 certificateTypeToString(type) + '/' + endpoint; 733 std::string emptyFile("emptycert.pem"); 734 std::ofstream ofs; 735 ofs.open(emptyFile, std::ofstream::out); 736 ofs.close(); 737 EXPECT_THROW( 738 { 739 try 740 { 741 auto event = sdeventplus::Event::get_default(); 742 // Attach the bus to sd_event to service user requests 743 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 744 Manager manager(bus, event, objPath.c_str(), type, 745 std::move(unit), std::move(installPath)); 746 MainApp mainApp(&manager); 747 mainApp.install(emptyFile); 748 } 749 catch (const InvalidCertificate& e) 750 { 751 throw; 752 } 753 }, 754 InvalidCertificate); 755 EXPECT_FALSE(fs::exists(verifyPath)); 756 fs::remove(emptyFile); 757 } 758 759 /** @brief Check if install fails if certificate file is corrupted 760 */ 761 TEST_F(TestCertificates, TestInvalidCertificateFile) 762 { 763 std::string endpoint("ldap"); 764 std::string unit; 765 CertificateType type = CertificateType::Client; 766 ; 767 768 std::ofstream ofs; 769 ofs.open(certificateFile, std::ofstream::out); 770 ofs << "-----BEGIN CERTIFICATE-----"; 771 ofs << "ADD_SOME_INVALID_DATA_INTO_FILE"; 772 ofs << "-----END CERTIFICATE-----"; 773 ofs.close(); 774 775 std::string installPath(certDir + "/" + certificateFile); 776 std::string verifyPath(installPath); 777 std::string verifyUnit(unit); 778 auto objPath = std::string(objectNamePrefix) + '/' + 779 certificateTypeToString(type) + '/' + endpoint; 780 EXPECT_THROW( 781 { 782 try 783 { 784 auto event = sdeventplus::Event::get_default(); 785 // Attach the bus to sd_event to service user requests 786 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 787 Manager manager(bus, event, objPath.c_str(), type, 788 std::move(unit), std::move(installPath)); 789 MainApp mainApp(&manager); 790 mainApp.install(certificateFile); 791 } 792 catch (const InvalidCertificate& e) 793 { 794 throw; 795 } 796 }, 797 InvalidCertificate); 798 EXPECT_FALSE(fs::exists(verifyPath)); 799 } 800 801 /** 802 * Class to generate private and certificate only file and test verification 803 */ 804 class TestInvalidCertificate : public ::testing::Test 805 { 806 public: 807 TestInvalidCertificate() : bus(sdbusplus::bus::new_default()) 808 { 809 } 810 void SetUp() override 811 { 812 char dirTemplate[] = "/tmp/FakeCerts.XXXXXX"; 813 auto dirPtr = mkdtemp(dirTemplate); 814 if (dirPtr == nullptr) 815 { 816 throw std::bad_alloc(); 817 } 818 certDir = std::string(dirPtr) + "/certs"; 819 fs::create_directories(certDir); 820 certificateFile = "cert.pem"; 821 keyFile = "key.pem"; 822 std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 "; 823 cmd += "-keyout key.pem -out cert.pem -days 3650 "; 824 cmd += "-subj " 825 "/O=openbmc-project.xyz/CN=localhost" 826 " -nodes"; 827 828 auto val = std::system(cmd.c_str()); 829 if (val) 830 { 831 std::cout << "command Error: " << val << std::endl; 832 } 833 } 834 void TearDown() override 835 { 836 fs::remove_all(certDir); 837 fs::remove(certificateFile); 838 fs::remove(keyFile); 839 } 840 841 protected: 842 sdbusplus::bus::bus bus; 843 std::string certificateFile; 844 std::string keyFile; 845 std::string certDir; 846 }; 847 848 /** @brief Check install fails if private key is missing in certificate file 849 */ 850 TEST_F(TestInvalidCertificate, TestMissingPrivateKey) 851 { 852 std::string endpoint("ldap"); 853 std::string unit; 854 CertificateType type = CertificateType::Client; 855 ; 856 std::string installPath(certDir + "/" + certificateFile); 857 std::string verifyPath(installPath); 858 std::string verifyUnit(unit); 859 auto objPath = std::string(objectNamePrefix) + '/' + 860 certificateTypeToString(type) + '/' + endpoint; 861 EXPECT_THROW( 862 { 863 try 864 { 865 auto event = sdeventplus::Event::get_default(); 866 // Attach the bus to sd_event to service user requests 867 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 868 Manager manager(bus, event, objPath.c_str(), type, 869 std::move(unit), std::move(installPath)); 870 MainApp mainApp(&manager); 871 mainApp.install(certificateFile); 872 } 873 catch (const InternalFailure& e) 874 { 875 throw; 876 } 877 }, 878 InternalFailure); 879 EXPECT_FALSE(fs::exists(verifyPath)); 880 } 881 882 /** @brief Check install fails if ceritificate is missing in certificate file 883 */ 884 TEST_F(TestInvalidCertificate, TestMissingCeritificate) 885 { 886 std::string endpoint("ldap"); 887 std::string unit; 888 CertificateType type = CertificateType::Client; 889 ; 890 std::string installPath(certDir + "/" + keyFile); 891 std::string verifyPath(installPath); 892 std::string verifyUnit(unit); 893 auto objPath = std::string(objectNamePrefix) + '/' + 894 certificateTypeToString(type) + '/' + endpoint; 895 EXPECT_THROW( 896 { 897 try 898 { 899 auto event = sdeventplus::Event::get_default(); 900 // Attach the bus to sd_event to service user requests 901 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 902 Manager manager(bus, event, objPath.c_str(), type, 903 std::move(unit), std::move(installPath)); 904 MainApp mainApp(&manager); 905 mainApp.install(keyFile); 906 } 907 catch (const InternalFailure& e) 908 { 909 throw; 910 } 911 }, 912 InvalidCertificate); 913 EXPECT_FALSE(fs::exists(verifyPath)); 914 } 915 916 /** @brief Check if error is thrown when multiple certificates are installed 917 * At present only one certificate per service is allowed 918 */ 919 TEST_F(TestCertificates, TestCertInstallNotAllowed) 920 { 921 using NotAllowed = 922 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 923 std::string endpoint("ldap"); 924 std::string unit; 925 CertificateType type = CertificateType::Client; 926 ; 927 std::string installPath(certDir + "/" + certificateFile); 928 std::string verifyPath(installPath); 929 auto objPath = std::string(objectNamePrefix) + '/' + 930 certificateTypeToString(type) + '/' + endpoint; 931 auto event = sdeventplus::Event::get_default(); 932 // Attach the bus to sd_event to service user requests 933 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 934 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 935 std::move(installPath)); 936 MainApp mainApp(&manager); 937 mainApp.install(certificateFile); 938 EXPECT_TRUE(fs::exists(verifyPath)); 939 EXPECT_THROW( 940 { 941 try 942 { 943 // install second certificate 944 mainApp.install(certificateFile); 945 } 946 catch (const NotAllowed& e) 947 { 948 throw; 949 } 950 }, 951 NotAllowed); 952 } 953 954 TEST_F(TestCertificates, TestGenerateCSR) 955 { 956 std::string endpoint("https"); 957 std::string unit; 958 CertificateType type = CertificateType::Server; 959 std::string installPath(certDir + "/" + certificateFile); 960 std::string verifyPath(installPath); 961 std::string CSRPath(certDir + "/" + CSRFile); 962 std::string privateKeyPath(certDir + "/" + privateKeyFile); 963 std::vector<std::string> alternativeNames{"localhost1", "localhost2"}; 964 std::string challengePassword("Password"); 965 std::string city("HYB"); 966 std::string commonName("abc.com"); 967 std::string contactPerson("Admin"); 968 std::string country("IN"); 969 std::string email("admin@in.ibm.com"); 970 std::string givenName("givenName"); 971 std::string initials("G"); 972 int64_t keyBitLength(2048); 973 std::string keyCurveId("0"); 974 std::string keyPairAlgorithm("RSA"); 975 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"}; 976 std::string organization("IBM"); 977 std::string organizationalUnit("orgUnit"); 978 std::string state("TS"); 979 std::string surname("surname"); 980 std::string unstructuredName("unstructuredName"); 981 auto objPath = std::string(objectNamePrefix) + '/' + 982 certificateTypeToString(type) + '/' + endpoint; 983 auto event = sdeventplus::Event::get_default(); 984 // Attach the bus to sd_event to service user requests 985 bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL); 986 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 987 std::move(installPath)); 988 Status status; 989 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status); 990 MainApp mainApp(&manager, &csr); 991 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName, 992 contactPerson, country, email, givenName, initials, 993 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage, 994 organization, organizationalUnit, state, surname, 995 unstructuredName); 996 std::string csrData(""); 997 // generateCSR takes considerable time to create CSR and privateKey Files 998 EXPECT_FALSE(fs::exists(CSRPath)); 999 EXPECT_FALSE(fs::exists(privateKeyPath)); 1000 EXPECT_THROW( 1001 { 1002 try 1003 { 1004 csrData = csr.csr(); 1005 } 1006 catch (const InternalFailure& e) 1007 { 1008 throw; 1009 } 1010 }, 1011 InternalFailure); 1012 // wait for 10 sec to get CSR and privateKey Files generated 1013 sleep(10); 1014 EXPECT_TRUE(fs::exists(CSRPath)); 1015 EXPECT_TRUE(fs::exists(privateKeyPath)); 1016 csrData = csr.csr(); 1017 ASSERT_NE("", csrData.c_str()); 1018 } 1019 1020 /** @brief Check if ECC key pair is generated when user is not given algorithm 1021 * type. At present RSA and EC key pair algorithm are supported 1022 */ 1023 TEST_F(TestCertificates, TestGenerateCSRwithEmptyKeyPairAlgorithm) 1024 { 1025 std::string endpoint("https"); 1026 std::string unit; 1027 CertificateType type = CertificateType::Server; 1028 std::string installPath(certDir + "/" + certificateFile); 1029 std::string verifyPath(installPath); 1030 std::string CSRPath(certDir + "/" + CSRFile); 1031 std::string privateKeyPath(certDir + "/" + privateKeyFile); 1032 std::vector<std::string> alternativeNames{"localhost1", "localhost2"}; 1033 std::string challengePassword("Password"); 1034 std::string city("HYB"); 1035 std::string commonName("abc.com"); 1036 std::string contactPerson("Admin"); 1037 std::string country("IN"); 1038 std::string email("admin@in.ibm.com"); 1039 std::string givenName("givenName"); 1040 std::string initials("G"); 1041 int64_t keyBitLength(2048); 1042 std::string keyCurveId(""); 1043 std::string keyPairAlgorithm(""); 1044 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"}; 1045 std::string organization("IBM"); 1046 std::string organizationalUnit("orgUnit"); 1047 std::string state("TS"); 1048 std::string surname("surname"); 1049 std::string unstructuredName("unstructuredName"); 1050 auto objPath = std::string(objectNamePrefix) + '/' + 1051 certificateTypeToString(type) + '/' + endpoint; 1052 auto event = sdeventplus::Event::get_default(); 1053 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 1054 std::move(installPath)); 1055 Status status; 1056 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status); 1057 MainApp mainApp(&manager, &csr); 1058 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName, 1059 contactPerson, country, email, givenName, initials, 1060 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage, 1061 organization, organizationalUnit, state, surname, 1062 unstructuredName); 1063 sleep(10); 1064 EXPECT_TRUE(fs::exists(CSRPath)); 1065 EXPECT_TRUE(fs::exists(privateKeyPath)); 1066 } 1067 1068 /** @brief Check if error is thrown when giving un supported key pair 1069 * algorithm. At present RSA and EC key pair algorithm are supported 1070 */ 1071 TEST_F(TestCertificates, TestGenerateCSRwithUnsupportedKeyPairAlgorithm) 1072 { 1073 std::string endpoint("https"); 1074 std::string unit; 1075 CertificateType type = CertificateType::Server; 1076 std::string installPath(certDir + "/" + certificateFile); 1077 std::string verifyPath(installPath); 1078 std::string CSRPath(certDir + "/" + CSRFile); 1079 std::string privateKeyPath(certDir + "/" + privateKeyFile); 1080 std::vector<std::string> alternativeNames{"localhost1", "localhost2"}; 1081 std::string challengePassword("Password"); 1082 std::string city("HYB"); 1083 std::string commonName("abc.com"); 1084 std::string contactPerson("Admin"); 1085 std::string country("IN"); 1086 std::string email("admin@in.ibm.com"); 1087 std::string givenName("givenName"); 1088 std::string initials("G"); 1089 int64_t keyBitLength(2048); 1090 std::string keyCurveId("secp521r1"); 1091 std::string keyPairAlgorithm("UnSupportedAlgorithm"); 1092 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"}; 1093 std::string organization("IBM"); 1094 std::string organizationalUnit("orgUnit"); 1095 std::string state("TS"); 1096 std::string surname("surname"); 1097 std::string unstructuredName("unstructuredName"); 1098 auto objPath = std::string(objectNamePrefix) + '/' + 1099 certificateTypeToString(type) + '/' + endpoint; 1100 auto event = sdeventplus::Event::get_default(); 1101 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 1102 std::move(installPath)); 1103 Status status; 1104 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status); 1105 MainApp mainApp(&manager, &csr); 1106 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName, 1107 contactPerson, country, email, givenName, initials, 1108 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage, 1109 organization, organizationalUnit, state, surname, 1110 unstructuredName); 1111 EXPECT_FALSE(fs::exists(CSRPath)); 1112 EXPECT_FALSE(fs::exists(privateKeyPath)); 1113 } 1114 1115 /** @brief Check if error is thrown when NID_undef is returned for given key 1116 * curve id 1117 */ 1118 TEST_F(TestCertificates, TestECKeyGenerationwithNIDundefCase) 1119 { 1120 std::string endpoint("https"); 1121 std::string unit; 1122 CertificateType type = CertificateType::Server; 1123 std::string installPath(certDir + "/" + certificateFile); 1124 std::string verifyPath(installPath); 1125 std::string CSRPath(certDir + "/" + CSRFile); 1126 std::string privateKeyPath(certDir + "/" + privateKeyFile); 1127 std::vector<std::string> alternativeNames{"localhost1", "localhost2"}; 1128 std::string challengePassword("Password"); 1129 std::string city("BLR"); 1130 std::string commonName("abc.com"); 1131 std::string contactPerson("Admin"); 1132 std::string country("IN"); 1133 std::string email("admin@in.ibm.com"); 1134 std::string givenName("givenName"); 1135 std::string initials("G"); 1136 int64_t keyBitLength(2048); 1137 std::string keyCurveId("DummyCurveName"); 1138 std::string keyPairAlgorithm("EC"); 1139 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"}; 1140 std::string organization("IBM"); 1141 std::string organizationalUnit("orgUnit"); 1142 std::string state("TS"); 1143 std::string surname("surname"); 1144 std::string unstructuredName("unstructuredName"); 1145 auto objPath = std::string(objectNamePrefix) + '/' + 1146 certificateTypeToString(type) + '/' + endpoint; 1147 auto event = sdeventplus::Event::get_default(); 1148 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 1149 std::move(installPath)); 1150 Status status; 1151 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status); 1152 MainApp mainApp(&manager, &csr); 1153 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName, 1154 contactPerson, country, email, givenName, initials, 1155 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage, 1156 organization, organizationalUnit, state, surname, 1157 unstructuredName); 1158 EXPECT_FALSE(fs::exists(CSRPath)); 1159 EXPECT_FALSE(fs::exists(privateKeyPath)); 1160 } 1161 1162 /** @brief Check default Key Curve Id is used if given curve id is empty 1163 */ 1164 TEST_F(TestCertificates, TestECKeyGenerationwithDefaultKeyCurveId) 1165 { 1166 std::string endpoint("https"); 1167 std::string unit; 1168 CertificateType type = CertificateType::Server; 1169 std::string installPath(certDir + "/" + certificateFile); 1170 std::string verifyPath(installPath); 1171 std::string CSRPath(certDir + "/" + CSRFile); 1172 std::string privateKeyPath(certDir + "/" + privateKeyFile); 1173 std::vector<std::string> alternativeNames{"localhost1", "localhost2"}; 1174 std::string challengePassword("Password"); 1175 std::string city("BLR"); 1176 std::string commonName("abc.com"); 1177 std::string contactPerson("Admin"); 1178 std::string country("IN"); 1179 std::string email("admin@in.ibm.com"); 1180 std::string givenName("givenName"); 1181 std::string initials("G"); 1182 int64_t keyBitLength(2048); 1183 std::string keyCurveId(""); 1184 std::string keyPairAlgorithm("EC"); 1185 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"}; 1186 std::string organization("IBM"); 1187 std::string organizationalUnit("orgUnit"); 1188 std::string state("TS"); 1189 std::string surname("surname"); 1190 std::string unstructuredName("unstructuredName"); 1191 auto objPath = std::string(objectNamePrefix) + '/' + 1192 certificateTypeToString(type) + '/' + endpoint; 1193 auto event = sdeventplus::Event::get_default(); 1194 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 1195 std::move(installPath)); 1196 Status status; 1197 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status); 1198 MainApp mainApp(&manager, &csr); 1199 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName, 1200 contactPerson, country, email, givenName, initials, 1201 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage, 1202 organization, organizationalUnit, state, surname, 1203 unstructuredName); 1204 sleep(10); 1205 EXPECT_TRUE(fs::exists(CSRPath)); 1206 EXPECT_TRUE(fs::exists(privateKeyPath)); 1207 } 1208 1209 /** @brief Check if error is not thrown to generate EC key pair 1210 */ 1211 TEST_F(TestCertificates, TestECKeyGeneration) 1212 { 1213 std::string endpoint("https"); 1214 std::string unit; 1215 CertificateType type = CertificateType::Server; 1216 std::string installPath(certDir + "/" + certificateFile); 1217 std::string verifyPath(installPath); 1218 std::string CSRPath(certDir + "/" + CSRFile); 1219 std::string privateKeyPath(certDir + "/" + privateKeyFile); 1220 std::vector<std::string> alternativeNames{"localhost1", "localhost2"}; 1221 std::string challengePassword("Password"); 1222 std::string city("BLR"); 1223 std::string commonName("abc.com"); 1224 std::string contactPerson("Admin"); 1225 std::string country("IN"); 1226 std::string email("admin@in.ibm.com"); 1227 std::string givenName("givenName"); 1228 std::string initials("G"); 1229 int64_t keyBitLength(2048); 1230 std::string keyCurveId("secp521r1"); 1231 std::string keyPairAlgorithm("EC"); 1232 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"}; 1233 std::string organization("IBM"); 1234 std::string organizationalUnit("orgUnit"); 1235 std::string state("TS"); 1236 std::string surname("surname"); 1237 std::string unstructuredName("unstructuredName"); 1238 auto objPath = std::string(objectNamePrefix) + '/' + 1239 certificateTypeToString(type) + '/' + endpoint; 1240 auto event = sdeventplus::Event::get_default(); 1241 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 1242 std::move(installPath)); 1243 Status status; 1244 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status); 1245 MainApp mainApp(&manager, &csr); 1246 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName, 1247 contactPerson, country, email, givenName, initials, 1248 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage, 1249 organization, organizationalUnit, state, surname, 1250 unstructuredName); 1251 std::cout << "CSRPath: " << CSRPath << std::endl 1252 << "privateKeyPath: " << privateKeyPath << std::endl; 1253 sleep(10); 1254 EXPECT_TRUE(fs::exists(CSRPath)); 1255 EXPECT_TRUE(fs::exists(privateKeyPath)); 1256 } 1257 1258 /** @brief Check error is thrown if giving unsupported key bit length to 1259 * generate rsa key 1260 */ 1261 TEST_F(TestCertificates, TestRSAKeyWithUnsupportedKeyBitLength) 1262 { 1263 std::string endpoint("https"); 1264 std::string unit; 1265 CertificateType type = CertificateType::Server; 1266 std::string installPath(certDir + "/" + certificateFile); 1267 std::string verifyPath(installPath); 1268 std::string CSRPath(certDir + "/" + CSRFile); 1269 std::string privateKeyPath(certDir + "/" + privateKeyFile); 1270 std::vector<std::string> alternativeNames{"localhost1", "localhost2"}; 1271 std::string challengePassword("Password"); 1272 std::string city("BLR"); 1273 std::string commonName("abc.com"); 1274 std::string contactPerson("Admin"); 1275 std::string country("IN"); 1276 std::string email("admin@in.ibm.com"); 1277 std::string givenName("givenName"); 1278 std::string initials("G"); 1279 int64_t keyBitLength(4096); 1280 std::string keyCurveId("secp521r1"); 1281 std::string keyPairAlgorithm("RSA"); 1282 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"}; 1283 std::string organization("IBM"); 1284 std::string organizationalUnit("orgUnit"); 1285 std::string state("TS"); 1286 std::string surname("surname"); 1287 std::string unstructuredName("unstructuredName"); 1288 auto objPath = std::string(objectNamePrefix) + '/' + 1289 certificateTypeToString(type) + '/' + endpoint; 1290 auto event = sdeventplus::Event::get_default(); 1291 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 1292 std::move(installPath)); 1293 Status status; 1294 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status); 1295 MainApp mainApp(&manager, &csr); 1296 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName, 1297 contactPerson, country, email, givenName, initials, 1298 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage, 1299 organization, organizationalUnit, state, surname, 1300 unstructuredName); 1301 EXPECT_FALSE(fs::exists(CSRPath)); 1302 EXPECT_FALSE(fs::exists(privateKeyPath)); 1303 } 1304 1305 /** @brief Check error is thrown if generated rsa key file is not present 1306 */ 1307 TEST_F(TestCertificates, TestRSAKeyFileNotPresentCase) 1308 { 1309 std::string endpoint("https"); 1310 std::string unit; 1311 CertificateType type = CertificateType::Server; 1312 std::string installPath(certDir + "/" + certificateFile); 1313 std::string verifyPath(installPath); 1314 std::string CSRPath(certDir + "/" + CSRFile); 1315 std::string privateKeyPath(certDir + "/" + privateKeyFile); 1316 std::vector<std::string> alternativeNames{"localhost1", "localhost2"}; 1317 std::string challengePassword("Password"); 1318 std::string city("BLR"); 1319 std::string commonName("abc.com"); 1320 std::string contactPerson("Admin"); 1321 std::string country("IN"); 1322 std::string email("admin@in.ibm.com"); 1323 std::string givenName("givenName"); 1324 std::string initials("G"); 1325 int64_t keyBitLength(2048); 1326 std::string keyCurveId("secp521r1"); 1327 std::string keyPairAlgorithm("RSA"); 1328 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"}; 1329 std::string organization("IBM"); 1330 std::string organizationalUnit("orgUnit"); 1331 std::string state("TS"); 1332 std::string surname("surname"); 1333 std::string unstructuredName("unstructuredName"); 1334 auto objPath = std::string(objectNamePrefix) + '/' + 1335 certificateTypeToString(type) + '/' + endpoint; 1336 auto event = sdeventplus::Event::get_default(); 1337 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 1338 std::move(installPath)); 1339 1340 // Removing generated RSA key file 1341 fs::remove(rsaPrivateKeyFilePath); 1342 1343 Status status; 1344 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status); 1345 MainApp mainApp(&manager, &csr); 1346 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName, 1347 contactPerson, country, email, givenName, initials, 1348 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage, 1349 organization, organizationalUnit, state, surname, 1350 unstructuredName); 1351 EXPECT_FALSE(fs::exists(CSRPath)); 1352 EXPECT_FALSE(fs::exists(privateKeyPath)); 1353 } 1354 1355 /** @brief Check private key file is created from generated rsa key file is 1356 * `present 1357 */ 1358 TEST_F(TestCertificates, TestRSAKeyFromRSAKeyFileIsWrittenIntoPrivateKeyFile) 1359 { 1360 std::string endpoint("https"); 1361 std::string unit; 1362 CertificateType type = CertificateType::Server; 1363 std::string installPath(certDir + "/" + certificateFile); 1364 std::string verifyPath(installPath); 1365 std::string CSRPath(certDir + "/" + CSRFile); 1366 std::string privateKeyPath(certDir + "/" + privateKeyFile); 1367 std::vector<std::string> alternativeNames{"localhost1", "localhost2"}; 1368 std::string challengePassword("Password"); 1369 std::string city("BLR"); 1370 std::string commonName("abc.com"); 1371 std::string contactPerson("Admin"); 1372 std::string country("IN"); 1373 std::string email("admin@in.ibm.com"); 1374 std::string givenName("givenName"); 1375 std::string initials("G"); 1376 int64_t keyBitLength(2048); 1377 std::string keyCurveId("secp521r1"); 1378 std::string keyPairAlgorithm("RSA"); 1379 std::vector<std::string> keyUsage{"serverAuth", "clientAuth"}; 1380 std::string organization("IBM"); 1381 std::string organizationalUnit("orgUnit"); 1382 std::string state("TS"); 1383 std::string surname("surname"); 1384 std::string unstructuredName("unstructuredName"); 1385 auto objPath = std::string(objectNamePrefix) + '/' + 1386 certificateTypeToString(type) + '/' + endpoint; 1387 auto event = sdeventplus::Event::get_default(); 1388 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 1389 std::move(installPath)); 1390 Status status; 1391 CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status); 1392 MainApp mainApp(&manager, &csr); 1393 mainApp.generateCSR(alternativeNames, challengePassword, city, commonName, 1394 contactPerson, country, email, givenName, initials, 1395 keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage, 1396 organization, organizationalUnit, state, surname, 1397 unstructuredName); 1398 sleep(10); 1399 EXPECT_TRUE(fs::exists(CSRPath)); 1400 EXPECT_TRUE(fs::exists(privateKeyPath)); 1401 } 1402 1403 /** @brief Check RSA key is generated during application startup*/ 1404 TEST_F(TestCertificates, TestGenerateRSAPrivateKeyFile) 1405 { 1406 std::string endpoint("https"); 1407 std::string unit; 1408 CertificateType type = CertificateType::Server; 1409 std::string installPath(certDir + "/" + certificateFile); 1410 auto objPath = std::string(objectNamePrefix) + '/' + 1411 certificateTypeToString(type) + '/' + endpoint; 1412 auto event = sdeventplus::Event::get_default(); 1413 1414 EXPECT_FALSE(fs::exists(rsaPrivateKeyFilePath)); 1415 Manager manager(bus, event, objPath.c_str(), type, std::move(unit), 1416 std::move(installPath)); 1417 EXPECT_TRUE(fs::exists(rsaPrivateKeyFilePath)); 1418 } 1419 } // namespace 1420 } // namespace phosphor::certs 1421