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