xref: /openbmc/phosphor-certificate-manager/certificate.cpp (revision b6274297a65ff0b89111206b7b0367161abc3c2a)
1cd30c496SMarri Devender Rao #include "config.h"
2cd30c496SMarri Devender Rao 
36ceec40bSMarri Devender Rao #include "certificate.hpp"
46ceec40bSMarri Devender Rao 
5a3bb38fbSZbigniew Kurzynski #include "certs_manager.hpp"
6e869bb63SNan Zhou #include "x509_utils.hpp"
7a3bb38fbSZbigniew Kurzynski 
8014be0bfSNan Zhou #include <openssl/asn1.h>
96ceec40bSMarri Devender Rao #include <openssl/bio.h>
10014be0bfSNan Zhou #include <openssl/buffer.h>
116ceec40bSMarri Devender Rao #include <openssl/err.h>
126ceec40bSMarri Devender Rao #include <openssl/evp.h>
13014be0bfSNan Zhou #include <openssl/obj_mac.h>
14014be0bfSNan Zhou #include <openssl/objects.h>
15014be0bfSNan Zhou #include <openssl/opensslv.h>
166ceec40bSMarri Devender Rao #include <openssl/pem.h>
176ceec40bSMarri Devender Rao #include <openssl/x509v3.h>
186ceec40bSMarri Devender Rao 
19223e4604SPatrick Williams #include <phosphor-logging/elog-errors.hpp>
20223e4604SPatrick Williams #include <phosphor-logging/elog.hpp>
21f2646271SRavi Teja #include <phosphor-logging/lg2.hpp>
22223e4604SPatrick Williams #include <watch.hpp>
23223e4604SPatrick Williams #include <xyz/openbmc_project/Certs/error.hpp>
24223e4604SPatrick Williams #include <xyz/openbmc_project/Common/error.hpp>
25223e4604SPatrick Williams 
26014be0bfSNan Zhou #include <cstdint>
27014be0bfSNan Zhou #include <cstdio>
28014be0bfSNan Zhou #include <cstdlib>
29014be0bfSNan Zhou #include <exception>
30014be0bfSNan Zhou #include <filesystem>
316ceec40bSMarri Devender Rao #include <fstream>
32014be0bfSNan Zhou #include <map>
33014be0bfSNan Zhou #include <utility>
34014be0bfSNan Zhou #include <vector>
3513bf74e4SMarri Devender Rao 
36e1289adfSNan Zhou namespace phosphor::certs
376ceec40bSMarri Devender Rao {
38cf06ccdcSNan Zhou 
39cf06ccdcSNan Zhou namespace
40cf06ccdcSNan Zhou {
41cf06ccdcSNan Zhou namespace fs = std::filesystem;
42cf06ccdcSNan Zhou using ::phosphor::logging::elog;
43cf06ccdcSNan Zhou using InvalidCertificateError =
44cf06ccdcSNan Zhou     ::sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate;
45cf06ccdcSNan Zhou using ::phosphor::logging::xyz::openbmc_project::Certs::InvalidCertificate;
46cf06ccdcSNan Zhou using ::sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
47cf06ccdcSNan Zhou 
486ceec40bSMarri Devender Rao // RAII support for openSSL functions.
49cf06ccdcSNan Zhou using BIOMemPtr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
50cf06ccdcSNan Zhou using X509StorePtr = std::unique_ptr<X509_STORE, decltype(&::X509_STORE_free)>;
51cf06ccdcSNan Zhou using ASN1TimePtr = std::unique_ptr<ASN1_TIME, decltype(&ASN1_STRING_free)>;
52cf06ccdcSNan Zhou using EVPPkeyPtr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
53cf06ccdcSNan Zhou using BufMemPtr = std::unique_ptr<BUF_MEM, decltype(&::BUF_MEM_free)>;
546ceec40bSMarri Devender Rao 
5536f25142SDhruvaraj Subhashchandran // Refer to schema 2018.3
5636f25142SDhruvaraj Subhashchandran // http://redfish.dmtf.org/schemas/v1/Certificate.json#/definitions/KeyUsage for
5736f25142SDhruvaraj Subhashchandran // supported KeyUsage types in redfish
5836f25142SDhruvaraj Subhashchandran // Refer to
5936f25142SDhruvaraj Subhashchandran // https://github.com/openssl/openssl/blob/master/include/openssl/x509v3.h for
6036f25142SDhruvaraj Subhashchandran // key usage bit fields
6136f25142SDhruvaraj Subhashchandran std::map<uint8_t, std::string> keyUsageToRfStr = {
6236f25142SDhruvaraj Subhashchandran     {KU_DIGITAL_SIGNATURE, "DigitalSignature"},
6336f25142SDhruvaraj Subhashchandran     {KU_NON_REPUDIATION, "NonRepudiation"},
6436f25142SDhruvaraj Subhashchandran     {KU_KEY_ENCIPHERMENT, "KeyEncipherment"},
6536f25142SDhruvaraj Subhashchandran     {KU_DATA_ENCIPHERMENT, "DataEncipherment"},
6636f25142SDhruvaraj Subhashchandran     {KU_KEY_AGREEMENT, "KeyAgreement"},
6736f25142SDhruvaraj Subhashchandran     {KU_KEY_CERT_SIGN, "KeyCertSign"},
6836f25142SDhruvaraj Subhashchandran     {KU_CRL_SIGN, "CRLSigning"},
6936f25142SDhruvaraj Subhashchandran     {KU_ENCIPHER_ONLY, "EncipherOnly"},
7036f25142SDhruvaraj Subhashchandran     {KU_DECIPHER_ONLY, "DecipherOnly"}};
7136f25142SDhruvaraj Subhashchandran 
7236f25142SDhruvaraj Subhashchandran // Refer to schema 2018.3
7336f25142SDhruvaraj Subhashchandran // http://redfish.dmtf.org/schemas/v1/Certificate.json#/definitions/KeyUsage for
7436f25142SDhruvaraj Subhashchandran // supported Extended KeyUsage types in redfish
7536f25142SDhruvaraj Subhashchandran std::map<uint8_t, std::string> extendedKeyUsageToRfStr = {
7636f25142SDhruvaraj Subhashchandran     {NID_server_auth, "ServerAuthentication"},
7736f25142SDhruvaraj Subhashchandran     {NID_client_auth, "ClientAuthentication"},
7836f25142SDhruvaraj Subhashchandran     {NID_email_protect, "EmailProtection"},
7936f25142SDhruvaraj Subhashchandran     {NID_OCSP_sign, "OCSPSigning"},
8036f25142SDhruvaraj Subhashchandran     {NID_ad_timeStamping, "Timestamping"},
8136f25142SDhruvaraj Subhashchandran     {NID_code_sign, "CodeSigning"}};
8236f25142SDhruvaraj Subhashchandran 
83e869bb63SNan Zhou /**
846ec13c8fSNan Zhou  * @brief Dumps the PEM encoded certificate to installFilePath
85e869bb63SNan Zhou  *
866ec13c8fSNan Zhou  * @param[in] pem - PEM encoded X509 certificate buffer.
876ec13c8fSNan Zhou  * @param[in] certFilePath - Path to the destination file.
88e869bb63SNan Zhou  *
89e869bb63SNan Zhou  * @return void
90e869bb63SNan Zhou  */
916ec13c8fSNan Zhou 
dumpCertificate(const std::string & pem,const std::string & certFilePath)926ec13c8fSNan Zhou void dumpCertificate(const std::string& pem, const std::string& certFilePath)
936ec13c8fSNan Zhou {
946ec13c8fSNan Zhou     std::ofstream outputCertFileStream;
956ec13c8fSNan Zhou 
966ec13c8fSNan Zhou     outputCertFileStream.exceptions(
976ec13c8fSNan Zhou         std::ofstream::failbit | std::ofstream::badbit | std::ofstream::eofbit);
986ec13c8fSNan Zhou 
996ec13c8fSNan Zhou     try
1006ec13c8fSNan Zhou     {
1016ec13c8fSNan Zhou         outputCertFileStream.open(certFilePath, std::ios::out);
1026ec13c8fSNan Zhou         outputCertFileStream << pem << "\n" << std::flush;
1036ec13c8fSNan Zhou         outputCertFileStream.close();
1046ec13c8fSNan Zhou     }
1056ec13c8fSNan Zhou     catch (const std::exception& e)
1066ec13c8fSNan Zhou     {
107f2646271SRavi Teja         lg2::error(
108f2646271SRavi Teja             "Failed to dump certificate, ERR:{ERR}, SRC_PEM:{SRC_PEM}, DST:{DST}",
109f2646271SRavi Teja             "ERR", e, "SRC_PEM", pem, "DST", certFilePath);
1106ec13c8fSNan Zhou         elog<InternalFailure>();
1116ec13c8fSNan Zhou     }
1126ec13c8fSNan Zhou }
1136ec13c8fSNan Zhou } // namespace
1146ec13c8fSNan Zhou 
copyCertificate(const std::string & certSrcFilePath,const std::string & certFilePath)1156ec13c8fSNan Zhou void Certificate::copyCertificate(const std::string& certSrcFilePath,
116e869bb63SNan Zhou                                   const std::string& certFilePath)
117db029c95SKowalski, Kamil {
118f44a39cfSJayanth Othayoth     try
119f44a39cfSJayanth Othayoth     {
120e869bb63SNan Zhou         // Copy the certificate to the installation path
121e869bb63SNan Zhou         // During bootup will be parsing existing file so no need to
122e869bb63SNan Zhou         // copy it.
123e869bb63SNan Zhou         if (certSrcFilePath != certFilePath)
124e869bb63SNan Zhou         {
125f44a39cfSJayanth Othayoth             fs::copy(certSrcFilePath, certFilePath,
126f44a39cfSJayanth Othayoth                      fs::copy_options::overwrite_existing);
127f44a39cfSJayanth Othayoth         }
128f44a39cfSJayanth Othayoth     }
129f44a39cfSJayanth Othayoth     catch (const fs::filesystem_error& e)
130e869bb63SNan Zhou     {
131f2646271SRavi Teja         lg2::error(
132f2646271SRavi Teja             "Failed to copy certificate, ERR:{ERR}, SRC:{SRC}, DST:{DST}",
133f44a39cfSJayanth Othayoth             "ERR", e.what(), "SRC", certSrcFilePath, "DST", certFilePath);
134e869bb63SNan Zhou         elog<InternalFailure>();
135e869bb63SNan Zhou     }
136e869bb63SNan Zhou }
1372f3563ccSZbigniew Lukwinski 
1382f3563ccSZbigniew Lukwinski std::string
generateUniqueFilePath(const std::string & directoryPath)1392f3563ccSZbigniew Lukwinski     Certificate::generateUniqueFilePath(const std::string& directoryPath)
1402f3563ccSZbigniew Lukwinski {
141*b6274297SMilton D. Miller II     char* filePath = tempnam(directoryPath.c_str(), nullptr);
142*b6274297SMilton D. Miller II     if (filePath == nullptr)
1432f3563ccSZbigniew Lukwinski     {
144f2646271SRavi Teja         lg2::error(
145f2646271SRavi Teja             "Error occurred while creating random certificate file path, DIR:{DIR}",
146f2646271SRavi Teja             "DIR", directoryPath);
1472f3563ccSZbigniew Lukwinski         elog<InternalFailure>();
1482f3563ccSZbigniew Lukwinski     }
149*b6274297SMilton D. Miller II     std::string filePathStr(filePath);
150*b6274297SMilton D. Miller II     free(filePath);
151*b6274297SMilton D. Miller II     return filePathStr;
1522f3563ccSZbigniew Lukwinski }
1532f3563ccSZbigniew Lukwinski 
generateAuthCertFileX509Path(const std::string & certSrcFilePath,const std::string & certDstDirPath)1542f3563ccSZbigniew Lukwinski std::string Certificate::generateAuthCertFileX509Path(
1552f3563ccSZbigniew Lukwinski     const std::string& certSrcFilePath, const std::string& certDstDirPath)
1562f3563ccSZbigniew Lukwinski {
157cf06ccdcSNan Zhou     const internal::X509Ptr cert = loadCert(certSrcFilePath);
158db029c95SKowalski, Kamil     unsigned long hash = X509_subject_name_hash(cert.get());
159e3d47cd4SNan Zhou     static constexpr auto certHashLength = 9;
160e3d47cd4SNan Zhou     char hashBuf[certHashLength];
161db029c95SKowalski, Kamil 
162e3d47cd4SNan Zhou     snprintf(hashBuf, certHashLength, "%08lx", hash);
163db029c95SKowalski, Kamil 
1642f3563ccSZbigniew Lukwinski     const std::string certHash(hashBuf);
165718eef37SNan Zhou     for (size_t i = 0; i < maxNumAuthorityCertificates; ++i)
1662f3563ccSZbigniew Lukwinski     {
16773d1fbf3SZbigniew Lukwinski         const std::string certDstFileX509Path =
16873d1fbf3SZbigniew Lukwinski             certDstDirPath + "/" + certHash + "." + std::to_string(i);
16973d1fbf3SZbigniew Lukwinski         if (!fs::exists(certDstFileX509Path))
17073d1fbf3SZbigniew Lukwinski         {
17173d1fbf3SZbigniew Lukwinski             return certDstFileX509Path;
17273d1fbf3SZbigniew Lukwinski         }
1732f3563ccSZbigniew Lukwinski     }
174db029c95SKowalski, Kamil 
175f2646271SRavi Teja     lg2::error("Authority certificate x509 file path already used, DIR:{DIR}",
176f2646271SRavi Teja                "DIR", certDstDirPath);
17773d1fbf3SZbigniew Lukwinski     elog<InternalFailure>();
1782f3563ccSZbigniew Lukwinski }
1792f3563ccSZbigniew Lukwinski 
1802f3563ccSZbigniew Lukwinski std::string
generateAuthCertFilePath(const std::string & certSrcFilePath)1812f3563ccSZbigniew Lukwinski     Certificate::generateAuthCertFilePath(const std::string& certSrcFilePath)
1822f3563ccSZbigniew Lukwinski {
1832f3563ccSZbigniew Lukwinski     // If there is a certificate file path (which means certificate replacement
1842f3563ccSZbigniew Lukwinski     // is doing) use it (do not create new one)
1852f3563ccSZbigniew Lukwinski     if (!certFilePath.empty())
1862f3563ccSZbigniew Lukwinski     {
1872f3563ccSZbigniew Lukwinski         return certFilePath;
1882f3563ccSZbigniew Lukwinski     }
1892f3563ccSZbigniew Lukwinski     // If source certificate file is located in the certificates directory use
1902f3563ccSZbigniew Lukwinski     // it (do not create new one)
1912f3563ccSZbigniew Lukwinski     else if (fs::path(certSrcFilePath).parent_path().string() ==
1922f3563ccSZbigniew Lukwinski              certInstallPath)
1932f3563ccSZbigniew Lukwinski     {
1942f3563ccSZbigniew Lukwinski         return certSrcFilePath;
1952f3563ccSZbigniew Lukwinski     }
1962f3563ccSZbigniew Lukwinski     // Otherwise generate new file name/path
1972f3563ccSZbigniew Lukwinski     else
1982f3563ccSZbigniew Lukwinski     {
1992f3563ccSZbigniew Lukwinski         return generateUniqueFilePath(certInstallPath);
2002f3563ccSZbigniew Lukwinski     }
2012f3563ccSZbigniew Lukwinski }
2022f3563ccSZbigniew Lukwinski 
2032f3563ccSZbigniew Lukwinski std::string
generateCertFilePath(const std::string & certSrcFilePath)2042f3563ccSZbigniew Lukwinski     Certificate::generateCertFilePath(const std::string& certSrcFilePath)
2052f3563ccSZbigniew Lukwinski {
206e3d47cd4SNan Zhou     if (certType == CertificateType::authority)
2072f3563ccSZbigniew Lukwinski     {
2082f3563ccSZbigniew Lukwinski         return generateAuthCertFilePath(certSrcFilePath);
2092f3563ccSZbigniew Lukwinski     }
2102f3563ccSZbigniew Lukwinski     else
2112f3563ccSZbigniew Lukwinski     {
2122f3563ccSZbigniew Lukwinski         return certInstallPath;
2132f3563ccSZbigniew Lukwinski     }
214db029c95SKowalski, Kamil }
215db029c95SKowalski, Kamil 
Certificate(sdbusplus::bus_t & bus,const std::string & objPath,CertificateType type,const std::string & installPath,const std::string & uploadPath,Watch * watch,Manager & parent,bool restore)216b3dbfb37SPatrick Williams Certificate::Certificate(sdbusplus::bus_t& bus, const std::string& objPath,
217cf06ccdcSNan Zhou                          CertificateType type, const std::string& installPath,
218cf06ccdcSNan Zhou                          const std::string& uploadPath, Watch* watch,
219698a5743SWilly Tu                          Manager& parent, bool restore) :
220ebd21ba4SPatrick Williams     internal::CertificateInterface(
221ebd21ba4SPatrick Williams         bus, objPath.c_str(),
222ebd21ba4SPatrick Williams         internal::CertificateInterface::action::defer_emit),
223cf06ccdcSNan Zhou     objectPath(objPath), certType(type), certInstallPath(installPath),
224cf06ccdcSNan Zhou     certWatch(watch), manager(parent)
2256ceec40bSMarri Devender Rao {
2266ceec40bSMarri Devender Rao     auto installHelper = [this](const auto& filePath) {
2276ceec40bSMarri Devender Rao         if (!compareKeys(filePath))
2286ceec40bSMarri Devender Rao         {
229cf06ccdcSNan Zhou             elog<InvalidCertificateError>(InvalidCertificate::REASON(
230cf06ccdcSNan Zhou                 "Private key does not match the Certificate"));
2316ceec40bSMarri Devender Rao         };
2326ceec40bSMarri Devender Rao     };
233e3d47cd4SNan Zhou     typeFuncMap[CertificateType::server] = installHelper;
234e3d47cd4SNan Zhou     typeFuncMap[CertificateType::client] = installHelper;
235e3d47cd4SNan Zhou     typeFuncMap[CertificateType::authority] = [](const std::string&) {};
236cd30c496SMarri Devender Rao 
237cd30c496SMarri Devender Rao     auto appendPrivateKey = [this](const std::string& filePath) {
238cd30c496SMarri Devender Rao         checkAndAppendPrivateKey(filePath);
239cd30c496SMarri Devender Rao     };
240cd30c496SMarri Devender Rao 
241e3d47cd4SNan Zhou     appendKeyMap[CertificateType::server] = appendPrivateKey;
242e3d47cd4SNan Zhou     appendKeyMap[CertificateType::client] = appendPrivateKey;
243e3d47cd4SNan Zhou     appendKeyMap[CertificateType::authority] = [](const std::string&) {};
244cd30c496SMarri Devender Rao 
2452f3563ccSZbigniew Lukwinski     // Generate certificate file path
2462f3563ccSZbigniew Lukwinski     certFilePath = generateCertFilePath(uploadPath);
2472f3563ccSZbigniew Lukwinski 
248cd30c496SMarri Devender Rao     // install the certificate
249698a5743SWilly Tu     install(uploadPath, restore);
250cd30c496SMarri Devender Rao 
251edd1131cSMarri Devender Rao     this->emit_object_added();
2526ceec40bSMarri Devender Rao }
2536ceec40bSMarri Devender Rao 
Certificate(sdbusplus::bus_t & bus,const std::string & objPath,const CertificateType & type,const std::string & installPath,X509_STORE & x509Store,const std::string & pem,Watch * watchPtr,Manager & parent,bool restore)254b3dbfb37SPatrick Williams Certificate::Certificate(sdbusplus::bus_t& bus, const std::string& objPath,
2556ec13c8fSNan Zhou                          const CertificateType& type,
2566ec13c8fSNan Zhou                          const std::string& installPath, X509_STORE& x509Store,
2576ec13c8fSNan Zhou                          const std::string& pem, Watch* watchPtr,
258698a5743SWilly Tu                          Manager& parent, bool restore) :
259ebd21ba4SPatrick Williams     internal::CertificateInterface(
260ebd21ba4SPatrick Williams         bus, objPath.c_str(),
261ebd21ba4SPatrick Williams         internal::CertificateInterface::action::defer_emit),
2626ec13c8fSNan Zhou     objectPath(objPath), certType(type), certInstallPath(installPath),
2636ec13c8fSNan Zhou     certWatch(watchPtr), manager(parent)
2646ec13c8fSNan Zhou {
2656ec13c8fSNan Zhou     // Generate certificate file path
2666ec13c8fSNan Zhou     certFilePath = generateUniqueFilePath(installPath);
2676ec13c8fSNan Zhou 
2686ec13c8fSNan Zhou     // install the certificate
269698a5743SWilly Tu     install(x509Store, pem, restore);
2706ec13c8fSNan Zhou 
2716ec13c8fSNan Zhou     this->emit_object_added();
2726ec13c8fSNan Zhou }
2736ec13c8fSNan Zhou 
~Certificate()2746ceec40bSMarri Devender Rao Certificate::~Certificate()
2756ceec40bSMarri Devender Rao {
2762f3563ccSZbigniew Lukwinski     if (!fs::remove(certFilePath))
2776ceec40bSMarri Devender Rao     {
278f2646271SRavi Teja         lg2::info("Certificate file not found! PATH:{PATH}", "PATH",
279f2646271SRavi Teja                   certFilePath);
2806ceec40bSMarri Devender Rao     }
2816ceec40bSMarri Devender Rao }
2826ceec40bSMarri Devender Rao 
replace(const std::string filePath)28313bf74e4SMarri Devender Rao void Certificate::replace(const std::string filePath)
28413bf74e4SMarri Devender Rao {
2852f3563ccSZbigniew Lukwinski     manager.replaceCertificate(this, filePath);
28613bf74e4SMarri Devender Rao }
28713bf74e4SMarri Devender Rao 
install(const std::string & certSrcFilePath,bool restore)288698a5743SWilly Tu void Certificate::install(const std::string& certSrcFilePath, bool restore)
289698a5743SWilly Tu {
290698a5743SWilly Tu     if (restore)
291698a5743SWilly Tu     {
292f2646271SRavi Teja         lg2::debug("Certificate install, FILEPATH:{FILEPATH}", "FILEPATH",
293f2646271SRavi Teja                    certSrcFilePath);
294698a5743SWilly Tu     }
295698a5743SWilly Tu     else
2966ceec40bSMarri Devender Rao     {
297f2646271SRavi Teja         lg2::info("Certificate install, FILEPATH:{FILEPATH}", "FILEPATH",
298f2646271SRavi Teja                   certSrcFilePath);
299698a5743SWilly Tu     }
3006ceec40bSMarri Devender Rao 
301ffad1ef1SMarri Devender Rao     // stop watch for user initiated certificate install
302cf06ccdcSNan Zhou     if (certWatch != nullptr)
303ffad1ef1SMarri Devender Rao     {
304cf06ccdcSNan Zhou         certWatch->stopWatch();
305ffad1ef1SMarri Devender Rao     }
306ffad1ef1SMarri Devender Rao 
3076ceec40bSMarri Devender Rao     // Verify the certificate file
3082f3563ccSZbigniew Lukwinski     fs::path file(certSrcFilePath);
3096ceec40bSMarri Devender Rao     if (!fs::exists(file))
3106ceec40bSMarri Devender Rao     {
311f2646271SRavi Teja         lg2::error("File is Missing, FILE:{FILE}", "FILE", certSrcFilePath);
3126ceec40bSMarri Devender Rao         elog<InternalFailure>();
3136ceec40bSMarri Devender Rao     }
3146ceec40bSMarri Devender Rao 
3156ceec40bSMarri Devender Rao     try
3166ceec40bSMarri Devender Rao     {
3172f3563ccSZbigniew Lukwinski         if (fs::file_size(certSrcFilePath) == 0)
3186ceec40bSMarri Devender Rao         {
3196ceec40bSMarri Devender Rao             // file is empty
320f2646271SRavi Teja             lg2::error("File is empty, FILE:{FILE}", "FILE", certSrcFilePath);
321cf06ccdcSNan Zhou             elog<InvalidCertificateError>(
322cf06ccdcSNan Zhou                 InvalidCertificate::REASON("File is empty"));
3236ceec40bSMarri Devender Rao         }
3246ceec40bSMarri Devender Rao     }
3256ceec40bSMarri Devender Rao     catch (const fs::filesystem_error& e)
3266ceec40bSMarri Devender Rao     {
3276ceec40bSMarri Devender Rao         // Log Error message
328f2646271SRavi Teja         lg2::error("File is empty, FILE:{FILE}, ERR:{ERR}", "FILE",
329f2646271SRavi Teja                    certSrcFilePath, "ERR", e);
3306ceec40bSMarri Devender Rao         elog<InternalFailure>();
3316ceec40bSMarri Devender Rao     }
3326ceec40bSMarri Devender Rao 
333e869bb63SNan Zhou     X509StorePtr x509Store = getX509Store(certSrcFilePath);
3346ceec40bSMarri Devender Rao 
335bf3cf751SNan Zhou     // Load Certificate file into the X509 structure.
336cf06ccdcSNan Zhou     internal::X509Ptr cert = loadCert(certSrcFilePath);
337e869bb63SNan Zhou 
338e869bb63SNan Zhou     // Perform validation
339e869bb63SNan Zhou     validateCertificateAgainstStore(*x509Store, *cert);
340e869bb63SNan Zhou     validateCertificateStartDate(*cert);
341e869bb63SNan Zhou     validateCertificateInSSLContext(*cert);
342e869bb63SNan Zhou 
343e869bb63SNan Zhou     // Invoke type specific append private key function.
344e869bb63SNan Zhou     if (auto it = appendKeyMap.find(certType); it == appendKeyMap.end())
3456ceec40bSMarri Devender Rao     {
346f2646271SRavi Teja         lg2::error("Unsupported Type, TYPE:{TYPE}", "TYPE",
347f2646271SRavi Teja                    certificateTypeToString(certType));
3486ceec40bSMarri Devender Rao         elog<InternalFailure>();
3496ceec40bSMarri Devender Rao     }
3506ceec40bSMarri Devender Rao     else
3516ceec40bSMarri Devender Rao     {
352e869bb63SNan Zhou         it->second(certSrcFilePath);
3536ceec40bSMarri Devender Rao     }
3546ceec40bSMarri Devender Rao 
355cd30c496SMarri Devender Rao     // Invoke type specific compare keys function.
356e869bb63SNan Zhou     if (auto it = typeFuncMap.find(certType); it == typeFuncMap.end())
357cd30c496SMarri Devender Rao     {
358f2646271SRavi Teja         lg2::error("Unsupported Type, TYPE:{TYPE}", "TYPE",
359f2646271SRavi Teja                    certificateTypeToString(certType));
360cd30c496SMarri Devender Rao         elog<InternalFailure>();
361cd30c496SMarri Devender Rao     }
362e869bb63SNan Zhou     else
3636ceec40bSMarri Devender Rao     {
364e869bb63SNan Zhou         it->second(certSrcFilePath);
365ffad1ef1SMarri Devender Rao     }
3668f80c35bSMarri Devender Rao 
367e869bb63SNan Zhou     copyCertificate(certSrcFilePath, certFilePath);
3682f3563ccSZbigniew Lukwinski     storageUpdate();
36936f25142SDhruvaraj Subhashchandran 
3702f3563ccSZbigniew Lukwinski     // Keep certificate ID
371e869bb63SNan Zhou     certId = generateCertId(*cert);
372db029c95SKowalski, Kamil 
37336f25142SDhruvaraj Subhashchandran     // Parse the certificate file and populate properties
374e869bb63SNan Zhou     populateProperties(*cert);
375ffad1ef1SMarri Devender Rao 
376ffad1ef1SMarri Devender Rao     // restart watch
377cf06ccdcSNan Zhou     if (certWatch != nullptr)
378ffad1ef1SMarri Devender Rao     {
379cf06ccdcSNan Zhou         certWatch->startWatch();
380ffad1ef1SMarri Devender Rao     }
38136f25142SDhruvaraj Subhashchandran }
38236f25142SDhruvaraj Subhashchandran 
install(X509_STORE & x509Store,const std::string & pem,bool restore)383698a5743SWilly Tu void Certificate::install(X509_STORE& x509Store, const std::string& pem,
384698a5743SWilly Tu                           bool restore)
3856ec13c8fSNan Zhou {
386698a5743SWilly Tu     if (restore)
387698a5743SWilly Tu     {
388f2646271SRavi Teja         lg2::debug("Certificate install, PEM_STR:{PEM_STR}", "PEM_STR", pem);
389698a5743SWilly Tu     }
390698a5743SWilly Tu     else
391698a5743SWilly Tu     {
392f2646271SRavi Teja         lg2::info("Certificate install, PEM_STR:{PEM_STR} ", "PEM_STR", pem);
393698a5743SWilly Tu     }
3946ec13c8fSNan Zhou 
395e3d47cd4SNan Zhou     if (certType != CertificateType::authority)
3966ec13c8fSNan Zhou     {
397f2646271SRavi Teja         lg2::error("Bulk install error: Unsupported Type; only authority "
398f2646271SRavi Teja                    "supports bulk install, TYPE:{TYPE}",
399f2646271SRavi Teja                    "TYPE", certificateTypeToString(certType));
4006ec13c8fSNan Zhou         elog<InternalFailure>();
4016ec13c8fSNan Zhou     }
4026ec13c8fSNan Zhou 
4036ec13c8fSNan Zhou     // stop watch for user initiated certificate install
4046ec13c8fSNan Zhou     if (certWatch)
4056ec13c8fSNan Zhou     {
4066ec13c8fSNan Zhou         certWatch->stopWatch();
4076ec13c8fSNan Zhou     }
4086ec13c8fSNan Zhou 
4096ec13c8fSNan Zhou     // Load Certificate file into the X509 structure.
4106ec13c8fSNan Zhou     internal::X509Ptr cert = parseCert(pem);
4116ec13c8fSNan Zhou     // Perform validation; no type specific compare keys function
4126ec13c8fSNan Zhou     validateCertificateAgainstStore(x509Store, *cert);
4136ec13c8fSNan Zhou     validateCertificateStartDate(*cert);
4146ec13c8fSNan Zhou     validateCertificateInSSLContext(*cert);
4156ec13c8fSNan Zhou 
4166ec13c8fSNan Zhou     // Copy the PEM to the installation path
4176ec13c8fSNan Zhou     dumpCertificate(pem, certFilePath);
4186ec13c8fSNan Zhou     storageUpdate();
4196ec13c8fSNan Zhou     // Keep certificate ID
4206ec13c8fSNan Zhou     certId = generateCertId(*cert);
4216ec13c8fSNan Zhou     // Parse the certificate file and populate properties
4226ec13c8fSNan Zhou     populateProperties(*cert);
4236ec13c8fSNan Zhou     // restart watch
4246ec13c8fSNan Zhou     if (certWatch)
4256ec13c8fSNan Zhou     {
4266ec13c8fSNan Zhou         certWatch->startWatch();
4276ec13c8fSNan Zhou     }
4286ec13c8fSNan Zhou }
4296ec13c8fSNan Zhou 
populateProperties()43036f25142SDhruvaraj Subhashchandran void Certificate::populateProperties()
43136f25142SDhruvaraj Subhashchandran {
432e869bb63SNan Zhou     internal::X509Ptr cert = loadCert(certInstallPath);
433e869bb63SNan Zhou     populateProperties(*cert);
434db029c95SKowalski, Kamil }
435db029c95SKowalski, Kamil 
getCertId() const4362f3563ccSZbigniew Lukwinski std::string Certificate::getCertId() const
437db029c95SKowalski, Kamil {
4382f3563ccSZbigniew Lukwinski     return certId;
4392f3563ccSZbigniew Lukwinski }
4402f3563ccSZbigniew Lukwinski 
isSame(const std::string & certPath)4412f3563ccSZbigniew Lukwinski bool Certificate::isSame(const std::string& certPath)
4422f3563ccSZbigniew Lukwinski {
443e869bb63SNan Zhou     internal::X509Ptr cert = loadCert(certPath);
444e869bb63SNan Zhou     return getCertId() == generateCertId(*cert);
4452f3563ccSZbigniew Lukwinski }
4462f3563ccSZbigniew Lukwinski 
storageUpdate()4472f3563ccSZbigniew Lukwinski void Certificate::storageUpdate()
4482f3563ccSZbigniew Lukwinski {
449e3d47cd4SNan Zhou     if (certType == CertificateType::authority)
4502f3563ccSZbigniew Lukwinski     {
4512f3563ccSZbigniew Lukwinski         // Create symbolic link in the certificate directory
4522f3563ccSZbigniew Lukwinski         std::string certFileX509Path;
4532f3563ccSZbigniew Lukwinski         try
4542f3563ccSZbigniew Lukwinski         {
4552f3563ccSZbigniew Lukwinski             if (!certFilePath.empty() &&
4562f3563ccSZbigniew Lukwinski                 fs::is_regular_file(fs::path(certFilePath)))
4572f3563ccSZbigniew Lukwinski             {
4582f3563ccSZbigniew Lukwinski                 certFileX509Path =
4592f3563ccSZbigniew Lukwinski                     generateAuthCertFileX509Path(certFilePath, certInstallPath);
4602f3563ccSZbigniew Lukwinski                 fs::create_symlink(fs::path(certFilePath),
4612f3563ccSZbigniew Lukwinski                                    fs::path(certFileX509Path));
4622f3563ccSZbigniew Lukwinski             }
4632f3563ccSZbigniew Lukwinski         }
4642f3563ccSZbigniew Lukwinski         catch (const std::exception& e)
4652f3563ccSZbigniew Lukwinski         {
466f2646271SRavi Teja             lg2::error("Failed to create symlink for certificate, ERR:{ERR},"
467f2646271SRavi Teja                        "FILE:{FILE}, SYMLINK:{SYMLINK}",
468f2646271SRavi Teja                        "ERR", e, "FILE", certFilePath, "SYMLINK",
469f2646271SRavi Teja                        certFileX509Path);
4702f3563ccSZbigniew Lukwinski             elog<InternalFailure>();
4712f3563ccSZbigniew Lukwinski         }
4722f3563ccSZbigniew Lukwinski     }
473db029c95SKowalski, Kamil }
474db029c95SKowalski, Kamil 
populateProperties(X509 & cert)475e869bb63SNan Zhou void Certificate::populateProperties(X509& cert)
476db029c95SKowalski, Kamil {
47736f25142SDhruvaraj Subhashchandran     // Update properties if no error thrown
478cf06ccdcSNan Zhou     BIOMemPtr certBio(BIO_new(BIO_s_mem()), BIO_free);
479e869bb63SNan Zhou     PEM_write_bio_X509(certBio.get(), &cert);
480cf06ccdcSNan Zhou     BufMemPtr certBuf(BUF_MEM_new(), BUF_MEM_free);
48136f25142SDhruvaraj Subhashchandran     BUF_MEM* buf = certBuf.get();
48236f25142SDhruvaraj Subhashchandran     BIO_get_mem_ptr(certBio.get(), &buf);
48336f25142SDhruvaraj Subhashchandran     std::string certStr(buf->data, buf->length);
484cf06ccdcSNan Zhou     certificateString(certStr);
48536f25142SDhruvaraj Subhashchandran 
48636f25142SDhruvaraj Subhashchandran     static const int maxKeySize = 4096;
48736f25142SDhruvaraj Subhashchandran     char subBuffer[maxKeySize] = {0};
488cf06ccdcSNan Zhou     BIOMemPtr subBio(BIO_new(BIO_s_mem()), BIO_free);
4895d4f7932SManojkiran Eda     // This pointer cannot be freed independently.
490e869bb63SNan Zhou     X509_NAME* sub = X509_get_subject_name(&cert);
491dec5877cSMarri Devender Rao     X509_NAME_print_ex(subBio.get(), sub, 0, XN_FLAG_SEP_COMMA_PLUS);
492dec5877cSMarri Devender Rao     BIO_read(subBio.get(), subBuffer, maxKeySize);
493cf06ccdcSNan Zhou     subject(subBuffer);
49436f25142SDhruvaraj Subhashchandran 
49536f25142SDhruvaraj Subhashchandran     char issuerBuffer[maxKeySize] = {0};
496cf06ccdcSNan Zhou     BIOMemPtr issuerBio(BIO_new(BIO_s_mem()), BIO_free);
4975d4f7932SManojkiran Eda     // This pointer cannot be freed independently.
498e3d47cd4SNan Zhou     X509_NAME* issuerName = X509_get_issuer_name(&cert);
499e3d47cd4SNan Zhou     X509_NAME_print_ex(issuerBio.get(), issuerName, 0, XN_FLAG_SEP_COMMA_PLUS);
500dec5877cSMarri Devender Rao     BIO_read(issuerBio.get(), issuerBuffer, maxKeySize);
501cf06ccdcSNan Zhou     issuer(issuerBuffer);
50236f25142SDhruvaraj Subhashchandran 
50336f25142SDhruvaraj Subhashchandran     std::vector<std::string> keyUsageList;
50436f25142SDhruvaraj Subhashchandran 
50536f25142SDhruvaraj Subhashchandran     // Go through each usage in the bit string and convert to
50636f25142SDhruvaraj Subhashchandran     // corresponding string value
507cb1ee9dcSJayanth Othayoth     ASN1_BIT_STRING* usage = static_cast<ASN1_BIT_STRING*>(
508cb1ee9dcSJayanth Othayoth         X509_get_ext_d2i(&cert, NID_key_usage, nullptr, nullptr));
509cb1ee9dcSJayanth Othayoth     if (usage != nullptr)
51036f25142SDhruvaraj Subhashchandran     {
51136f25142SDhruvaraj Subhashchandran         for (auto i = 0; i < usage->length; ++i)
51236f25142SDhruvaraj Subhashchandran         {
51336f25142SDhruvaraj Subhashchandran             for (auto& x : keyUsageToRfStr)
51436f25142SDhruvaraj Subhashchandran             {
51536f25142SDhruvaraj Subhashchandran                 if (x.first & usage->data[i])
51636f25142SDhruvaraj Subhashchandran                 {
51736f25142SDhruvaraj Subhashchandran                     keyUsageList.push_back(x.second);
51836f25142SDhruvaraj Subhashchandran                     break;
51936f25142SDhruvaraj Subhashchandran                 }
52036f25142SDhruvaraj Subhashchandran             }
52136f25142SDhruvaraj Subhashchandran         }
52236f25142SDhruvaraj Subhashchandran     }
52336f25142SDhruvaraj Subhashchandran 
524cb1ee9dcSJayanth Othayoth     EXTENDED_KEY_USAGE* extUsage = static_cast<EXTENDED_KEY_USAGE*>(
525cb1ee9dcSJayanth Othayoth         X509_get_ext_d2i(&cert, NID_ext_key_usage, nullptr, nullptr));
526cb1ee9dcSJayanth Othayoth     if (extUsage == nullptr)
52736f25142SDhruvaraj Subhashchandran     {
52836f25142SDhruvaraj Subhashchandran         for (int i = 0; i < sk_ASN1_OBJECT_num(extUsage); i++)
52936f25142SDhruvaraj Subhashchandran         {
53036f25142SDhruvaraj Subhashchandran             keyUsageList.push_back(extendedKeyUsageToRfStr[OBJ_obj2nid(
53136f25142SDhruvaraj Subhashchandran                 sk_ASN1_OBJECT_value(extUsage, i))]);
53236f25142SDhruvaraj Subhashchandran         }
53336f25142SDhruvaraj Subhashchandran     }
534cf06ccdcSNan Zhou     keyUsage(keyUsageList);
53536f25142SDhruvaraj Subhashchandran 
53636f25142SDhruvaraj Subhashchandran     int days = 0;
53736f25142SDhruvaraj Subhashchandran     int secs = 0;
53836f25142SDhruvaraj Subhashchandran 
539cf06ccdcSNan Zhou     ASN1TimePtr epoch(ASN1_TIME_new(), ASN1_STRING_free);
540cf811c43SNan Zhou     // Set time to 00:00am GMT, Jan 1 1970; format: YYYYMMDDHHMMSSZ
541cf811c43SNan Zhou     ASN1_TIME_set_string(epoch.get(), "19700101000000Z");
54236f25142SDhruvaraj Subhashchandran 
5438a59ea28SJayanth Othayoth     constexpr uint64_t dayToSeconds = 86400; // 24 * 60 * 60
544e869bb63SNan Zhou     ASN1_TIME* notAfter = X509_get_notAfter(&cert);
54536f25142SDhruvaraj Subhashchandran     ASN1_TIME_diff(&days, &secs, epoch.get(), notAfter);
546cf06ccdcSNan Zhou     validNotAfter((days * dayToSeconds) + secs);
54736f25142SDhruvaraj Subhashchandran 
548e869bb63SNan Zhou     ASN1_TIME* notBefore = X509_get_notBefore(&cert);
54936f25142SDhruvaraj Subhashchandran     ASN1_TIME_diff(&days, &secs, epoch.get(), notBefore);
550cf06ccdcSNan Zhou     validNotBefore((days * dayToSeconds) + secs);
5516ceec40bSMarri Devender Rao }
5526ceec40bSMarri Devender Rao 
checkAndAppendPrivateKey(const std::string & filePath)553cd30c496SMarri Devender Rao void Certificate::checkAndAppendPrivateKey(const std::string& filePath)
554cd30c496SMarri Devender Rao {
555cf06ccdcSNan Zhou     BIOMemPtr keyBio(BIO_new(BIO_s_file()), ::BIO_free);
556cd30c496SMarri Devender Rao     if (!keyBio)
557cd30c496SMarri Devender Rao     {
558f2646271SRavi Teja         lg2::error("Error occurred during BIO_s_file call, FILE:{FILE}", "FILE",
559f2646271SRavi Teja                    filePath);
560cd30c496SMarri Devender Rao         elog<InternalFailure>();
561cd30c496SMarri Devender Rao     }
562cd30c496SMarri Devender Rao     BIO_read_filename(keyBio.get(), filePath.c_str());
563cd30c496SMarri Devender Rao 
564cf06ccdcSNan Zhou     EVPPkeyPtr priKey(
565cd30c496SMarri Devender Rao         PEM_read_bio_PrivateKey(keyBio.get(), nullptr, nullptr, nullptr),
566cd30c496SMarri Devender Rao         ::EVP_PKEY_free);
567cd30c496SMarri Devender Rao     if (!priKey)
568cd30c496SMarri Devender Rao     {
569f2646271SRavi Teja         lg2::info("Private key not present in file, FILE:{FILE}", "FILE",
570f2646271SRavi Teja                   filePath);
571cd30c496SMarri Devender Rao         fs::path privateKeyFile = fs::path(certInstallPath).parent_path();
572718eef37SNan Zhou         privateKeyFile = privateKeyFile / defaultPrivateKeyFileName;
573cd30c496SMarri Devender Rao         if (!fs::exists(privateKeyFile))
574cd30c496SMarri Devender Rao         {
575f2646271SRavi Teja             lg2::error("Private key file is not found, FILE:{FILE}", "FILE",
576f2646271SRavi Teja                        privateKeyFile);
577cd30c496SMarri Devender Rao             elog<InternalFailure>();
578cd30c496SMarri Devender Rao         }
579cd30c496SMarri Devender Rao 
580cd30c496SMarri Devender Rao         std::ifstream privKeyFileStream;
581cd30c496SMarri Devender Rao         std::ofstream certFileStream;
582a2f68d8bSPatrick Williams         privKeyFileStream.exceptions(
583a2f68d8bSPatrick Williams             std::ifstream::failbit | std::ifstream::badbit |
584cd30c496SMarri Devender Rao             std::ifstream::eofbit);
585a2f68d8bSPatrick Williams         certFileStream.exceptions(
586a2f68d8bSPatrick Williams             std::ofstream::failbit | std::ofstream::badbit |
587cd30c496SMarri Devender Rao             std::ofstream::eofbit);
588cd30c496SMarri Devender Rao         try
589cd30c496SMarri Devender Rao         {
590cd30c496SMarri Devender Rao             privKeyFileStream.open(privateKeyFile);
591cd30c496SMarri Devender Rao             certFileStream.open(filePath, std::ios::app);
59218e51c92SMarri Devender Rao             certFileStream << std::endl; // insert line break
593cd30c496SMarri Devender Rao             certFileStream << privKeyFileStream.rdbuf() << std::flush;
594cd30c496SMarri Devender Rao             privKeyFileStream.close();
595cd30c496SMarri Devender Rao             certFileStream.close();
596cd30c496SMarri Devender Rao         }
597cd30c496SMarri Devender Rao         catch (const std::exception& e)
598cd30c496SMarri Devender Rao         {
599f2646271SRavi Teja             lg2::error(
600f2646271SRavi Teja                 "Failed to append private key, ERR:{ERR}, SRC:{SRC}, DST:{DST}",
601f2646271SRavi Teja                 "ERR", e, "SRC", privateKeyFile, "DST", filePath);
602cd30c496SMarri Devender Rao             elog<InternalFailure>();
603cd30c496SMarri Devender Rao         }
604cd30c496SMarri Devender Rao     }
605cd30c496SMarri Devender Rao }
606cd30c496SMarri Devender Rao 
compareKeys(const std::string & filePath)6076ceec40bSMarri Devender Rao bool Certificate::compareKeys(const std::string& filePath)
6086ceec40bSMarri Devender Rao {
609f2646271SRavi Teja     lg2::info("Certificate compareKeys, FILEPATH:{FILEPATH}", "FILEPATH",
610f2646271SRavi Teja               filePath);
611cf06ccdcSNan Zhou     internal::X509Ptr cert(X509_new(), ::X509_free);
6126ceec40bSMarri Devender Rao     if (!cert)
6136ceec40bSMarri Devender Rao     {
614f2646271SRavi Teja         lg2::error(
615f2646271SRavi Teja             "Error occurred during X509_new call, FILE:{FILE}, ERRCODE:{ERRCODE}",
616f2646271SRavi Teja             "FILE", filePath, "ERRCODE", ERR_get_error());
6176ceec40bSMarri Devender Rao         elog<InternalFailure>();
6186ceec40bSMarri Devender Rao     }
6196ceec40bSMarri Devender Rao 
620cf06ccdcSNan Zhou     BIOMemPtr bioCert(BIO_new_file(filePath.c_str(), "rb"), ::BIO_free);
6216ceec40bSMarri Devender Rao     if (!bioCert)
6226ceec40bSMarri Devender Rao     {
623f2646271SRavi Teja         lg2::error("Error occurred during BIO_new_file call, FILE:{FILE}",
624f2646271SRavi Teja                    "FILE", filePath);
6256ceec40bSMarri Devender Rao         elog<InternalFailure>();
6266ceec40bSMarri Devender Rao     }
6276ceec40bSMarri Devender Rao 
6286ceec40bSMarri Devender Rao     X509* x509 = cert.get();
6296ceec40bSMarri Devender Rao     PEM_read_bio_X509(bioCert.get(), &x509, nullptr, nullptr);
6306ceec40bSMarri Devender Rao 
631cf06ccdcSNan Zhou     EVPPkeyPtr pubKey(X509_get_pubkey(cert.get()), ::EVP_PKEY_free);
6326ceec40bSMarri Devender Rao     if (!pubKey)
6336ceec40bSMarri Devender Rao     {
634f2646271SRavi Teja         lg2::error(
635f2646271SRavi Teja             "Error occurred during X509_get_pubkey, FILE:{FILE}, ERRCODE:{ERRCODE}",
636f2646271SRavi Teja             "FILE", filePath, "ERRCODE", ERR_get_error());
637cf06ccdcSNan Zhou         elog<InvalidCertificateError>(
638cf06ccdcSNan Zhou             InvalidCertificate::REASON("Failed to get public key info"));
6396ceec40bSMarri Devender Rao     }
6406ceec40bSMarri Devender Rao 
641cf06ccdcSNan Zhou     BIOMemPtr keyBio(BIO_new(BIO_s_file()), ::BIO_free);
6426ceec40bSMarri Devender Rao     if (!keyBio)
6436ceec40bSMarri Devender Rao     {
644f2646271SRavi Teja         lg2::error("Error occurred during BIO_s_file call, FILE:{FILE}", "FILE",
645f2646271SRavi Teja                    filePath);
6466ceec40bSMarri Devender Rao         elog<InternalFailure>();
6476ceec40bSMarri Devender Rao     }
6486ceec40bSMarri Devender Rao     BIO_read_filename(keyBio.get(), filePath.c_str());
6496ceec40bSMarri Devender Rao 
650cf06ccdcSNan Zhou     EVPPkeyPtr priKey(
6516ceec40bSMarri Devender Rao         PEM_read_bio_PrivateKey(keyBio.get(), nullptr, nullptr, nullptr),
6526ceec40bSMarri Devender Rao         ::EVP_PKEY_free);
6536ceec40bSMarri Devender Rao     if (!priKey)
6546ceec40bSMarri Devender Rao     {
655f2646271SRavi Teja         lg2::error(
656f2646271SRavi Teja             "Error occurred during PEM_read_bio_PrivateKey, FILE:{FILE}, ERRCODE:{ERRCODE}",
657f2646271SRavi Teja             "FILE", filePath, "ERRCODE", ERR_get_error());
658cf06ccdcSNan Zhou         elog<InvalidCertificateError>(
659cf06ccdcSNan Zhou             InvalidCertificate::REASON("Failed to get private key info"));
6606ceec40bSMarri Devender Rao     }
6616ceec40bSMarri Devender Rao 
66255ceaa2bSPatrick Williams #if (OPENSSL_VERSION_NUMBER < 0x30000000L)
6636ceec40bSMarri Devender Rao     int32_t rc = EVP_PKEY_cmp(priKey.get(), pubKey.get());
66455ceaa2bSPatrick Williams #else
66555ceaa2bSPatrick Williams     int32_t rc = EVP_PKEY_eq(priKey.get(), pubKey.get());
66655ceaa2bSPatrick Williams #endif
6676ceec40bSMarri Devender Rao     if (rc != 1)
6686ceec40bSMarri Devender Rao     {
669f2646271SRavi Teja         lg2::error(
670f2646271SRavi Teja             "Private key is not matching with Certificate, FILE:{FILE}, ERRCODE:{ERRCODE}",
671f2646271SRavi Teja             "FILE", filePath, "ERRCODE", rc);
6726ceec40bSMarri Devender Rao         return false;
6736ceec40bSMarri Devender Rao     }
6746ceec40bSMarri Devender Rao     return true;
6756ceec40bSMarri Devender Rao }
6766ceec40bSMarri Devender Rao 
delete_()677a3bb38fbSZbigniew Kurzynski void Certificate::delete_()
678a3bb38fbSZbigniew Kurzynski {
6792f3563ccSZbigniew Lukwinski     manager.deleteCertificate(this);
680a3bb38fbSZbigniew Kurzynski }
6816ec13c8fSNan Zhou 
getObjectPath()6826ec13c8fSNan Zhou std::string Certificate::getObjectPath()
6836ec13c8fSNan Zhou {
6846ec13c8fSNan Zhou     return objectPath;
6856ec13c8fSNan Zhou }
6866ec13c8fSNan Zhou 
getCertFilePath()6876ec13c8fSNan Zhou std::string Certificate::getCertFilePath()
6886ec13c8fSNan Zhou {
6896ec13c8fSNan Zhou     return certFilePath;
6906ec13c8fSNan Zhou }
6916ec13c8fSNan Zhou 
setCertFilePath(const std::string & path)6926ec13c8fSNan Zhou void Certificate::setCertFilePath(const std::string& path)
6936ec13c8fSNan Zhou {
6946ec13c8fSNan Zhou     certFilePath = path;
6956ec13c8fSNan Zhou }
6966ec13c8fSNan Zhou 
setCertInstallPath(const std::string & path)6976ec13c8fSNan Zhou void Certificate::setCertInstallPath(const std::string& path)
6986ec13c8fSNan Zhou {
6996ec13c8fSNan Zhou     certInstallPath = path;
7006ec13c8fSNan Zhou }
7016ec13c8fSNan Zhou 
702e1289adfSNan Zhou } // namespace phosphor::certs
703