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