1cfbc8dc8SJayanth Othayoth #include "certs_manager.hpp" 2cfbc8dc8SJayanth Othayoth 3*f4682712SMarri Devender Rao #include <openssl/pem.h> 4*f4682712SMarri Devender Rao #include <unistd.h> 5*f4682712SMarri Devender Rao 66ceec40bSMarri Devender Rao #include <phosphor-logging/elog-errors.hpp> 713bf74e4SMarri Devender Rao #include <xyz/openbmc_project/Certs/error.hpp> 8cfbc8dc8SJayanth Othayoth #include <xyz/openbmc_project/Common/error.hpp> 9cfbc8dc8SJayanth Othayoth namespace phosphor 10cfbc8dc8SJayanth Othayoth { 11cfbc8dc8SJayanth Othayoth namespace certs 12cfbc8dc8SJayanth Othayoth { 131396511dSMarri Devender Rao using InternalFailure = 141396511dSMarri Devender Rao sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 15cfbc8dc8SJayanth Othayoth 16*f4682712SMarri Devender Rao using X509_REQ_Ptr = std::unique_ptr<X509_REQ, decltype(&::X509_REQ_free)>; 17*f4682712SMarri Devender Rao using BIGNUM_Ptr = std::unique_ptr<BIGNUM, decltype(&::BN_free)>; 18*f4682712SMarri Devender Rao 19*f4682712SMarri Devender Rao Manager::Manager(sdbusplus::bus::bus& bus, sdeventplus::Event& event, 20*f4682712SMarri Devender Rao const char* path, const CertificateType& type, 21*f4682712SMarri Devender Rao UnitsToRestart&& unit, CertInstallPath&& installPath) : 226ceec40bSMarri Devender Rao Ifaces(bus, path), 23*f4682712SMarri Devender Rao bus(bus), event(event), objectPath(path), certType(type), 24*f4682712SMarri Devender Rao unitToRestart(std::move(unit)), certInstallPath(std::move(installPath)), 25*f4682712SMarri Devender Rao childPtr(nullptr) 26cfbc8dc8SJayanth Othayoth { 2713bf74e4SMarri Devender Rao using InvalidCertificate = 2813bf74e4SMarri Devender Rao sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate; 2913bf74e4SMarri Devender Rao using Reason = xyz::openbmc_project::Certs::InvalidCertificate::REASON; 30bf7c588cSMarri Devender Rao if (fs::exists(certInstallPath)) 31bf7c588cSMarri Devender Rao { 32bf7c588cSMarri Devender Rao try 33bf7c588cSMarri Devender Rao { 34bf7c588cSMarri Devender Rao // TODO: Issue#3 At present supporting only one certificate to be 35bf7c588cSMarri Devender Rao // uploaded this need to be revisited to support multiple 36bf7c588cSMarri Devender Rao // certificates 37bf7c588cSMarri Devender Rao auto certObjectPath = objectPath + '/' + '1'; 38bf7c588cSMarri Devender Rao certificatePtr = std::make_unique<Certificate>( 39bf7c588cSMarri Devender Rao bus, certObjectPath, certType, unitToRestart, certInstallPath, 408f80c35bSMarri Devender Rao certInstallPath, true); 41bf7c588cSMarri Devender Rao } 42bf7c588cSMarri Devender Rao catch (const InternalFailure& e) 43bf7c588cSMarri Devender Rao { 44bf7c588cSMarri Devender Rao report<InternalFailure>(); 45bf7c588cSMarri Devender Rao } 46bf7c588cSMarri Devender Rao catch (const InvalidCertificate& e) 47bf7c588cSMarri Devender Rao { 48bf7c588cSMarri Devender Rao report<InvalidCertificate>( 49bf7c588cSMarri Devender Rao Reason("Existing certificate file is corrupted")); 50bf7c588cSMarri Devender Rao } 51bf7c588cSMarri Devender Rao } 52dd74bd20SJayanth Othayoth } 53589159f2SJayanth Othayoth 546ceec40bSMarri Devender Rao void Manager::install(const std::string filePath) 55cfbc8dc8SJayanth Othayoth { 561396511dSMarri Devender Rao using NotAllowed = 571396511dSMarri Devender Rao sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 581396511dSMarri Devender Rao using Reason = xyz::openbmc_project::Common::NotAllowed::REASON; 591396511dSMarri Devender Rao // TODO: Issue#3 At present supporting only one certificate to be 601396511dSMarri Devender Rao // uploaded this need to be revisited to support multiple 611396511dSMarri Devender Rao // certificates 621396511dSMarri Devender Rao if (certificatePtr != nullptr) 631396511dSMarri Devender Rao { 641396511dSMarri Devender Rao elog<NotAllowed>(Reason("Certificate already exist")); 651396511dSMarri Devender Rao } 661396511dSMarri Devender Rao auto certObjectPath = objectPath + '/' + '1'; 678f80c35bSMarri Devender Rao certificatePtr = std::make_unique<Certificate>( 688f80c35bSMarri Devender Rao bus, certObjectPath, certType, unitToRestart, certInstallPath, filePath, 698f80c35bSMarri Devender Rao false); 70589159f2SJayanth Othayoth } 71ae70b3daSDeepak Kodihalli 72ae70b3daSDeepak Kodihalli void Manager::delete_() 73ae70b3daSDeepak Kodihalli { 746ceec40bSMarri Devender Rao // TODO: #Issue 4 when a certificate is deleted system auto generates 756ceec40bSMarri Devender Rao // certificate file. At present we are not supporting creation of 766ceec40bSMarri Devender Rao // certificate object for the auto-generated certificate file as 776ceec40bSMarri Devender Rao // deletion if only applicable for REST server and Bmcweb does not allow 786ceec40bSMarri Devender Rao // deletion of certificates 796ceec40bSMarri Devender Rao if (certificatePtr != nullptr) 80ae70b3daSDeepak Kodihalli { 816ceec40bSMarri Devender Rao certificatePtr.reset(nullptr); 82ae70b3daSDeepak Kodihalli } 83ae70b3daSDeepak Kodihalli } 84*f4682712SMarri Devender Rao 85*f4682712SMarri Devender Rao std::string Manager::generateCSR( 86*f4682712SMarri Devender Rao std::vector<std::string> alternativeNames, std::string challengePassword, 87*f4682712SMarri Devender Rao std::string city, std::string commonName, std::string contactPerson, 88*f4682712SMarri Devender Rao std::string country, std::string email, std::string givenName, 89*f4682712SMarri Devender Rao std::string initials, int64_t keyBitLength, std::string keyCurveId, 90*f4682712SMarri Devender Rao std::string keyPairAlgorithm, std::vector<std::string> keyUsage, 91*f4682712SMarri Devender Rao std::string organization, std::string organizationalUnit, std::string state, 92*f4682712SMarri Devender Rao std::string surname, std::string unstructuredName) 93*f4682712SMarri Devender Rao { 94*f4682712SMarri Devender Rao // We support only one CSR. 95*f4682712SMarri Devender Rao csrPtr.reset(nullptr); 96*f4682712SMarri Devender Rao auto pid = fork(); 97*f4682712SMarri Devender Rao if (pid == -1) 98*f4682712SMarri Devender Rao { 99*f4682712SMarri Devender Rao log<level::ERR>("Error occurred during forking process"); 100*f4682712SMarri Devender Rao report<InternalFailure>(); 101*f4682712SMarri Devender Rao } 102*f4682712SMarri Devender Rao else if (pid == 0) 103*f4682712SMarri Devender Rao { 104*f4682712SMarri Devender Rao try 105*f4682712SMarri Devender Rao { 106*f4682712SMarri Devender Rao generateCSRHelper(alternativeNames, challengePassword, city, 107*f4682712SMarri Devender Rao commonName, contactPerson, country, email, 108*f4682712SMarri Devender Rao givenName, initials, keyBitLength, keyCurveId, 109*f4682712SMarri Devender Rao keyPairAlgorithm, keyUsage, organization, 110*f4682712SMarri Devender Rao organizationalUnit, state, surname, 111*f4682712SMarri Devender Rao unstructuredName); 112*f4682712SMarri Devender Rao exit(EXIT_SUCCESS); 113*f4682712SMarri Devender Rao } 114*f4682712SMarri Devender Rao catch (const InternalFailure& e) 115*f4682712SMarri Devender Rao { 116*f4682712SMarri Devender Rao // commit the error reported in child process and exit 117*f4682712SMarri Devender Rao // Callback method from SDEvent Loop looks for exit status 118*f4682712SMarri Devender Rao exit(EXIT_FAILURE); 119*f4682712SMarri Devender Rao commit<InternalFailure>(); 120*f4682712SMarri Devender Rao } 121*f4682712SMarri Devender Rao } 122*f4682712SMarri Devender Rao else 123*f4682712SMarri Devender Rao { 124*f4682712SMarri Devender Rao using namespace sdeventplus::source; 125*f4682712SMarri Devender Rao Child::Callback callback = [this](Child& eventSource, 126*f4682712SMarri Devender Rao const siginfo_t* si) { 127*f4682712SMarri Devender Rao eventSource.set_enabled(Enabled::On); 128*f4682712SMarri Devender Rao if (si->si_status != 0) 129*f4682712SMarri Devender Rao { 130*f4682712SMarri Devender Rao this->createCSRObject(Status::FAILURE); 131*f4682712SMarri Devender Rao } 132*f4682712SMarri Devender Rao else 133*f4682712SMarri Devender Rao { 134*f4682712SMarri Devender Rao this->createCSRObject(Status::SUCCESS); 135*f4682712SMarri Devender Rao } 136*f4682712SMarri Devender Rao }; 137*f4682712SMarri Devender Rao try 138*f4682712SMarri Devender Rao { 139*f4682712SMarri Devender Rao sigset_t ss; 140*f4682712SMarri Devender Rao if (sigemptyset(&ss) < 0) 141*f4682712SMarri Devender Rao { 142*f4682712SMarri Devender Rao log<level::ERR>("Unable to initialize signal set"); 143*f4682712SMarri Devender Rao elog<InternalFailure>(); 144*f4682712SMarri Devender Rao } 145*f4682712SMarri Devender Rao if (sigaddset(&ss, SIGCHLD) < 0) 146*f4682712SMarri Devender Rao { 147*f4682712SMarri Devender Rao log<level::ERR>("Unable to add signal to signal set"); 148*f4682712SMarri Devender Rao elog<InternalFailure>(); 149*f4682712SMarri Devender Rao } 150*f4682712SMarri Devender Rao 151*f4682712SMarri Devender Rao // Block SIGCHLD first, so that the event loop can handle it 152*f4682712SMarri Devender Rao if (sigprocmask(SIG_BLOCK, &ss, NULL) < 0) 153*f4682712SMarri Devender Rao { 154*f4682712SMarri Devender Rao log<level::ERR>("Unable to block signal"); 155*f4682712SMarri Devender Rao elog<InternalFailure>(); 156*f4682712SMarri Devender Rao } 157*f4682712SMarri Devender Rao if (childPtr) 158*f4682712SMarri Devender Rao { 159*f4682712SMarri Devender Rao childPtr.reset(); 160*f4682712SMarri Devender Rao } 161*f4682712SMarri Devender Rao childPtr = std::make_unique<Child>(event, pid, WEXITED | WSTOPPED, 162*f4682712SMarri Devender Rao std::move(callback)); 163*f4682712SMarri Devender Rao } 164*f4682712SMarri Devender Rao catch (const InternalFailure& e) 165*f4682712SMarri Devender Rao { 166*f4682712SMarri Devender Rao commit<InternalFailure>(); 167*f4682712SMarri Devender Rao } 168*f4682712SMarri Devender Rao } 169*f4682712SMarri Devender Rao auto csrObjectPath = objectPath + '/' + "csr"; 170*f4682712SMarri Devender Rao return csrObjectPath; 171*f4682712SMarri Devender Rao } 172*f4682712SMarri Devender Rao 173*f4682712SMarri Devender Rao void Manager::generateCSRHelper( 174*f4682712SMarri Devender Rao std::vector<std::string> alternativeNames, std::string challengePassword, 175*f4682712SMarri Devender Rao std::string city, std::string commonName, std::string contactPerson, 176*f4682712SMarri Devender Rao std::string country, std::string email, std::string givenName, 177*f4682712SMarri Devender Rao std::string initials, int64_t keyBitLength, std::string keyCurveId, 178*f4682712SMarri Devender Rao std::string keyPairAlgorithm, std::vector<std::string> keyUsage, 179*f4682712SMarri Devender Rao std::string organization, std::string organizationalUnit, std::string state, 180*f4682712SMarri Devender Rao std::string surname, std::string unstructuredName) 181*f4682712SMarri Devender Rao { 182*f4682712SMarri Devender Rao int ret = 0; 183*f4682712SMarri Devender Rao 184*f4682712SMarri Devender Rao // set version of x509 req 185*f4682712SMarri Devender Rao int nVersion = 1; 186*f4682712SMarri Devender Rao // TODO: Issue#6 need to make version number configurable 187*f4682712SMarri Devender Rao X509_REQ_Ptr x509Req(X509_REQ_new(), ::X509_REQ_free); 188*f4682712SMarri Devender Rao ret = X509_REQ_set_version(x509Req.get(), nVersion); 189*f4682712SMarri Devender Rao if (ret == 0) 190*f4682712SMarri Devender Rao { 191*f4682712SMarri Devender Rao log<level::ERR>("Error occured during X509_REQ_set_version call"); 192*f4682712SMarri Devender Rao elog<InternalFailure>(); 193*f4682712SMarri Devender Rao } 194*f4682712SMarri Devender Rao 195*f4682712SMarri Devender Rao // set subject of x509 req 196*f4682712SMarri Devender Rao X509_NAME* x509Name = X509_REQ_get_subject_name(x509Req.get()); 197*f4682712SMarri Devender Rao 198*f4682712SMarri Devender Rao if (!alternativeNames.empty()) 199*f4682712SMarri Devender Rao { 200*f4682712SMarri Devender Rao for (auto& name : alternativeNames) 201*f4682712SMarri Devender Rao { 202*f4682712SMarri Devender Rao addEntry(x509Name, "subjectAltName", name); 203*f4682712SMarri Devender Rao } 204*f4682712SMarri Devender Rao } 205*f4682712SMarri Devender Rao addEntry(x509Name, "challengePassword", challengePassword); 206*f4682712SMarri Devender Rao addEntry(x509Name, "L", city); 207*f4682712SMarri Devender Rao addEntry(x509Name, "CN", commonName); 208*f4682712SMarri Devender Rao addEntry(x509Name, "name", contactPerson); 209*f4682712SMarri Devender Rao addEntry(x509Name, "C", country); 210*f4682712SMarri Devender Rao addEntry(x509Name, "emailAddress", email); 211*f4682712SMarri Devender Rao addEntry(x509Name, "GN", givenName); 212*f4682712SMarri Devender Rao addEntry(x509Name, "initials", initials); 213*f4682712SMarri Devender Rao addEntry(x509Name, "algorithm", keyPairAlgorithm); 214*f4682712SMarri Devender Rao if (!keyUsage.empty()) 215*f4682712SMarri Devender Rao { 216*f4682712SMarri Devender Rao for (auto& usage : keyUsage) 217*f4682712SMarri Devender Rao { 218*f4682712SMarri Devender Rao addEntry(x509Name, "keyUsage", usage); 219*f4682712SMarri Devender Rao } 220*f4682712SMarri Devender Rao } 221*f4682712SMarri Devender Rao addEntry(x509Name, "O", organization); 222*f4682712SMarri Devender Rao addEntry(x509Name, "ST", state); 223*f4682712SMarri Devender Rao addEntry(x509Name, "SN", surname); 224*f4682712SMarri Devender Rao addEntry(x509Name, "unstructuredName", unstructuredName); 225*f4682712SMarri Devender Rao 226*f4682712SMarri Devender Rao // Generate private key and write to file 227*f4682712SMarri Devender Rao EVP_PKEY_Ptr pKey = writePrivateKey(keyBitLength, x509Req); 228*f4682712SMarri Devender Rao 229*f4682712SMarri Devender Rao // set sign key of x509 req 230*f4682712SMarri Devender Rao ret = X509_REQ_sign(x509Req.get(), pKey.get(), EVP_sha256()); 231*f4682712SMarri Devender Rao if (ret <= 0) 232*f4682712SMarri Devender Rao { 233*f4682712SMarri Devender Rao log<level::ERR>("Error occured while signing key of x509"); 234*f4682712SMarri Devender Rao elog<InternalFailure>(); 235*f4682712SMarri Devender Rao } 236*f4682712SMarri Devender Rao log<level::INFO>("Writing CSR to file"); 237*f4682712SMarri Devender Rao std::string path = fs::path(certInstallPath).parent_path(); 238*f4682712SMarri Devender Rao std::string csrFilePath = path + '/' + CSR_FILE_NAME; 239*f4682712SMarri Devender Rao writeCSR(csrFilePath, x509Req); 240*f4682712SMarri Devender Rao } 241*f4682712SMarri Devender Rao 242*f4682712SMarri Devender Rao EVP_PKEY_Ptr Manager::writePrivateKey(int64_t keyBitLength, 243*f4682712SMarri Devender Rao X509_REQ_Ptr& x509Req) 244*f4682712SMarri Devender Rao { 245*f4682712SMarri Devender Rao int ret = 0; 246*f4682712SMarri Devender Rao // generate rsa key 247*f4682712SMarri Devender Rao BIGNUM_Ptr bne(BN_new(), ::BN_free); 248*f4682712SMarri Devender Rao ret = BN_set_word(bne.get(), RSA_F4); 249*f4682712SMarri Devender Rao if (ret == 0) 250*f4682712SMarri Devender Rao { 251*f4682712SMarri Devender Rao log<level::ERR>("Error occured during BN_set_word call"); 252*f4682712SMarri Devender Rao elog<InternalFailure>(); 253*f4682712SMarri Devender Rao } 254*f4682712SMarri Devender Rao 255*f4682712SMarri Devender Rao // set keybit length to default value if not set 256*f4682712SMarri Devender Rao if (keyBitLength <= 0) 257*f4682712SMarri Devender Rao { 258*f4682712SMarri Devender Rao keyBitLength = 2048; 259*f4682712SMarri Devender Rao } 260*f4682712SMarri Devender Rao RSA* rsa = RSA_new(); 261*f4682712SMarri Devender Rao ret = RSA_generate_key_ex(rsa, keyBitLength, bne.get(), NULL); 262*f4682712SMarri Devender Rao if (ret != 1) 263*f4682712SMarri Devender Rao { 264*f4682712SMarri Devender Rao free(rsa); 265*f4682712SMarri Devender Rao log<level::ERR>("Error occured during RSA_generate_key_ex call", 266*f4682712SMarri Devender Rao entry("KEYBITLENGTH=%PRIu64", keyBitLength)); 267*f4682712SMarri Devender Rao elog<InternalFailure>(); 268*f4682712SMarri Devender Rao } 269*f4682712SMarri Devender Rao 270*f4682712SMarri Devender Rao // set public key of x509 req 271*f4682712SMarri Devender Rao EVP_PKEY_Ptr pKey(EVP_PKEY_new(), ::EVP_PKEY_free); 272*f4682712SMarri Devender Rao EVP_PKEY_assign_RSA(pKey.get(), rsa); 273*f4682712SMarri Devender Rao ret = X509_REQ_set_pubkey(x509Req.get(), pKey.get()); 274*f4682712SMarri Devender Rao if (ret == 0) 275*f4682712SMarri Devender Rao { 276*f4682712SMarri Devender Rao log<level::ERR>("Error occured while setting Public key"); 277*f4682712SMarri Devender Rao elog<InternalFailure>(); 278*f4682712SMarri Devender Rao } 279*f4682712SMarri Devender Rao 280*f4682712SMarri Devender Rao log<level::ERR>("Writing private key to file"); 281*f4682712SMarri Devender Rao // write private key to file 282*f4682712SMarri Devender Rao std::string path = fs::path(certInstallPath).parent_path(); 283*f4682712SMarri Devender Rao std::string privKeyPath = path + '/' + PRIV_KEY_FILE_NAME; 284*f4682712SMarri Devender Rao 285*f4682712SMarri Devender Rao FILE* fp = std::fopen(privKeyPath.c_str(), "w"); 286*f4682712SMarri Devender Rao if (fp == NULL) 287*f4682712SMarri Devender Rao { 288*f4682712SMarri Devender Rao ret = -1; 289*f4682712SMarri Devender Rao log<level::ERR>("Error occured creating private key file"); 290*f4682712SMarri Devender Rao elog<InternalFailure>(); 291*f4682712SMarri Devender Rao } 292*f4682712SMarri Devender Rao ret = PEM_write_PrivateKey(fp, pKey.get(), NULL, NULL, 0, 0, NULL); 293*f4682712SMarri Devender Rao std::fclose(fp); 294*f4682712SMarri Devender Rao if (ret == 0) 295*f4682712SMarri Devender Rao { 296*f4682712SMarri Devender Rao log<level::ERR>("Error occured while writing private key to file"); 297*f4682712SMarri Devender Rao elog<InternalFailure>(); 298*f4682712SMarri Devender Rao } 299*f4682712SMarri Devender Rao return pKey; 300*f4682712SMarri Devender Rao } 301*f4682712SMarri Devender Rao 302*f4682712SMarri Devender Rao void Manager::addEntry(X509_NAME* x509Name, const char* field, 303*f4682712SMarri Devender Rao const std::string& bytes) 304*f4682712SMarri Devender Rao { 305*f4682712SMarri Devender Rao if (bytes.empty()) 306*f4682712SMarri Devender Rao { 307*f4682712SMarri Devender Rao return; 308*f4682712SMarri Devender Rao } 309*f4682712SMarri Devender Rao int ret = X509_NAME_add_entry_by_txt( 310*f4682712SMarri Devender Rao x509Name, field, MBSTRING_ASC, 311*f4682712SMarri Devender Rao reinterpret_cast<const unsigned char*>(bytes.c_str()), -1, -1, 0); 312*f4682712SMarri Devender Rao if (ret != 1) 313*f4682712SMarri Devender Rao { 314*f4682712SMarri Devender Rao log<level::ERR>("Unable to set entry", entry("FIELD=%s", field), 315*f4682712SMarri Devender Rao entry("VALUE=%s", bytes.c_str())); 316*f4682712SMarri Devender Rao elog<InternalFailure>(); 317*f4682712SMarri Devender Rao } 318*f4682712SMarri Devender Rao } 319*f4682712SMarri Devender Rao 320*f4682712SMarri Devender Rao void Manager::createCSRObject(const Status& status) 321*f4682712SMarri Devender Rao { 322*f4682712SMarri Devender Rao if (csrPtr) 323*f4682712SMarri Devender Rao { 324*f4682712SMarri Devender Rao csrPtr.reset(nullptr); 325*f4682712SMarri Devender Rao } 326*f4682712SMarri Devender Rao auto csrObjectPath = objectPath + '/' + "csr"; 327*f4682712SMarri Devender Rao csrPtr = std::make_unique<CSR>(bus, csrObjectPath.c_str(), 328*f4682712SMarri Devender Rao certInstallPath.c_str(), status); 329*f4682712SMarri Devender Rao } 330*f4682712SMarri Devender Rao 331*f4682712SMarri Devender Rao void Manager::writeCSR(const std::string& filePath, const X509_REQ_Ptr& x509Req) 332*f4682712SMarri Devender Rao { 333*f4682712SMarri Devender Rao if (fs::exists(filePath)) 334*f4682712SMarri Devender Rao { 335*f4682712SMarri Devender Rao log<level::INFO>("Removing the existing file", 336*f4682712SMarri Devender Rao entry("FILENAME=%s", filePath.c_str())); 337*f4682712SMarri Devender Rao if (!fs::remove(filePath.c_str())) 338*f4682712SMarri Devender Rao { 339*f4682712SMarri Devender Rao log<level::ERR>("Unable to remove the file", 340*f4682712SMarri Devender Rao entry("FILENAME=%s", filePath.c_str())); 341*f4682712SMarri Devender Rao elog<InternalFailure>(); 342*f4682712SMarri Devender Rao } 343*f4682712SMarri Devender Rao } 344*f4682712SMarri Devender Rao 345*f4682712SMarri Devender Rao FILE* fp = NULL; 346*f4682712SMarri Devender Rao 347*f4682712SMarri Devender Rao if ((fp = std::fopen(filePath.c_str(), "w")) == NULL) 348*f4682712SMarri Devender Rao { 349*f4682712SMarri Devender Rao log<level::ERR>("Error opening the file to write the CSR", 350*f4682712SMarri Devender Rao entry("FILENAME=%s", filePath.c_str())); 351*f4682712SMarri Devender Rao elog<InternalFailure>(); 352*f4682712SMarri Devender Rao } 353*f4682712SMarri Devender Rao 354*f4682712SMarri Devender Rao int rc = PEM_write_X509_REQ(fp, x509Req.get()); 355*f4682712SMarri Devender Rao if (!rc) 356*f4682712SMarri Devender Rao { 357*f4682712SMarri Devender Rao log<level::ERR>("PEM write routine failed", 358*f4682712SMarri Devender Rao entry("FILENAME=%s", filePath.c_str())); 359*f4682712SMarri Devender Rao std::fclose(fp); 360*f4682712SMarri Devender Rao elog<InternalFailure>(); 361*f4682712SMarri Devender Rao } 362*f4682712SMarri Devender Rao std::fclose(fp); 363*f4682712SMarri Devender Rao } 364*f4682712SMarri Devender Rao 365cfbc8dc8SJayanth Othayoth } // namespace certs 366cfbc8dc8SJayanth Othayoth } // namespace phosphor 367