1 #include "config.h" 2 3 #include "certificate.hpp" 4 5 #include "certs_manager.hpp" 6 #include "x509_utils.hpp" 7 8 #include <openssl/asn1.h> 9 #include <openssl/bio.h> 10 #include <openssl/buffer.h> 11 #include <openssl/err.h> 12 #include <openssl/evp.h> 13 #include <openssl/obj_mac.h> 14 #include <openssl/objects.h> 15 #include <openssl/opensslv.h> 16 #include <openssl/pem.h> 17 #include <openssl/x509v3.h> 18 19 #include <phosphor-logging/elog-errors.hpp> 20 #include <phosphor-logging/elog.hpp> 21 #include <phosphor-logging/lg2.hpp> 22 #include <watch.hpp> 23 #include <xyz/openbmc_project/Certs/error.hpp> 24 #include <xyz/openbmc_project/Common/error.hpp> 25 26 #include <cstdint> 27 #include <cstdio> 28 #include <cstdlib> 29 #include <exception> 30 #include <filesystem> 31 #include <fstream> 32 #include <map> 33 #include <utility> 34 #include <vector> 35 36 namespace phosphor::certs 37 { 38 39 namespace 40 { 41 namespace fs = std::filesystem; 42 using ::phosphor::logging::elog; 43 using InvalidCertificateError = 44 ::sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate; 45 using ::phosphor::logging::xyz::openbmc_project::Certs::InvalidCertificate; 46 using ::sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 47 48 // RAII support for openSSL functions. 49 using BIOMemPtr = std::unique_ptr<BIO, decltype(&::BIO_free)>; 50 using X509StorePtr = std::unique_ptr<X509_STORE, decltype(&::X509_STORE_free)>; 51 using ASN1TimePtr = std::unique_ptr<ASN1_TIME, decltype(&ASN1_STRING_free)>; 52 using EVPPkeyPtr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>; 53 using BufMemPtr = std::unique_ptr<BUF_MEM, decltype(&::BUF_MEM_free)>; 54 55 // Refer to schema 2018.3 56 // http://redfish.dmtf.org/schemas/v1/Certificate.json#/definitions/KeyUsage for 57 // supported KeyUsage types in redfish 58 // Refer to 59 // https://github.com/openssl/openssl/blob/master/include/openssl/x509v3.h for 60 // key usage bit fields 61 std::map<uint8_t, std::string> keyUsageToRfStr = { 62 {KU_DIGITAL_SIGNATURE, "DigitalSignature"}, 63 {KU_NON_REPUDIATION, "NonRepudiation"}, 64 {KU_KEY_ENCIPHERMENT, "KeyEncipherment"}, 65 {KU_DATA_ENCIPHERMENT, "DataEncipherment"}, 66 {KU_KEY_AGREEMENT, "KeyAgreement"}, 67 {KU_KEY_CERT_SIGN, "KeyCertSign"}, 68 {KU_CRL_SIGN, "CRLSigning"}, 69 {KU_ENCIPHER_ONLY, "EncipherOnly"}, 70 {KU_DECIPHER_ONLY, "DecipherOnly"}}; 71 72 // Refer to schema 2018.3 73 // http://redfish.dmtf.org/schemas/v1/Certificate.json#/definitions/KeyUsage for 74 // supported Extended KeyUsage types in redfish 75 std::map<uint8_t, std::string> extendedKeyUsageToRfStr = { 76 {NID_server_auth, "ServerAuthentication"}, 77 {NID_client_auth, "ClientAuthentication"}, 78 {NID_email_protect, "EmailProtection"}, 79 {NID_OCSP_sign, "OCSPSigning"}, 80 {NID_ad_timeStamping, "Timestamping"}, 81 {NID_code_sign, "CodeSigning"}}; 82 83 /** 84 * @brief Dumps the PEM encoded certificate to installFilePath 85 * 86 * @param[in] pem - PEM encoded X509 certificate buffer. 87 * @param[in] certFilePath - Path to the destination file. 88 * 89 * @return void 90 */ 91 92 void dumpCertificate(const std::string& pem, const std::string& certFilePath) 93 { 94 std::ofstream outputCertFileStream; 95 96 outputCertFileStream.exceptions( 97 std::ofstream::failbit | std::ofstream::badbit | std::ofstream::eofbit); 98 99 try 100 { 101 outputCertFileStream.open(certFilePath, std::ios::out); 102 outputCertFileStream << pem << "\n" << std::flush; 103 outputCertFileStream.close(); 104 } 105 catch (const std::exception& e) 106 { 107 lg2::error( 108 "Failed to dump certificate, ERR:{ERR}, SRC_PEM:{SRC_PEM}, DST:{DST}", 109 "ERR", e, "SRC_PEM", pem, "DST", certFilePath); 110 elog<InternalFailure>(); 111 } 112 } 113 } // namespace 114 115 void Certificate::copyCertificate(const std::string& certSrcFilePath, 116 const std::string& certFilePath) 117 { 118 // Copy the certificate to the installation path 119 // During bootup will be parsing existing file so no need to 120 // copy it. 121 if (certSrcFilePath != certFilePath) 122 { 123 // -p flag preserves the file metadata when copying 124 // -f flag forces the copy 125 const std::string command = 126 std::format("cp -fp {} {}", certSrcFilePath, certFilePath); 127 int statusCode = std::system(command.c_str()); 128 129 // Non-zero `status_code` indicates something went wrong with issuing 130 // the copy command. 131 if (statusCode != 0) 132 { 133 lg2::error( 134 "Failed to copy certificate, ERR:{ERR}, SRC:{SRC}, DST:{DST}", 135 "ERR", statusCode, "SRC", certSrcFilePath, "DST", certFilePath); 136 elog<InternalFailure>(); 137 } 138 } 139 } 140 141 std::string 142 Certificate::generateUniqueFilePath(const std::string& directoryPath) 143 { 144 char* filePath = tempnam(directoryPath.c_str(), nullptr); 145 if (filePath == nullptr) 146 { 147 lg2::error( 148 "Error occurred while creating random certificate file path, DIR:{DIR}", 149 "DIR", directoryPath); 150 elog<InternalFailure>(); 151 } 152 std::string filePathStr(filePath); 153 free(filePath); 154 return filePathStr; 155 } 156 157 std::string Certificate::generateAuthCertFileX509Path( 158 const std::string& certSrcFilePath, const std::string& certDstDirPath) 159 { 160 const internal::X509Ptr cert = loadCert(certSrcFilePath); 161 unsigned long hash = X509_subject_name_hash(cert.get()); 162 static constexpr auto certHashLength = 9; 163 char hashBuf[certHashLength]; 164 165 snprintf(hashBuf, certHashLength, "%08lx", hash); 166 167 const std::string certHash(hashBuf); 168 for (size_t i = 0; i < maxNumAuthorityCertificates; ++i) 169 { 170 const std::string certDstFileX509Path = 171 certDstDirPath + "/" + certHash + "." + std::to_string(i); 172 if (!fs::exists(certDstFileX509Path)) 173 { 174 return certDstFileX509Path; 175 } 176 } 177 178 lg2::error("Authority certificate x509 file path already used, DIR:{DIR}", 179 "DIR", certDstDirPath); 180 elog<InternalFailure>(); 181 } 182 183 std::string 184 Certificate::generateAuthCertFilePath(const std::string& certSrcFilePath) 185 { 186 // If there is a certificate file path (which means certificate replacement 187 // is doing) use it (do not create new one) 188 if (!certFilePath.empty()) 189 { 190 return certFilePath; 191 } 192 // If source certificate file is located in the certificates directory use 193 // it (do not create new one) 194 else if (fs::path(certSrcFilePath).parent_path().string() == 195 certInstallPath) 196 { 197 return certSrcFilePath; 198 } 199 // Otherwise generate new file name/path 200 else 201 { 202 return generateUniqueFilePath(certInstallPath); 203 } 204 } 205 206 std::string 207 Certificate::generateCertFilePath(const std::string& certSrcFilePath) 208 { 209 if (certType == CertificateType::authority) 210 { 211 return generateAuthCertFilePath(certSrcFilePath); 212 } 213 else 214 { 215 return certInstallPath; 216 } 217 } 218 219 Certificate::Certificate(sdbusplus::bus_t& bus, const std::string& objPath, 220 CertificateType type, const std::string& installPath, 221 const std::string& uploadPath, Watch* watch, 222 Manager& parent, bool restore) : 223 internal::CertificateInterface( 224 bus, objPath.c_str(), 225 internal::CertificateInterface::action::defer_emit), 226 objectPath(objPath), certType(type), certInstallPath(installPath), 227 certWatch(watch), manager(parent) 228 { 229 auto installHelper = [this](const auto& filePath) { 230 if (!compareKeys(filePath)) 231 { 232 elog<InvalidCertificateError>(InvalidCertificate::REASON( 233 "Private key does not match the Certificate")); 234 }; 235 }; 236 typeFuncMap[CertificateType::server] = installHelper; 237 typeFuncMap[CertificateType::client] = installHelper; 238 typeFuncMap[CertificateType::authority] = [](const std::string&) {}; 239 240 auto appendPrivateKey = [this](const std::string& filePath) { 241 checkAndAppendPrivateKey(filePath); 242 }; 243 244 appendKeyMap[CertificateType::server] = appendPrivateKey; 245 appendKeyMap[CertificateType::client] = appendPrivateKey; 246 appendKeyMap[CertificateType::authority] = [](const std::string&) {}; 247 248 // Generate certificate file path 249 certFilePath = generateCertFilePath(uploadPath); 250 251 // install the certificate 252 install(uploadPath, restore); 253 254 this->emit_object_added(); 255 } 256 257 Certificate::Certificate(sdbusplus::bus_t& bus, const std::string& objPath, 258 const CertificateType& type, 259 const std::string& installPath, X509_STORE& x509Store, 260 const std::string& pem, Watch* watchPtr, 261 Manager& parent, bool restore) : 262 internal::CertificateInterface( 263 bus, objPath.c_str(), 264 internal::CertificateInterface::action::defer_emit), 265 objectPath(objPath), certType(type), certInstallPath(installPath), 266 certWatch(watchPtr), manager(parent) 267 { 268 // Generate certificate file path 269 certFilePath = generateUniqueFilePath(installPath); 270 271 // install the certificate 272 install(x509Store, pem, restore); 273 274 this->emit_object_added(); 275 } 276 277 Certificate::~Certificate() 278 { 279 if (!fs::remove(certFilePath)) 280 { 281 lg2::info("Certificate file not found! PATH:{PATH}", "PATH", 282 certFilePath); 283 } 284 } 285 286 void Certificate::replace(const std::string filePath) 287 { 288 manager.replaceCertificate(this, filePath); 289 } 290 291 void Certificate::install(const std::string& certSrcFilePath, bool restore) 292 { 293 if (restore) 294 { 295 lg2::debug("Certificate install, FILEPATH:{FILEPATH}", "FILEPATH", 296 certSrcFilePath); 297 } 298 else 299 { 300 lg2::info("Certificate install, FILEPATH:{FILEPATH}", "FILEPATH", 301 certSrcFilePath); 302 } 303 304 // stop watch for user initiated certificate install 305 if (certWatch != nullptr) 306 { 307 certWatch->stopWatch(); 308 } 309 310 // Verify the certificate file 311 fs::path file(certSrcFilePath); 312 if (!fs::exists(file)) 313 { 314 lg2::error("File is Missing, FILE:{FILE}", "FILE", certSrcFilePath); 315 elog<InternalFailure>(); 316 } 317 318 try 319 { 320 if (fs::file_size(certSrcFilePath) == 0) 321 { 322 // file is empty 323 lg2::error("File is empty, FILE:{FILE}", "FILE", certSrcFilePath); 324 elog<InvalidCertificateError>( 325 InvalidCertificate::REASON("File is empty")); 326 } 327 } 328 catch (const fs::filesystem_error& e) 329 { 330 // Log Error message 331 lg2::error("File is empty, FILE:{FILE}, ERR:{ERR}", "FILE", 332 certSrcFilePath, "ERR", e); 333 elog<InternalFailure>(); 334 } 335 336 X509StorePtr x509Store = getX509Store(certSrcFilePath); 337 338 // Load Certificate file into the X509 structure. 339 internal::X509Ptr cert = loadCert(certSrcFilePath); 340 341 // Perform validation 342 validateCertificateAgainstStore(*x509Store, *cert); 343 validateCertificateStartDate(*cert); 344 validateCertificateInSSLContext(*cert); 345 346 // Invoke type specific append private key function. 347 if (auto it = appendKeyMap.find(certType); it == appendKeyMap.end()) 348 { 349 lg2::error("Unsupported Type, TYPE:{TYPE}", "TYPE", 350 certificateTypeToString(certType)); 351 elog<InternalFailure>(); 352 } 353 else 354 { 355 it->second(certSrcFilePath); 356 } 357 358 // Invoke type specific compare keys function. 359 if (auto it = typeFuncMap.find(certType); it == typeFuncMap.end()) 360 { 361 lg2::error("Unsupported Type, TYPE:{TYPE}", "TYPE", 362 certificateTypeToString(certType)); 363 elog<InternalFailure>(); 364 } 365 else 366 { 367 it->second(certSrcFilePath); 368 } 369 370 copyCertificate(certSrcFilePath, certFilePath); 371 storageUpdate(); 372 373 // Keep certificate ID 374 certId = generateCertId(*cert); 375 376 // Parse the certificate file and populate properties 377 populateProperties(*cert); 378 379 // restart watch 380 if (certWatch != nullptr) 381 { 382 certWatch->startWatch(); 383 } 384 } 385 386 void Certificate::install(X509_STORE& x509Store, const std::string& pem, 387 bool restore) 388 { 389 if (restore) 390 { 391 lg2::debug("Certificate install, PEM_STR:{PEM_STR}", "PEM_STR", pem); 392 } 393 else 394 { 395 lg2::info("Certificate install, PEM_STR:{PEM_STR} ", "PEM_STR", pem); 396 } 397 398 if (certType != CertificateType::authority) 399 { 400 lg2::error("Bulk install error: Unsupported Type; only authority " 401 "supports bulk install, TYPE:{TYPE}", 402 "TYPE", certificateTypeToString(certType)); 403 elog<InternalFailure>(); 404 } 405 406 // stop watch for user initiated certificate install 407 if (certWatch) 408 { 409 certWatch->stopWatch(); 410 } 411 412 // Load Certificate file into the X509 structure. 413 internal::X509Ptr cert = parseCert(pem); 414 // Perform validation; no type specific compare keys function 415 validateCertificateAgainstStore(x509Store, *cert); 416 validateCertificateStartDate(*cert); 417 validateCertificateInSSLContext(*cert); 418 419 // Copy the PEM to the installation path 420 dumpCertificate(pem, certFilePath); 421 storageUpdate(); 422 // Keep certificate ID 423 certId = generateCertId(*cert); 424 // Parse the certificate file and populate properties 425 populateProperties(*cert); 426 // restart watch 427 if (certWatch) 428 { 429 certWatch->startWatch(); 430 } 431 } 432 433 void Certificate::populateProperties() 434 { 435 internal::X509Ptr cert = loadCert(certInstallPath); 436 populateProperties(*cert); 437 } 438 439 std::string Certificate::getCertId() const 440 { 441 return certId; 442 } 443 444 bool Certificate::isSame(const std::string& certPath) 445 { 446 internal::X509Ptr cert = loadCert(certPath); 447 return getCertId() == generateCertId(*cert); 448 } 449 450 void Certificate::storageUpdate() 451 { 452 if (certType == CertificateType::authority) 453 { 454 // Create symbolic link in the certificate directory 455 std::string certFileX509Path; 456 try 457 { 458 if (!certFilePath.empty() && 459 fs::is_regular_file(fs::path(certFilePath))) 460 { 461 certFileX509Path = 462 generateAuthCertFileX509Path(certFilePath, certInstallPath); 463 fs::create_symlink(fs::path(certFilePath), 464 fs::path(certFileX509Path)); 465 } 466 } 467 catch (const std::exception& e) 468 { 469 lg2::error("Failed to create symlink for certificate, ERR:{ERR}," 470 "FILE:{FILE}, SYMLINK:{SYMLINK}", 471 "ERR", e, "FILE", certFilePath, "SYMLINK", 472 certFileX509Path); 473 elog<InternalFailure>(); 474 } 475 } 476 } 477 478 void Certificate::populateProperties(X509& cert) 479 { 480 // Update properties if no error thrown 481 BIOMemPtr certBio(BIO_new(BIO_s_mem()), BIO_free); 482 PEM_write_bio_X509(certBio.get(), &cert); 483 BufMemPtr certBuf(BUF_MEM_new(), BUF_MEM_free); 484 BUF_MEM* buf = certBuf.get(); 485 BIO_get_mem_ptr(certBio.get(), &buf); 486 std::string certStr(buf->data, buf->length); 487 certificateString(certStr); 488 489 static const int maxKeySize = 4096; 490 char subBuffer[maxKeySize] = {0}; 491 BIOMemPtr subBio(BIO_new(BIO_s_mem()), BIO_free); 492 // This pointer cannot be freed independently. 493 X509_NAME* sub = X509_get_subject_name(&cert); 494 X509_NAME_print_ex(subBio.get(), sub, 0, XN_FLAG_SEP_COMMA_PLUS); 495 BIO_read(subBio.get(), subBuffer, maxKeySize); 496 subject(subBuffer); 497 498 char issuerBuffer[maxKeySize] = {0}; 499 BIOMemPtr issuerBio(BIO_new(BIO_s_mem()), BIO_free); 500 // This pointer cannot be freed independently. 501 X509_NAME* issuerName = X509_get_issuer_name(&cert); 502 X509_NAME_print_ex(issuerBio.get(), issuerName, 0, XN_FLAG_SEP_COMMA_PLUS); 503 BIO_read(issuerBio.get(), issuerBuffer, maxKeySize); 504 issuer(issuerBuffer); 505 506 std::vector<std::string> keyUsageList; 507 ASN1_BIT_STRING* usage; 508 509 // Go through each usage in the bit string and convert to 510 // corresponding string value 511 if ((usage = static_cast<ASN1_BIT_STRING*>( 512 X509_get_ext_d2i(&cert, NID_key_usage, nullptr, nullptr)))) 513 { 514 for (auto i = 0; i < usage->length; ++i) 515 { 516 for (auto& x : keyUsageToRfStr) 517 { 518 if (x.first & usage->data[i]) 519 { 520 keyUsageList.push_back(x.second); 521 break; 522 } 523 } 524 } 525 } 526 527 EXTENDED_KEY_USAGE* extUsage; 528 if ((extUsage = static_cast<EXTENDED_KEY_USAGE*>( 529 X509_get_ext_d2i(&cert, NID_ext_key_usage, nullptr, nullptr)))) 530 { 531 for (int i = 0; i < sk_ASN1_OBJECT_num(extUsage); i++) 532 { 533 keyUsageList.push_back(extendedKeyUsageToRfStr[OBJ_obj2nid( 534 sk_ASN1_OBJECT_value(extUsage, i))]); 535 } 536 } 537 keyUsage(keyUsageList); 538 539 int days = 0; 540 int secs = 0; 541 542 ASN1TimePtr epoch(ASN1_TIME_new(), ASN1_STRING_free); 543 // Set time to 00:00am GMT, Jan 1 1970; format: YYYYMMDDHHMMSSZ 544 ASN1_TIME_set_string(epoch.get(), "19700101000000Z"); 545 546 static const uint64_t dayToSeconds = 24 * 60 * 60; 547 ASN1_TIME* notAfter = X509_get_notAfter(&cert); 548 ASN1_TIME_diff(&days, &secs, epoch.get(), notAfter); 549 validNotAfter((days * dayToSeconds) + secs); 550 551 ASN1_TIME* notBefore = X509_get_notBefore(&cert); 552 ASN1_TIME_diff(&days, &secs, epoch.get(), notBefore); 553 validNotBefore((days * dayToSeconds) + secs); 554 } 555 556 void Certificate::checkAndAppendPrivateKey(const std::string& filePath) 557 { 558 BIOMemPtr keyBio(BIO_new(BIO_s_file()), ::BIO_free); 559 if (!keyBio) 560 { 561 lg2::error("Error occurred during BIO_s_file call, FILE:{FILE}", "FILE", 562 filePath); 563 elog<InternalFailure>(); 564 } 565 BIO_read_filename(keyBio.get(), filePath.c_str()); 566 567 EVPPkeyPtr priKey( 568 PEM_read_bio_PrivateKey(keyBio.get(), nullptr, nullptr, nullptr), 569 ::EVP_PKEY_free); 570 if (!priKey) 571 { 572 lg2::info("Private key not present in file, FILE:{FILE}", "FILE", 573 filePath); 574 fs::path privateKeyFile = fs::path(certInstallPath).parent_path(); 575 privateKeyFile = privateKeyFile / defaultPrivateKeyFileName; 576 if (!fs::exists(privateKeyFile)) 577 { 578 lg2::error("Private key file is not found, FILE:{FILE}", "FILE", 579 privateKeyFile); 580 elog<InternalFailure>(); 581 } 582 583 std::ifstream privKeyFileStream; 584 std::ofstream certFileStream; 585 privKeyFileStream.exceptions( 586 std::ifstream::failbit | std::ifstream::badbit | 587 std::ifstream::eofbit); 588 certFileStream.exceptions( 589 std::ofstream::failbit | std::ofstream::badbit | 590 std::ofstream::eofbit); 591 try 592 { 593 privKeyFileStream.open(privateKeyFile); 594 certFileStream.open(filePath, std::ios::app); 595 certFileStream << std::endl; // insert line break 596 certFileStream << privKeyFileStream.rdbuf() << std::flush; 597 privKeyFileStream.close(); 598 certFileStream.close(); 599 } 600 catch (const std::exception& e) 601 { 602 lg2::error( 603 "Failed to append private key, ERR:{ERR}, SRC:{SRC}, DST:{DST}", 604 "ERR", e, "SRC", privateKeyFile, "DST", filePath); 605 elog<InternalFailure>(); 606 } 607 } 608 } 609 610 bool Certificate::compareKeys(const std::string& filePath) 611 { 612 lg2::info("Certificate compareKeys, FILEPATH:{FILEPATH}", "FILEPATH", 613 filePath); 614 internal::X509Ptr cert(X509_new(), ::X509_free); 615 if (!cert) 616 { 617 lg2::error( 618 "Error occurred during X509_new call, FILE:{FILE}, ERRCODE:{ERRCODE}", 619 "FILE", filePath, "ERRCODE", ERR_get_error()); 620 elog<InternalFailure>(); 621 } 622 623 BIOMemPtr bioCert(BIO_new_file(filePath.c_str(), "rb"), ::BIO_free); 624 if (!bioCert) 625 { 626 lg2::error("Error occurred during BIO_new_file call, FILE:{FILE}", 627 "FILE", filePath); 628 elog<InternalFailure>(); 629 } 630 631 X509* x509 = cert.get(); 632 PEM_read_bio_X509(bioCert.get(), &x509, nullptr, nullptr); 633 634 EVPPkeyPtr pubKey(X509_get_pubkey(cert.get()), ::EVP_PKEY_free); 635 if (!pubKey) 636 { 637 lg2::error( 638 "Error occurred during X509_get_pubkey, FILE:{FILE}, ERRCODE:{ERRCODE}", 639 "FILE", filePath, "ERRCODE", ERR_get_error()); 640 elog<InvalidCertificateError>( 641 InvalidCertificate::REASON("Failed to get public key info")); 642 } 643 644 BIOMemPtr keyBio(BIO_new(BIO_s_file()), ::BIO_free); 645 if (!keyBio) 646 { 647 lg2::error("Error occurred during BIO_s_file call, FILE:{FILE}", "FILE", 648 filePath); 649 elog<InternalFailure>(); 650 } 651 BIO_read_filename(keyBio.get(), filePath.c_str()); 652 653 EVPPkeyPtr priKey( 654 PEM_read_bio_PrivateKey(keyBio.get(), nullptr, nullptr, nullptr), 655 ::EVP_PKEY_free); 656 if (!priKey) 657 { 658 lg2::error( 659 "Error occurred during PEM_read_bio_PrivateKey, FILE:{FILE}, ERRCODE:{ERRCODE}", 660 "FILE", filePath, "ERRCODE", ERR_get_error()); 661 elog<InvalidCertificateError>( 662 InvalidCertificate::REASON("Failed to get private key info")); 663 } 664 665 #if (OPENSSL_VERSION_NUMBER < 0x30000000L) 666 int32_t rc = EVP_PKEY_cmp(priKey.get(), pubKey.get()); 667 #else 668 int32_t rc = EVP_PKEY_eq(priKey.get(), pubKey.get()); 669 #endif 670 if (rc != 1) 671 { 672 lg2::error( 673 "Private key is not matching with Certificate, FILE:{FILE}, ERRCODE:{ERRCODE}", 674 "FILE", filePath, "ERRCODE", rc); 675 return false; 676 } 677 return true; 678 } 679 680 void Certificate::delete_() 681 { 682 manager.deleteCertificate(this); 683 } 684 685 std::string Certificate::getObjectPath() 686 { 687 return objectPath; 688 } 689 690 std::string Certificate::getCertFilePath() 691 { 692 return certFilePath; 693 } 694 695 void Certificate::setCertFilePath(const std::string& path) 696 { 697 certFilePath = path; 698 } 699 700 void Certificate::setCertInstallPath(const std::string& path) 701 { 702 certInstallPath = path; 703 } 704 705 } // namespace phosphor::certs 706