xref: /openbmc/phosphor-certificate-manager/certs_manager.cpp (revision fe590c4e28e28f611162f5766681d6396d6fd59b)
1cfbc8dc8SJayanth Othayoth #include "certs_manager.hpp"
2cfbc8dc8SJayanth Othayoth 
3f4682712SMarri Devender Rao #include <openssl/pem.h>
4f4682712SMarri Devender Rao #include <unistd.h>
5f4682712SMarri Devender Rao 
6a3bb38fbSZbigniew Kurzynski #include <algorithm>
76ceec40bSMarri Devender Rao #include <phosphor-logging/elog-errors.hpp>
813bf74e4SMarri Devender Rao #include <xyz/openbmc_project/Certs/error.hpp>
9cfbc8dc8SJayanth Othayoth #include <xyz/openbmc_project/Common/error.hpp>
10cfbc8dc8SJayanth Othayoth namespace phosphor
11cfbc8dc8SJayanth Othayoth {
12cfbc8dc8SJayanth Othayoth namespace certs
13cfbc8dc8SJayanth Othayoth {
141396511dSMarri Devender Rao using InternalFailure =
151396511dSMarri Devender Rao     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
16ffad1ef1SMarri Devender Rao using InvalidCertificate =
17ffad1ef1SMarri Devender Rao     sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate;
18ffad1ef1SMarri Devender Rao using Reason = xyz::openbmc_project::Certs::InvalidCertificate::REASON;
19cfbc8dc8SJayanth Othayoth 
20f4682712SMarri Devender Rao using X509_REQ_Ptr = std::unique_ptr<X509_REQ, decltype(&::X509_REQ_free)>;
21f4682712SMarri Devender Rao using BIGNUM_Ptr = std::unique_ptr<BIGNUM, decltype(&::BN_free)>;
22c6e58c7eSRamesh Iyyar using InvalidArgument =
23c6e58c7eSRamesh Iyyar     sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
24c6e58c7eSRamesh Iyyar using Argument = xyz::openbmc_project::Common::InvalidArgument;
25c6e58c7eSRamesh Iyyar 
26c6e58c7eSRamesh Iyyar constexpr auto SUPPORTED_KEYBITLENGTH = 2048;
27f4682712SMarri Devender Rao 
28f4682712SMarri Devender Rao Manager::Manager(sdbusplus::bus::bus& bus, sdeventplus::Event& event,
29f4682712SMarri Devender Rao                  const char* path, const CertificateType& type,
30f4682712SMarri Devender Rao                  UnitsToRestart&& unit, CertInstallPath&& installPath) :
316ceec40bSMarri Devender Rao     Ifaces(bus, path),
32f4682712SMarri Devender Rao     bus(bus), event(event), objectPath(path), certType(type),
33c6e58c7eSRamesh Iyyar     unitToRestart(std::move(unit)), certInstallPath(std::move(installPath)),
34c6e58c7eSRamesh Iyyar     certParentInstallPath(fs::path(certInstallPath).parent_path())
35cfbc8dc8SJayanth Othayoth {
36*fe590c4eSZbigniew Lukwinski     // Create certificate directory if not existing.
37*fe590c4eSZbigniew Lukwinski     // Set correct certificate directory permitions.
38*fe590c4eSZbigniew Lukwinski     fs::path certDirectory;
39b57d75e2SMarri Devender Rao     try
40b57d75e2SMarri Devender Rao     {
41*fe590c4eSZbigniew Lukwinski         if (certType == AUTHORITY)
42b57d75e2SMarri Devender Rao         {
43*fe590c4eSZbigniew Lukwinski             certDirectory = certInstallPath;
44b57d75e2SMarri Devender Rao         }
45*fe590c4eSZbigniew Lukwinski         else
46*fe590c4eSZbigniew Lukwinski         {
47*fe590c4eSZbigniew Lukwinski             certDirectory = certParentInstallPath;
48*fe590c4eSZbigniew Lukwinski         }
49*fe590c4eSZbigniew Lukwinski 
50*fe590c4eSZbigniew Lukwinski         if (!fs::exists(certDirectory))
51*fe590c4eSZbigniew Lukwinski         {
52*fe590c4eSZbigniew Lukwinski             fs::create_directories(certDirectory);
53*fe590c4eSZbigniew Lukwinski         }
54*fe590c4eSZbigniew Lukwinski 
55667286e4SMarri Devender Rao         auto permission = fs::perms::owner_read | fs::perms::owner_write |
56667286e4SMarri Devender Rao                           fs::perms::owner_exec;
57*fe590c4eSZbigniew Lukwinski         fs::permissions(certDirectory, permission, fs::perm_options::replace);
58b57d75e2SMarri Devender Rao     }
59b57d75e2SMarri Devender Rao     catch (fs::filesystem_error& e)
60b57d75e2SMarri Devender Rao     {
61b57d75e2SMarri Devender Rao         log<level::ERR>("Failed to create directory", entry("ERR=%s", e.what()),
62b57d75e2SMarri Devender Rao                         entry("DIRECTORY=%s", certParentInstallPath.c_str()));
63b57d75e2SMarri Devender Rao         report<InternalFailure>();
64b57d75e2SMarri Devender Rao     }
65b57d75e2SMarri Devender Rao 
66c6e58c7eSRamesh Iyyar     // Generating RSA private key file if certificate type is server/client
67c6e58c7eSRamesh Iyyar     if (certType != AUTHORITY)
68c6e58c7eSRamesh Iyyar     {
69c6e58c7eSRamesh Iyyar         createRSAPrivateKeyFile();
70c6e58c7eSRamesh Iyyar     }
71c6e58c7eSRamesh Iyyar 
72ffad1ef1SMarri Devender Rao     // restore any existing certificates
73db029c95SKowalski, Kamil     createCertificates();
74ffad1ef1SMarri Devender Rao 
75ffad1ef1SMarri Devender Rao     // watch is not required for authority certificates
76ffad1ef1SMarri Devender Rao     if (certType != AUTHORITY)
77ffad1ef1SMarri Devender Rao     {
78ffad1ef1SMarri Devender Rao         // watch for certificate file create/replace
79ffad1ef1SMarri Devender Rao         certWatchPtr = std::make_unique<
80ffad1ef1SMarri Devender Rao             Watch>(event, certInstallPath, [this]() {
81bf7c588cSMarri Devender Rao             try
82bf7c588cSMarri Devender Rao             {
83ffad1ef1SMarri Devender Rao                 // if certificate file existing update it
84db029c95SKowalski, Kamil                 if (!installedCerts.empty())
85ffad1ef1SMarri Devender Rao                 {
86ffad1ef1SMarri Devender Rao                     log<level::INFO>(
87ffad1ef1SMarri Devender Rao                         "Inotify callback to update certificate properties");
88db029c95SKowalski, Kamil                     installedCerts[0]->populateProperties();
89ffad1ef1SMarri Devender Rao                 }
90ffad1ef1SMarri Devender Rao                 else
91ffad1ef1SMarri Devender Rao                 {
92ffad1ef1SMarri Devender Rao                     log<level::INFO>(
93ffad1ef1SMarri Devender Rao                         "Inotify callback to create certificate object");
94db029c95SKowalski, Kamil                     createCertificates();
95ffad1ef1SMarri Devender Rao                 }
96bf7c588cSMarri Devender Rao             }
97bf7c588cSMarri Devender Rao             catch (const InternalFailure& e)
98bf7c588cSMarri Devender Rao             {
99ffad1ef1SMarri Devender Rao                 commit<InternalFailure>();
100bf7c588cSMarri Devender Rao             }
101bf7c588cSMarri Devender Rao             catch (const InvalidCertificate& e)
102bf7c588cSMarri Devender Rao             {
103ffad1ef1SMarri Devender Rao                 commit<InvalidCertificate>();
104bf7c588cSMarri Devender Rao             }
105ffad1ef1SMarri Devender Rao         });
106bf7c588cSMarri Devender Rao     }
107db029c95SKowalski, Kamil     else
108db029c95SKowalski, Kamil     {
109db029c95SKowalski, Kamil         const std::string signleCertPath = "/etc/ssl/certs/Root-CA.pem";
110db029c95SKowalski, Kamil         if (fs::exists(signleCertPath) && !fs::is_empty(signleCertPath))
111db029c95SKowalski, Kamil         {
112db029c95SKowalski, Kamil             log<level::NOTICE>(
113db029c95SKowalski, Kamil                 "Legacy certificate detected, will be installed from: ",
114db029c95SKowalski, Kamil                 entry("SINGLE_CERTPATH=%s", signleCertPath.c_str()));
115db029c95SKowalski, Kamil             install(signleCertPath);
116db029c95SKowalski, Kamil             if (!fs::remove(signleCertPath))
117db029c95SKowalski, Kamil             {
118db029c95SKowalski, Kamil                 log<level::ERR>(
119db029c95SKowalski, Kamil                     "Unable to remove old certificate from: ",
120db029c95SKowalski, Kamil                     entry("SINGLE_CERTPATH=%s", signleCertPath.c_str()));
121db029c95SKowalski, Kamil                 elog<InternalFailure>();
122db029c95SKowalski, Kamil             }
123db029c95SKowalski, Kamil         }
124db029c95SKowalski, Kamil     }
125dd74bd20SJayanth Othayoth }
126589159f2SJayanth Othayoth 
12706a69d7bSZbigniew Kurzynski std::string Manager::install(const std::string filePath)
128cfbc8dc8SJayanth Othayoth {
1291396511dSMarri Devender Rao     using NotAllowed =
1301396511dSMarri Devender Rao         sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
1311396511dSMarri Devender Rao     using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
132db029c95SKowalski, Kamil 
133db029c95SKowalski, Kamil     if (certType != phosphor::certs::AUTHORITY && !installedCerts.empty())
1341396511dSMarri Devender Rao     {
1351396511dSMarri Devender Rao         elog<NotAllowed>(Reason("Certificate already exist"));
1361396511dSMarri Devender Rao     }
1373b07b77aSZbigniew Lukwinski     else if (certType == phosphor::certs::AUTHORITY &&
1383b07b77aSZbigniew Lukwinski              installedCerts.size() >= AUTHORITY_CERTIFICATES_LIMIT)
1393b07b77aSZbigniew Lukwinski     {
1403b07b77aSZbigniew Lukwinski         elog<NotAllowed>(Reason("Certificates limit reached"));
1413b07b77aSZbigniew Lukwinski     }
142ffad1ef1SMarri Devender Rao 
143db029c95SKowalski, Kamil     auto certObjectPath = objectPath + '/' + std::to_string(certIdCounter++);
144db029c95SKowalski, Kamil 
145db029c95SKowalski, Kamil     installedCerts.emplace_back(std::make_unique<Certificate>(
1468f80c35bSMarri Devender Rao         bus, certObjectPath, certType, unitToRestart, certInstallPath, filePath,
147a3bb38fbSZbigniew Kurzynski         false, certWatchPtr, *this));
14806a69d7bSZbigniew Kurzynski     return certObjectPath;
149589159f2SJayanth Othayoth }
150ae70b3daSDeepak Kodihalli 
151a3bb38fbSZbigniew Kurzynski void Manager::deleteAll()
152ae70b3daSDeepak Kodihalli {
1536ceec40bSMarri Devender Rao     // TODO: #Issue 4 when a certificate is deleted system auto generates
1546ceec40bSMarri Devender Rao     // certificate file. At present we are not supporting creation of
1556ceec40bSMarri Devender Rao     // certificate object for the auto-generated certificate file as
1566ceec40bSMarri Devender Rao     // deletion if only applicable for REST server and Bmcweb does not allow
1576ceec40bSMarri Devender Rao     // deletion of certificates
158db029c95SKowalski, Kamil     installedCerts.clear();
159ae70b3daSDeepak Kodihalli }
160f4682712SMarri Devender Rao 
161a3bb38fbSZbigniew Kurzynski void Manager::deleteCertificate(const std::string& certHash)
162a3bb38fbSZbigniew Kurzynski {
163a3bb38fbSZbigniew Kurzynski     std::vector<std::unique_ptr<Certificate>>::iterator const& certIt =
164a3bb38fbSZbigniew Kurzynski         std::find_if(installedCerts.begin(), installedCerts.end(),
165a3bb38fbSZbigniew Kurzynski                      [certHash](std::unique_ptr<Certificate> const& cert) {
166a3bb38fbSZbigniew Kurzynski                          return cert->getHash().compare(certHash) == 0;
167a3bb38fbSZbigniew Kurzynski                      });
168a3bb38fbSZbigniew Kurzynski     if (certIt != installedCerts.end())
169a3bb38fbSZbigniew Kurzynski     {
170a3bb38fbSZbigniew Kurzynski         installedCerts.erase(certIt);
171a3bb38fbSZbigniew Kurzynski     }
172a3bb38fbSZbigniew Kurzynski     else
173a3bb38fbSZbigniew Kurzynski     {
174a3bb38fbSZbigniew Kurzynski         log<level::ERR>("Certificate does not exist",
175a3bb38fbSZbigniew Kurzynski                         entry("HASH=%s", certHash.c_str()));
176a3bb38fbSZbigniew Kurzynski         elog<InternalFailure>();
177a3bb38fbSZbigniew Kurzynski     }
178a3bb38fbSZbigniew Kurzynski }
179a3bb38fbSZbigniew Kurzynski 
180f4682712SMarri Devender Rao std::string Manager::generateCSR(
181f4682712SMarri Devender Rao     std::vector<std::string> alternativeNames, std::string challengePassword,
182f4682712SMarri Devender Rao     std::string city, std::string commonName, std::string contactPerson,
183f4682712SMarri Devender Rao     std::string country, std::string email, std::string givenName,
184f4682712SMarri Devender Rao     std::string initials, int64_t keyBitLength, std::string keyCurveId,
185f4682712SMarri Devender Rao     std::string keyPairAlgorithm, std::vector<std::string> keyUsage,
186f4682712SMarri Devender Rao     std::string organization, std::string organizationalUnit, std::string state,
187f4682712SMarri Devender Rao     std::string surname, std::string unstructuredName)
188f4682712SMarri Devender Rao {
189f4682712SMarri Devender Rao     // We support only one CSR.
190f4682712SMarri Devender Rao     csrPtr.reset(nullptr);
191f4682712SMarri Devender Rao     auto pid = fork();
192f4682712SMarri Devender Rao     if (pid == -1)
193f4682712SMarri Devender Rao     {
194f4682712SMarri Devender Rao         log<level::ERR>("Error occurred during forking process");
195f4682712SMarri Devender Rao         report<InternalFailure>();
196f4682712SMarri Devender Rao     }
197f4682712SMarri Devender Rao     else if (pid == 0)
198f4682712SMarri Devender Rao     {
199f4682712SMarri Devender Rao         try
200f4682712SMarri Devender Rao         {
201f4682712SMarri Devender Rao             generateCSRHelper(alternativeNames, challengePassword, city,
202f4682712SMarri Devender Rao                               commonName, contactPerson, country, email,
203f4682712SMarri Devender Rao                               givenName, initials, keyBitLength, keyCurveId,
204f4682712SMarri Devender Rao                               keyPairAlgorithm, keyUsage, organization,
205f4682712SMarri Devender Rao                               organizationalUnit, state, surname,
206f4682712SMarri Devender Rao                               unstructuredName);
207f4682712SMarri Devender Rao             exit(EXIT_SUCCESS);
208f4682712SMarri Devender Rao         }
209f4682712SMarri Devender Rao         catch (const InternalFailure& e)
210f4682712SMarri Devender Rao         {
211f4682712SMarri Devender Rao             // commit the error reported in child process and exit
212f4682712SMarri Devender Rao             // Callback method from SDEvent Loop looks for exit status
213f4682712SMarri Devender Rao             exit(EXIT_FAILURE);
214f4682712SMarri Devender Rao             commit<InternalFailure>();
215f4682712SMarri Devender Rao         }
216f4682712SMarri Devender Rao     }
217f4682712SMarri Devender Rao     else
218f4682712SMarri Devender Rao     {
219f4682712SMarri Devender Rao         using namespace sdeventplus::source;
220f4682712SMarri Devender Rao         Child::Callback callback = [this](Child& eventSource,
221f4682712SMarri Devender Rao                                           const siginfo_t* si) {
222f4682712SMarri Devender Rao             eventSource.set_enabled(Enabled::On);
223f4682712SMarri Devender Rao             if (si->si_status != 0)
224f4682712SMarri Devender Rao             {
225f4682712SMarri Devender Rao                 this->createCSRObject(Status::FAILURE);
226f4682712SMarri Devender Rao             }
227f4682712SMarri Devender Rao             else
228f4682712SMarri Devender Rao             {
229f4682712SMarri Devender Rao                 this->createCSRObject(Status::SUCCESS);
230f4682712SMarri Devender Rao             }
231f4682712SMarri Devender Rao         };
232f4682712SMarri Devender Rao         try
233f4682712SMarri Devender Rao         {
234f4682712SMarri Devender Rao             sigset_t ss;
235f4682712SMarri Devender Rao             if (sigemptyset(&ss) < 0)
236f4682712SMarri Devender Rao             {
237f4682712SMarri Devender Rao                 log<level::ERR>("Unable to initialize signal set");
238f4682712SMarri Devender Rao                 elog<InternalFailure>();
239f4682712SMarri Devender Rao             }
240f4682712SMarri Devender Rao             if (sigaddset(&ss, SIGCHLD) < 0)
241f4682712SMarri Devender Rao             {
242f4682712SMarri Devender Rao                 log<level::ERR>("Unable to add signal to signal set");
243f4682712SMarri Devender Rao                 elog<InternalFailure>();
244f4682712SMarri Devender Rao             }
245f4682712SMarri Devender Rao 
246f4682712SMarri Devender Rao             // Block SIGCHLD first, so that the event loop can handle it
247f4682712SMarri Devender Rao             if (sigprocmask(SIG_BLOCK, &ss, NULL) < 0)
248f4682712SMarri Devender Rao             {
249f4682712SMarri Devender Rao                 log<level::ERR>("Unable to block signal");
250f4682712SMarri Devender Rao                 elog<InternalFailure>();
251f4682712SMarri Devender Rao             }
252f4682712SMarri Devender Rao             if (childPtr)
253f4682712SMarri Devender Rao             {
254f4682712SMarri Devender Rao                 childPtr.reset();
255f4682712SMarri Devender Rao             }
256f4682712SMarri Devender Rao             childPtr = std::make_unique<Child>(event, pid, WEXITED | WSTOPPED,
257f4682712SMarri Devender Rao                                                std::move(callback));
258f4682712SMarri Devender Rao         }
259f4682712SMarri Devender Rao         catch (const InternalFailure& e)
260f4682712SMarri Devender Rao         {
261f4682712SMarri Devender Rao             commit<InternalFailure>();
262f4682712SMarri Devender Rao         }
263f4682712SMarri Devender Rao     }
264f4682712SMarri Devender Rao     auto csrObjectPath = objectPath + '/' + "csr";
265f4682712SMarri Devender Rao     return csrObjectPath;
266f4682712SMarri Devender Rao }
267f4682712SMarri Devender Rao 
268db029c95SKowalski, Kamil std::vector<std::unique_ptr<Certificate>>& Manager::getCertificates()
269ffad1ef1SMarri Devender Rao {
270db029c95SKowalski, Kamil     return installedCerts;
271ffad1ef1SMarri Devender Rao }
272ffad1ef1SMarri Devender Rao 
273f4682712SMarri Devender Rao void Manager::generateCSRHelper(
274f4682712SMarri Devender Rao     std::vector<std::string> alternativeNames, std::string challengePassword,
275f4682712SMarri Devender Rao     std::string city, std::string commonName, std::string contactPerson,
276f4682712SMarri Devender Rao     std::string country, std::string email, std::string givenName,
277f4682712SMarri Devender Rao     std::string initials, int64_t keyBitLength, std::string keyCurveId,
278f4682712SMarri Devender Rao     std::string keyPairAlgorithm, std::vector<std::string> keyUsage,
279f4682712SMarri Devender Rao     std::string organization, std::string organizationalUnit, std::string state,
280f4682712SMarri Devender Rao     std::string surname, std::string unstructuredName)
281f4682712SMarri Devender Rao {
282f4682712SMarri Devender Rao     int ret = 0;
283f4682712SMarri Devender Rao 
284f4682712SMarri Devender Rao     // set version of x509 req
285f4682712SMarri Devender Rao     int nVersion = 1;
286f4682712SMarri Devender Rao     // TODO: Issue#6 need to make version number configurable
287f4682712SMarri Devender Rao     X509_REQ_Ptr x509Req(X509_REQ_new(), ::X509_REQ_free);
288f4682712SMarri Devender Rao     ret = X509_REQ_set_version(x509Req.get(), nVersion);
289f4682712SMarri Devender Rao     if (ret == 0)
290f4682712SMarri Devender Rao     {
291f4682712SMarri Devender Rao         log<level::ERR>("Error occured during X509_REQ_set_version call");
292f4682712SMarri Devender Rao         elog<InternalFailure>();
293f4682712SMarri Devender Rao     }
294f4682712SMarri Devender Rao 
295f4682712SMarri Devender Rao     // set subject of x509 req
296f4682712SMarri Devender Rao     X509_NAME* x509Name = X509_REQ_get_subject_name(x509Req.get());
297f4682712SMarri Devender Rao 
298f4682712SMarri Devender Rao     if (!alternativeNames.empty())
299f4682712SMarri Devender Rao     {
300f4682712SMarri Devender Rao         for (auto& name : alternativeNames)
301f4682712SMarri Devender Rao         {
302f4682712SMarri Devender Rao             addEntry(x509Name, "subjectAltName", name);
303f4682712SMarri Devender Rao         }
304f4682712SMarri Devender Rao     }
305f4682712SMarri Devender Rao     addEntry(x509Name, "challengePassword", challengePassword);
306f4682712SMarri Devender Rao     addEntry(x509Name, "L", city);
307f4682712SMarri Devender Rao     addEntry(x509Name, "CN", commonName);
308f4682712SMarri Devender Rao     addEntry(x509Name, "name", contactPerson);
309f4682712SMarri Devender Rao     addEntry(x509Name, "C", country);
310f4682712SMarri Devender Rao     addEntry(x509Name, "emailAddress", email);
311f4682712SMarri Devender Rao     addEntry(x509Name, "GN", givenName);
312f4682712SMarri Devender Rao     addEntry(x509Name, "initials", initials);
313f4682712SMarri Devender Rao     addEntry(x509Name, "algorithm", keyPairAlgorithm);
314f4682712SMarri Devender Rao     if (!keyUsage.empty())
315f4682712SMarri Devender Rao     {
316f4682712SMarri Devender Rao         for (auto& usage : keyUsage)
317f4682712SMarri Devender Rao         {
3187641105dSMarri Devender Rao             if (isExtendedKeyUsage(usage))
3197641105dSMarri Devender Rao             {
3207641105dSMarri Devender Rao                 addEntry(x509Name, "extendedKeyUsage", usage);
3217641105dSMarri Devender Rao             }
3227641105dSMarri Devender Rao             else
3237641105dSMarri Devender Rao             {
324f4682712SMarri Devender Rao                 addEntry(x509Name, "keyUsage", usage);
325f4682712SMarri Devender Rao             }
326f4682712SMarri Devender Rao         }
3277641105dSMarri Devender Rao     }
328f4682712SMarri Devender Rao     addEntry(x509Name, "O", organization);
329f4682712SMarri Devender Rao     addEntry(x509Name, "ST", state);
330f4682712SMarri Devender Rao     addEntry(x509Name, "SN", surname);
331f4682712SMarri Devender Rao     addEntry(x509Name, "unstructuredName", unstructuredName);
332f4682712SMarri Devender Rao 
3338a09b52aSRamesh Iyyar     EVP_PKEY_Ptr pKey(nullptr, ::EVP_PKEY_free);
3348a09b52aSRamesh Iyyar 
3358a09b52aSRamesh Iyyar     log<level::INFO>("Given Key pair algorithm",
3368a09b52aSRamesh Iyyar                      entry("KEYPAIRALGORITHM=%s", keyPairAlgorithm.c_str()));
3378a09b52aSRamesh Iyyar 
3388a09b52aSRamesh Iyyar     // Used EC algorithm as default if user did not give algorithm type.
3398a09b52aSRamesh Iyyar     if (keyPairAlgorithm == "RSA")
340c6e58c7eSRamesh Iyyar         pKey = getRSAKeyPair(keyBitLength);
3418a09b52aSRamesh Iyyar     else if ((keyPairAlgorithm == "EC") || (keyPairAlgorithm.empty()))
342c6e58c7eSRamesh Iyyar         pKey = generateECKeyPair(keyCurveId);
3438a09b52aSRamesh Iyyar     else
3448a09b52aSRamesh Iyyar     {
3458a09b52aSRamesh Iyyar         log<level::ERR>("Given Key pair algorithm is not supported. Supporting "
3468a09b52aSRamesh Iyyar                         "RSA and EC only");
3478a09b52aSRamesh Iyyar         elog<InvalidArgument>(
3488a09b52aSRamesh Iyyar             Argument::ARGUMENT_NAME("KEYPAIRALGORITHM"),
3498a09b52aSRamesh Iyyar             Argument::ARGUMENT_VALUE(keyPairAlgorithm.c_str()));
3508a09b52aSRamesh Iyyar     }
3518a09b52aSRamesh Iyyar 
3528a09b52aSRamesh Iyyar     ret = X509_REQ_set_pubkey(x509Req.get(), pKey.get());
3538a09b52aSRamesh Iyyar     if (ret == 0)
3548a09b52aSRamesh Iyyar     {
3558a09b52aSRamesh Iyyar         log<level::ERR>("Error occured while setting Public key");
3568a09b52aSRamesh Iyyar         elog<InternalFailure>();
3578a09b52aSRamesh Iyyar     }
3588a09b52aSRamesh Iyyar 
3598a09b52aSRamesh Iyyar     // Write private key to file
360c6e58c7eSRamesh Iyyar     writePrivateKey(pKey, PRIV_KEY_FILE_NAME);
361f4682712SMarri Devender Rao 
362f4682712SMarri Devender Rao     // set sign key of x509 req
363f4682712SMarri Devender Rao     ret = X509_REQ_sign(x509Req.get(), pKey.get(), EVP_sha256());
3648a09b52aSRamesh Iyyar     if (ret == 0)
365f4682712SMarri Devender Rao     {
366f4682712SMarri Devender Rao         log<level::ERR>("Error occured while signing key of x509");
367f4682712SMarri Devender Rao         elog<InternalFailure>();
368f4682712SMarri Devender Rao     }
3698a09b52aSRamesh Iyyar 
370f4682712SMarri Devender Rao     log<level::INFO>("Writing CSR to file");
371c6e58c7eSRamesh Iyyar     fs::path csrFilePath = certParentInstallPath / CSR_FILE_NAME;
372c6e58c7eSRamesh Iyyar     writeCSR(csrFilePath.string(), x509Req);
373f4682712SMarri Devender Rao }
374f4682712SMarri Devender Rao 
3757641105dSMarri Devender Rao bool Manager::isExtendedKeyUsage(const std::string& usage)
3767641105dSMarri Devender Rao {
3777641105dSMarri Devender Rao     const static std::array<const char*, 6> usageList = {
3787641105dSMarri Devender Rao         "ServerAuthentication", "ClientAuthentication", "OCSPSigning",
3797641105dSMarri Devender Rao         "Timestamping",         "CodeSigning",          "EmailProtection"};
3807641105dSMarri Devender Rao     auto it = std::find_if(
3817641105dSMarri Devender Rao         usageList.begin(), usageList.end(),
3827641105dSMarri Devender Rao         [&usage](const char* s) { return (strcmp(s, usage.c_str()) == 0); });
3837641105dSMarri Devender Rao     return it != usageList.end();
3847641105dSMarri Devender Rao }
3858a09b52aSRamesh Iyyar EVP_PKEY_Ptr Manager::generateRSAKeyPair(const int64_t keyBitLength)
386f4682712SMarri Devender Rao {
387f4682712SMarri Devender Rao     int ret = 0;
388f4682712SMarri Devender Rao     // generate rsa key
389f4682712SMarri Devender Rao     BIGNUM_Ptr bne(BN_new(), ::BN_free);
390f4682712SMarri Devender Rao     ret = BN_set_word(bne.get(), RSA_F4);
391f4682712SMarri Devender Rao     if (ret == 0)
392f4682712SMarri Devender Rao     {
393f4682712SMarri Devender Rao         log<level::ERR>("Error occured during BN_set_word call");
394f4682712SMarri Devender Rao         elog<InternalFailure>();
395f4682712SMarri Devender Rao     }
396f4682712SMarri Devender Rao 
3978a09b52aSRamesh Iyyar     int64_t keyBitLen = keyBitLength;
398f4682712SMarri Devender Rao     // set keybit length to default value if not set
3998a09b52aSRamesh Iyyar     if (keyBitLen <= 0)
400f4682712SMarri Devender Rao     {
4018a09b52aSRamesh Iyyar         constexpr auto DEFAULT_KEYBITLENGTH = 2048;
4028a09b52aSRamesh Iyyar         log<level::INFO>(
4038a09b52aSRamesh Iyyar             "KeyBitLength is not given.Hence, using default KeyBitLength",
4048a09b52aSRamesh Iyyar             entry("DEFAULTKEYBITLENGTH=%d", DEFAULT_KEYBITLENGTH));
4058a09b52aSRamesh Iyyar         keyBitLen = DEFAULT_KEYBITLENGTH;
406f4682712SMarri Devender Rao     }
407f4682712SMarri Devender Rao     RSA* rsa = RSA_new();
4088a09b52aSRamesh Iyyar     ret = RSA_generate_key_ex(rsa, keyBitLen, bne.get(), NULL);
409f4682712SMarri Devender Rao     if (ret != 1)
410f4682712SMarri Devender Rao     {
411f4682712SMarri Devender Rao         free(rsa);
412f4682712SMarri Devender Rao         log<level::ERR>("Error occured during RSA_generate_key_ex call",
4138a09b52aSRamesh Iyyar                         entry("KEYBITLENGTH=%PRIu64", keyBitLen));
414f4682712SMarri Devender Rao         elog<InternalFailure>();
415f4682712SMarri Devender Rao     }
416f4682712SMarri Devender Rao 
417f4682712SMarri Devender Rao     // set public key of x509 req
418f4682712SMarri Devender Rao     EVP_PKEY_Ptr pKey(EVP_PKEY_new(), ::EVP_PKEY_free);
4198a09b52aSRamesh Iyyar     ret = EVP_PKEY_assign_RSA(pKey.get(), rsa);
420f4682712SMarri Devender Rao     if (ret == 0)
421f4682712SMarri Devender Rao     {
4228a09b52aSRamesh Iyyar         free(rsa);
4238a09b52aSRamesh Iyyar         log<level::ERR>("Error occured during assign rsa key into EVP");
424f4682712SMarri Devender Rao         elog<InternalFailure>();
425f4682712SMarri Devender Rao     }
426f4682712SMarri Devender Rao 
4278a09b52aSRamesh Iyyar     return pKey;
4288a09b52aSRamesh Iyyar }
4298a09b52aSRamesh Iyyar 
4308a09b52aSRamesh Iyyar EVP_PKEY_Ptr Manager::generateECKeyPair(const std::string& curveId)
4318a09b52aSRamesh Iyyar {
4328a09b52aSRamesh Iyyar     std::string curId(curveId);
4338a09b52aSRamesh Iyyar 
4348a09b52aSRamesh Iyyar     if (curId.empty())
4358a09b52aSRamesh Iyyar     {
4368a09b52aSRamesh Iyyar         // secp224r1 is equal to RSA 2048 KeyBitLength. Refer RFC 5349
4378a09b52aSRamesh Iyyar         constexpr auto DEFAULT_KEYCURVEID = "secp224r1";
4388a09b52aSRamesh Iyyar         log<level::INFO>(
4398a09b52aSRamesh Iyyar             "KeyCurveId is not given. Hence using default curve id",
4408a09b52aSRamesh Iyyar             entry("DEFAULTKEYCURVEID=%s", DEFAULT_KEYCURVEID));
4418a09b52aSRamesh Iyyar         curId = DEFAULT_KEYCURVEID;
4428a09b52aSRamesh Iyyar     }
4438a09b52aSRamesh Iyyar 
4448a09b52aSRamesh Iyyar     int ecGrp = OBJ_txt2nid(curId.c_str());
4458a09b52aSRamesh Iyyar 
4468a09b52aSRamesh Iyyar     if (ecGrp == NID_undef)
4478a09b52aSRamesh Iyyar     {
4488a09b52aSRamesh Iyyar         log<level::ERR>(
4498a09b52aSRamesh Iyyar             "Error occured during convert the curve id string format into NID",
4508a09b52aSRamesh Iyyar             entry("KEYCURVEID=%s", curId.c_str()));
4518a09b52aSRamesh Iyyar         elog<InternalFailure>();
4528a09b52aSRamesh Iyyar     }
4538a09b52aSRamesh Iyyar 
4548a09b52aSRamesh Iyyar     EC_KEY* ecKey = EC_KEY_new_by_curve_name(ecGrp);
4558a09b52aSRamesh Iyyar 
4568a09b52aSRamesh Iyyar     if (ecKey == NULL)
4578a09b52aSRamesh Iyyar     {
4588a09b52aSRamesh Iyyar         log<level::ERR>(
4598a09b52aSRamesh Iyyar             "Error occured during create the EC_Key object from NID",
4608a09b52aSRamesh Iyyar             entry("ECGROUP=%d", ecGrp));
4618a09b52aSRamesh Iyyar         elog<InternalFailure>();
4628a09b52aSRamesh Iyyar     }
4638a09b52aSRamesh Iyyar 
4648a09b52aSRamesh Iyyar     // If you want to save a key and later load it with
4658a09b52aSRamesh Iyyar     // SSL_CTX_use_PrivateKey_file, then you must set the OPENSSL_EC_NAMED_CURVE
4668a09b52aSRamesh Iyyar     // flag on the key.
4678a09b52aSRamesh Iyyar     EC_KEY_set_asn1_flag(ecKey, OPENSSL_EC_NAMED_CURVE);
4688a09b52aSRamesh Iyyar 
4698a09b52aSRamesh Iyyar     int ret = EC_KEY_generate_key(ecKey);
4708a09b52aSRamesh Iyyar 
4718a09b52aSRamesh Iyyar     if (ret == 0)
4728a09b52aSRamesh Iyyar     {
4738a09b52aSRamesh Iyyar         EC_KEY_free(ecKey);
4748a09b52aSRamesh Iyyar         log<level::ERR>("Error occured during generate EC key");
4758a09b52aSRamesh Iyyar         elog<InternalFailure>();
4768a09b52aSRamesh Iyyar     }
4778a09b52aSRamesh Iyyar 
4788a09b52aSRamesh Iyyar     EVP_PKEY_Ptr pKey(EVP_PKEY_new(), ::EVP_PKEY_free);
4798a09b52aSRamesh Iyyar     ret = EVP_PKEY_assign_EC_KEY(pKey.get(), ecKey);
4808a09b52aSRamesh Iyyar     if (ret == 0)
4818a09b52aSRamesh Iyyar     {
4828a09b52aSRamesh Iyyar         EC_KEY_free(ecKey);
4838a09b52aSRamesh Iyyar         log<level::ERR>("Error occured during assign EC Key into EVP");
4848a09b52aSRamesh Iyyar         elog<InternalFailure>();
4858a09b52aSRamesh Iyyar     }
4868a09b52aSRamesh Iyyar 
4878a09b52aSRamesh Iyyar     return pKey;
4888a09b52aSRamesh Iyyar }
4898a09b52aSRamesh Iyyar 
490c6e58c7eSRamesh Iyyar void Manager::writePrivateKey(const EVP_PKEY_Ptr& pKey,
491c6e58c7eSRamesh Iyyar                               const std::string& privKeyFileName)
4928a09b52aSRamesh Iyyar {
4938a09b52aSRamesh Iyyar     log<level::INFO>("Writing private key to file");
494f4682712SMarri Devender Rao     // write private key to file
495c6e58c7eSRamesh Iyyar     fs::path privKeyPath = certParentInstallPath / privKeyFileName;
496f4682712SMarri Devender Rao 
497f4682712SMarri Devender Rao     FILE* fp = std::fopen(privKeyPath.c_str(), "w");
498f4682712SMarri Devender Rao     if (fp == NULL)
499f4682712SMarri Devender Rao     {
500f4682712SMarri Devender Rao         log<level::ERR>("Error occured creating private key file");
501f4682712SMarri Devender Rao         elog<InternalFailure>();
502f4682712SMarri Devender Rao     }
5038a09b52aSRamesh Iyyar     int ret = PEM_write_PrivateKey(fp, pKey.get(), NULL, NULL, 0, 0, NULL);
504f4682712SMarri Devender Rao     std::fclose(fp);
505f4682712SMarri Devender Rao     if (ret == 0)
506f4682712SMarri Devender Rao     {
507f4682712SMarri Devender Rao         log<level::ERR>("Error occured while writing private key to file");
508f4682712SMarri Devender Rao         elog<InternalFailure>();
509f4682712SMarri Devender Rao     }
510f4682712SMarri Devender Rao }
511f4682712SMarri Devender Rao 
512f4682712SMarri Devender Rao void Manager::addEntry(X509_NAME* x509Name, const char* field,
513f4682712SMarri Devender Rao                        const std::string& bytes)
514f4682712SMarri Devender Rao {
515f4682712SMarri Devender Rao     if (bytes.empty())
516f4682712SMarri Devender Rao     {
517f4682712SMarri Devender Rao         return;
518f4682712SMarri Devender Rao     }
519f4682712SMarri Devender Rao     int ret = X509_NAME_add_entry_by_txt(
520f4682712SMarri Devender Rao         x509Name, field, MBSTRING_ASC,
521f4682712SMarri Devender Rao         reinterpret_cast<const unsigned char*>(bytes.c_str()), -1, -1, 0);
522f4682712SMarri Devender Rao     if (ret != 1)
523f4682712SMarri Devender Rao     {
524f4682712SMarri Devender Rao         log<level::ERR>("Unable to set entry", entry("FIELD=%s", field),
525f4682712SMarri Devender Rao                         entry("VALUE=%s", bytes.c_str()));
526f4682712SMarri Devender Rao         elog<InternalFailure>();
527f4682712SMarri Devender Rao     }
528f4682712SMarri Devender Rao }
529f4682712SMarri Devender Rao 
530f4682712SMarri Devender Rao void Manager::createCSRObject(const Status& status)
531f4682712SMarri Devender Rao {
532f4682712SMarri Devender Rao     if (csrPtr)
533f4682712SMarri Devender Rao     {
534f4682712SMarri Devender Rao         csrPtr.reset(nullptr);
535f4682712SMarri Devender Rao     }
536f4682712SMarri Devender Rao     auto csrObjectPath = objectPath + '/' + "csr";
537f4682712SMarri Devender Rao     csrPtr = std::make_unique<CSR>(bus, csrObjectPath.c_str(),
538f4682712SMarri Devender Rao                                    certInstallPath.c_str(), status);
539f4682712SMarri Devender Rao }
540f4682712SMarri Devender Rao 
541f4682712SMarri Devender Rao void Manager::writeCSR(const std::string& filePath, const X509_REQ_Ptr& x509Req)
542f4682712SMarri Devender Rao {
543f4682712SMarri Devender Rao     if (fs::exists(filePath))
544f4682712SMarri Devender Rao     {
545f4682712SMarri Devender Rao         log<level::INFO>("Removing the existing file",
546f4682712SMarri Devender Rao                          entry("FILENAME=%s", filePath.c_str()));
547f4682712SMarri Devender Rao         if (!fs::remove(filePath.c_str()))
548f4682712SMarri Devender Rao         {
549f4682712SMarri Devender Rao             log<level::ERR>("Unable to remove the file",
550f4682712SMarri Devender Rao                             entry("FILENAME=%s", filePath.c_str()));
551f4682712SMarri Devender Rao             elog<InternalFailure>();
552f4682712SMarri Devender Rao         }
553f4682712SMarri Devender Rao     }
554f4682712SMarri Devender Rao 
555f4682712SMarri Devender Rao     FILE* fp = NULL;
556f4682712SMarri Devender Rao 
557f4682712SMarri Devender Rao     if ((fp = std::fopen(filePath.c_str(), "w")) == NULL)
558f4682712SMarri Devender Rao     {
559f4682712SMarri Devender Rao         log<level::ERR>("Error opening the file to write the CSR",
560f4682712SMarri Devender Rao                         entry("FILENAME=%s", filePath.c_str()));
561f4682712SMarri Devender Rao         elog<InternalFailure>();
562f4682712SMarri Devender Rao     }
563f4682712SMarri Devender Rao 
564f4682712SMarri Devender Rao     int rc = PEM_write_X509_REQ(fp, x509Req.get());
565f4682712SMarri Devender Rao     if (!rc)
566f4682712SMarri Devender Rao     {
567f4682712SMarri Devender Rao         log<level::ERR>("PEM write routine failed",
568f4682712SMarri Devender Rao                         entry("FILENAME=%s", filePath.c_str()));
569f4682712SMarri Devender Rao         std::fclose(fp);
570f4682712SMarri Devender Rao         elog<InternalFailure>();
571f4682712SMarri Devender Rao     }
572f4682712SMarri Devender Rao     std::fclose(fp);
573f4682712SMarri Devender Rao }
574f4682712SMarri Devender Rao 
575db029c95SKowalski, Kamil void Manager::createCertificates()
576db029c95SKowalski, Kamil {
577db029c95SKowalski, Kamil     auto certObjectPath = objectPath + '/';
578db029c95SKowalski, Kamil 
579db029c95SKowalski, Kamil     if (certType == phosphor::certs::AUTHORITY)
580db029c95SKowalski, Kamil     {
581*fe590c4eSZbigniew Lukwinski         // Check whether install path is a directory.
582db029c95SKowalski, Kamil         if (!fs::is_directory(certInstallPath))
583db029c95SKowalski, Kamil         {
584db029c95SKowalski, Kamil             log<level::ERR>("Certificate installation path exists and it is "
585db029c95SKowalski, Kamil                             "not a directory");
586db029c95SKowalski, Kamil             elog<InternalFailure>();
587db029c95SKowalski, Kamil             return;
588db029c95SKowalski, Kamil         }
589db029c95SKowalski, Kamil 
590db029c95SKowalski, Kamil         for (auto& path : fs::directory_iterator(certInstallPath))
591ffad1ef1SMarri Devender Rao         {
592ffad1ef1SMarri Devender Rao             try
593ffad1ef1SMarri Devender Rao             {
594db029c95SKowalski, Kamil                 installedCerts.emplace_back(std::make_unique<Certificate>(
595db029c95SKowalski, Kamil                     bus, certObjectPath + std::to_string(certIdCounter++),
596db029c95SKowalski, Kamil                     certType, unitToRestart, certInstallPath, path.path(), true,
597a3bb38fbSZbigniew Kurzynski                     certWatchPtr, *this));
598ffad1ef1SMarri Devender Rao             }
599ffad1ef1SMarri Devender Rao             catch (const InternalFailure& e)
600ffad1ef1SMarri Devender Rao             {
601ffad1ef1SMarri Devender Rao                 report<InternalFailure>();
602ffad1ef1SMarri Devender Rao             }
603ffad1ef1SMarri Devender Rao             catch (const InvalidCertificate& e)
604ffad1ef1SMarri Devender Rao             {
605ffad1ef1SMarri Devender Rao                 report<InvalidCertificate>(
606ffad1ef1SMarri Devender Rao                     Reason("Existing certificate file is corrupted"));
607ffad1ef1SMarri Devender Rao             }
608ffad1ef1SMarri Devender Rao         }
609db029c95SKowalski, Kamil     }
610db029c95SKowalski, Kamil     else if (fs::exists(certInstallPath))
611db029c95SKowalski, Kamil     {
612db029c95SKowalski, Kamil         try
613db029c95SKowalski, Kamil         {
614db029c95SKowalski, Kamil             installedCerts.emplace_back(std::make_unique<Certificate>(
615db029c95SKowalski, Kamil                 bus, certObjectPath + '1', certType, unitToRestart,
616a3bb38fbSZbigniew Kurzynski                 certInstallPath, certInstallPath, true, certWatchPtr, *this));
617db029c95SKowalski, Kamil         }
618db029c95SKowalski, Kamil         catch (const InternalFailure& e)
619db029c95SKowalski, Kamil         {
620db029c95SKowalski, Kamil             report<InternalFailure>();
621db029c95SKowalski, Kamil         }
622db029c95SKowalski, Kamil         catch (const InvalidCertificate& e)
623db029c95SKowalski, Kamil         {
624db029c95SKowalski, Kamil             report<InvalidCertificate>(
625db029c95SKowalski, Kamil                 Reason("Existing certificate file is corrupted"));
626db029c95SKowalski, Kamil         }
627db029c95SKowalski, Kamil     }
628db029c95SKowalski, Kamil }
629c6e58c7eSRamesh Iyyar 
630c6e58c7eSRamesh Iyyar void Manager::createRSAPrivateKeyFile()
631c6e58c7eSRamesh Iyyar {
632c6e58c7eSRamesh Iyyar     fs::path rsaPrivateKeyFileName =
633c6e58c7eSRamesh Iyyar         certParentInstallPath / RSA_PRIV_KEY_FILE_NAME;
634c6e58c7eSRamesh Iyyar 
635c6e58c7eSRamesh Iyyar     try
636c6e58c7eSRamesh Iyyar     {
637c6e58c7eSRamesh Iyyar         if (!fs::exists(rsaPrivateKeyFileName))
638c6e58c7eSRamesh Iyyar         {
639c6e58c7eSRamesh Iyyar             writePrivateKey(generateRSAKeyPair(SUPPORTED_KEYBITLENGTH),
640c6e58c7eSRamesh Iyyar                             RSA_PRIV_KEY_FILE_NAME);
641c6e58c7eSRamesh Iyyar         }
642c6e58c7eSRamesh Iyyar     }
643c6e58c7eSRamesh Iyyar     catch (const InternalFailure& e)
644c6e58c7eSRamesh Iyyar     {
645c6e58c7eSRamesh Iyyar         report<InternalFailure>();
646c6e58c7eSRamesh Iyyar     }
647c6e58c7eSRamesh Iyyar }
648c6e58c7eSRamesh Iyyar 
649c6e58c7eSRamesh Iyyar EVP_PKEY_Ptr Manager::getRSAKeyPair(const int64_t keyBitLength)
650c6e58c7eSRamesh Iyyar {
651c6e58c7eSRamesh Iyyar     if (keyBitLength != SUPPORTED_KEYBITLENGTH)
652c6e58c7eSRamesh Iyyar     {
653c6e58c7eSRamesh Iyyar         log<level::ERR>(
654c6e58c7eSRamesh Iyyar             "Given Key bit length is not supported",
655c6e58c7eSRamesh Iyyar             entry("GIVENKEYBITLENGTH=%d", keyBitLength),
656c6e58c7eSRamesh Iyyar             entry("SUPPORTEDKEYBITLENGTH=%d", SUPPORTED_KEYBITLENGTH));
657c6e58c7eSRamesh Iyyar         elog<InvalidArgument>(
658c6e58c7eSRamesh Iyyar             Argument::ARGUMENT_NAME("KEYBITLENGTH"),
659c6e58c7eSRamesh Iyyar             Argument::ARGUMENT_VALUE(std::to_string(keyBitLength).c_str()));
660c6e58c7eSRamesh Iyyar     }
661c6e58c7eSRamesh Iyyar     fs::path rsaPrivateKeyFileName =
662c6e58c7eSRamesh Iyyar         certParentInstallPath / RSA_PRIV_KEY_FILE_NAME;
663c6e58c7eSRamesh Iyyar 
664c6e58c7eSRamesh Iyyar     FILE* privateKeyFile = std::fopen(rsaPrivateKeyFileName.c_str(), "r");
665c6e58c7eSRamesh Iyyar     if (!privateKeyFile)
666c6e58c7eSRamesh Iyyar     {
667c6e58c7eSRamesh Iyyar         log<level::ERR>("Unable to open RSA private key file to read",
668c6e58c7eSRamesh Iyyar                         entry("RSAKEYFILE=%s", rsaPrivateKeyFileName.c_str()),
669c6e58c7eSRamesh Iyyar                         entry("ERRORREASON=%s", strerror(errno)));
670c6e58c7eSRamesh Iyyar         elog<InternalFailure>();
671c6e58c7eSRamesh Iyyar     }
672c6e58c7eSRamesh Iyyar 
673c6e58c7eSRamesh Iyyar     EVP_PKEY_Ptr privateKey(
674c6e58c7eSRamesh Iyyar         PEM_read_PrivateKey(privateKeyFile, nullptr, nullptr, nullptr),
675c6e58c7eSRamesh Iyyar         ::EVP_PKEY_free);
676c6e58c7eSRamesh Iyyar     std::fclose(privateKeyFile);
677c6e58c7eSRamesh Iyyar 
678c6e58c7eSRamesh Iyyar     if (!privateKey)
679c6e58c7eSRamesh Iyyar     {
680c6e58c7eSRamesh Iyyar         log<level::ERR>("Error occured during PEM_read_PrivateKey call");
681c6e58c7eSRamesh Iyyar         elog<InternalFailure>();
682c6e58c7eSRamesh Iyyar     }
683c6e58c7eSRamesh Iyyar     return privateKey;
684c6e58c7eSRamesh Iyyar }
685cfbc8dc8SJayanth Othayoth } // namespace certs
686cfbc8dc8SJayanth Othayoth } // namespace phosphor
687