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