xref: /openbmc/phosphor-certificate-manager/certs_manager.cpp (revision 589159f27e6ea73ffe82d53cde50b6d5a7eb23d3)
1cfbc8dc8SJayanth Othayoth #include "certs_manager.hpp"
2cfbc8dc8SJayanth Othayoth 
3dd74bd20SJayanth Othayoth #include <openssl/bio.h>
4dd74bd20SJayanth Othayoth #include <openssl/crypto.h>
5dd74bd20SJayanth Othayoth #include <openssl/err.h>
6dd74bd20SJayanth Othayoth #include <openssl/evp.h>
7dd74bd20SJayanth Othayoth #include <openssl/pem.h>
8dd74bd20SJayanth Othayoth #include <openssl/x509v3.h>
9dd74bd20SJayanth Othayoth 
10cfbc8dc8SJayanth Othayoth #include <experimental/filesystem>
11cfbc8dc8SJayanth Othayoth #include <phosphor-logging/elog-errors.hpp>
12cfbc8dc8SJayanth Othayoth #include <phosphor-logging/elog.hpp>
13cfbc8dc8SJayanth Othayoth #include <phosphor-logging/log.hpp>
14cfbc8dc8SJayanth Othayoth #include <sdbusplus/bus.hpp>
15dd74bd20SJayanth Othayoth #include <xyz/openbmc_project/Certs/Install/error.hpp>
16cfbc8dc8SJayanth Othayoth #include <xyz/openbmc_project/Common/error.hpp>
17cfbc8dc8SJayanth Othayoth 
18cfbc8dc8SJayanth Othayoth namespace phosphor
19cfbc8dc8SJayanth Othayoth {
20cfbc8dc8SJayanth Othayoth namespace certs
21cfbc8dc8SJayanth Othayoth {
22dd74bd20SJayanth Othayoth // RAII support for openSSL functions.
23dd74bd20SJayanth Othayoth using BIO_MEM_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
24dd74bd20SJayanth Othayoth using X509_STORE_CTX_Ptr =
25dd74bd20SJayanth Othayoth     std::unique_ptr<X509_STORE_CTX, decltype(&::X509_STORE_CTX_free)>;
26dd74bd20SJayanth Othayoth using X509_LOOKUP_Ptr =
27dd74bd20SJayanth Othayoth     std::unique_ptr<X509_LOOKUP, decltype(&::X509_LOOKUP_free)>;
28*589159f2SJayanth Othayoth using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
29cfbc8dc8SJayanth Othayoth 
30dd74bd20SJayanth Othayoth namespace fs = std::experimental::filesystem;
31cfbc8dc8SJayanth Othayoth using namespace phosphor::logging;
32cfbc8dc8SJayanth Othayoth using InternalFailure =
33cfbc8dc8SJayanth Othayoth     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
34dd74bd20SJayanth Othayoth using InvalidCertificate =
35dd74bd20SJayanth Othayoth     sdbusplus::xyz::openbmc_project::Certs::Install::Error::InvalidCertificate;
36dd74bd20SJayanth Othayoth using Reason = xyz::openbmc_project::Certs::Install::InvalidCertificate::REASON;
37cfbc8dc8SJayanth Othayoth 
38cfbc8dc8SJayanth Othayoth void Manager::install(const std::string path)
39cfbc8dc8SJayanth Othayoth {
40dd74bd20SJayanth Othayoth     // Verify the certificate file
41dd74bd20SJayanth Othayoth     auto rc = verifyCert(path);
42dd74bd20SJayanth Othayoth     if (rc != X509_V_OK)
43dd74bd20SJayanth Othayoth     {
44dd74bd20SJayanth Othayoth         if (rc == X509_V_ERR_CERT_HAS_EXPIRED)
45dd74bd20SJayanth Othayoth         {
46dd74bd20SJayanth Othayoth             elog<InvalidCertificate>(Reason("Expired Certificate"));
47dd74bd20SJayanth Othayoth         }
48dd74bd20SJayanth Othayoth         // Loging general error here.
49dd74bd20SJayanth Othayoth         elog<InvalidCertificate>(Reason("Certificate validation failed"));
50dd74bd20SJayanth Othayoth     }
51*589159f2SJayanth Othayoth 
52*589159f2SJayanth Othayoth     // Compare the Keys
53*589159f2SJayanth Othayoth     if (!compareKeys(path))
54*589159f2SJayanth Othayoth     {
55*589159f2SJayanth Othayoth         elog<InvalidCertificate>(
56*589159f2SJayanth Othayoth             Reason("Private key is not matching with Certificate"));
57*589159f2SJayanth Othayoth     }
58*589159f2SJayanth Othayoth 
59cfbc8dc8SJayanth Othayoth     // Copy the certificate file
60cfbc8dc8SJayanth Othayoth     copy(path, certPath);
61cfbc8dc8SJayanth Othayoth 
62cfbc8dc8SJayanth Othayoth     // Invoke type specific install function.
63cfbc8dc8SJayanth Othayoth     auto iter = typeFuncMap.find(type);
64cfbc8dc8SJayanth Othayoth     if (iter == typeFuncMap.end())
65cfbc8dc8SJayanth Othayoth     {
66cfbc8dc8SJayanth Othayoth         log<level::ERR>("Unsupported Type", entry("TYPE=%s", type.c_str()));
67cfbc8dc8SJayanth Othayoth         elog<InternalFailure>();
68cfbc8dc8SJayanth Othayoth     }
69cfbc8dc8SJayanth Othayoth     iter->second();
70cfbc8dc8SJayanth Othayoth }
71cfbc8dc8SJayanth Othayoth 
72cfbc8dc8SJayanth Othayoth void Manager::serverInstall()
73cfbc8dc8SJayanth Othayoth {
74cfbc8dc8SJayanth Othayoth     if (!unit.empty())
75cfbc8dc8SJayanth Othayoth     {
76cfbc8dc8SJayanth Othayoth         reload(unit);
77cfbc8dc8SJayanth Othayoth     }
78cfbc8dc8SJayanth Othayoth }
79cfbc8dc8SJayanth Othayoth 
80cfbc8dc8SJayanth Othayoth void Manager::clientInstall()
81cfbc8dc8SJayanth Othayoth {
82cfbc8dc8SJayanth Othayoth     // Do nothing now
83cfbc8dc8SJayanth Othayoth }
84cfbc8dc8SJayanth Othayoth 
85cfbc8dc8SJayanth Othayoth void Manager::reload(const std::string& unit)
86cfbc8dc8SJayanth Othayoth {
87cfbc8dc8SJayanth Othayoth     constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
88cfbc8dc8SJayanth Othayoth     constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
89cfbc8dc8SJayanth Othayoth     constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
90cfbc8dc8SJayanth Othayoth 
91cfbc8dc8SJayanth Othayoth     try
92cfbc8dc8SJayanth Othayoth     {
93cfbc8dc8SJayanth Othayoth         auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
94cfbc8dc8SJayanth Othayoth                                           SYSTEMD_INTERFACE, "ReloadUnit");
95cfbc8dc8SJayanth Othayoth 
96cfbc8dc8SJayanth Othayoth         method.append(unit, "replace");
97cfbc8dc8SJayanth Othayoth 
98cfbc8dc8SJayanth Othayoth         bus.call_noreply(method);
99cfbc8dc8SJayanth Othayoth     }
100cfbc8dc8SJayanth Othayoth     catch (const sdbusplus::exception::SdBusError& e)
101cfbc8dc8SJayanth Othayoth     {
102cfbc8dc8SJayanth Othayoth         log<level::ERR>("Failed to reload service", entry("ERR=%s", e.what()),
103cfbc8dc8SJayanth Othayoth                         entry("UNIT=%s", unit.c_str()));
104cfbc8dc8SJayanth Othayoth         elog<InternalFailure>();
105cfbc8dc8SJayanth Othayoth     }
106cfbc8dc8SJayanth Othayoth }
107cfbc8dc8SJayanth Othayoth 
108cfbc8dc8SJayanth Othayoth void Manager::copy(const std::string& src, const std::string& dst)
109cfbc8dc8SJayanth Othayoth {
110cfbc8dc8SJayanth Othayoth     namespace fs = std::experimental::filesystem;
111cfbc8dc8SJayanth Othayoth 
112cfbc8dc8SJayanth Othayoth     try
113cfbc8dc8SJayanth Othayoth     {
114cfbc8dc8SJayanth Othayoth         auto path = fs::path(dst).parent_path();
115cfbc8dc8SJayanth Othayoth         // create dst path folder by default
116cfbc8dc8SJayanth Othayoth         fs::create_directories(path);
117cfbc8dc8SJayanth Othayoth         fs::copy_file(src, dst, fs::copy_options::overwrite_existing);
118cfbc8dc8SJayanth Othayoth     }
119cfbc8dc8SJayanth Othayoth     catch (fs::filesystem_error& e)
120cfbc8dc8SJayanth Othayoth     {
121cfbc8dc8SJayanth Othayoth         log<level::ERR>("Failed to copy certificate", entry("ERR=%s", e.what()),
122cfbc8dc8SJayanth Othayoth                         entry("SRC=%s", src.c_str()),
123cfbc8dc8SJayanth Othayoth                         entry("DST=%s", dst.c_str()));
124cfbc8dc8SJayanth Othayoth         elog<InternalFailure>();
125cfbc8dc8SJayanth Othayoth     }
126cfbc8dc8SJayanth Othayoth }
127cfbc8dc8SJayanth Othayoth 
128dd74bd20SJayanth Othayoth X509_Ptr Manager::loadCert(const std::string& filePath)
129dd74bd20SJayanth Othayoth {
130dd74bd20SJayanth Othayoth     // Read Certificate file
131dd74bd20SJayanth Othayoth     X509_Ptr cert(X509_new(), ::X509_free);
132dd74bd20SJayanth Othayoth     if (!cert)
133dd74bd20SJayanth Othayoth     {
134dd74bd20SJayanth Othayoth         log<level::ERR>("Error occured during X509_new call",
135dd74bd20SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()),
136dd74bd20SJayanth Othayoth                         entry("ERRCODE=%lu", ERR_get_error()));
137dd74bd20SJayanth Othayoth         elog<InternalFailure>();
138dd74bd20SJayanth Othayoth     }
139dd74bd20SJayanth Othayoth 
140dd74bd20SJayanth Othayoth     BIO_MEM_Ptr bioCert(BIO_new_file(filePath.c_str(), "rb"), ::BIO_free);
141dd74bd20SJayanth Othayoth     if (!bioCert)
142dd74bd20SJayanth Othayoth     {
143dd74bd20SJayanth Othayoth         log<level::ERR>("Error occured during BIO_new_file call",
144dd74bd20SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()));
145dd74bd20SJayanth Othayoth         elog<InternalFailure>();
146dd74bd20SJayanth Othayoth     }
147dd74bd20SJayanth Othayoth 
148dd74bd20SJayanth Othayoth     X509* x509 = cert.get();
149dd74bd20SJayanth Othayoth     if (!PEM_read_bio_X509(bioCert.get(), &x509, nullptr, nullptr))
150dd74bd20SJayanth Othayoth     {
151dd74bd20SJayanth Othayoth         log<level::ERR>("Error occured during PEM_read_bio_X509 call",
152dd74bd20SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()));
153dd74bd20SJayanth Othayoth         elog<InternalFailure>();
154dd74bd20SJayanth Othayoth     }
155dd74bd20SJayanth Othayoth     return cert;
156dd74bd20SJayanth Othayoth }
157dd74bd20SJayanth Othayoth 
158dd74bd20SJayanth Othayoth int32_t Manager::verifyCert(const std::string& filePath)
159dd74bd20SJayanth Othayoth {
160dd74bd20SJayanth Othayoth     auto errCode = X509_V_OK;
161dd74bd20SJayanth Othayoth 
162dd74bd20SJayanth Othayoth     fs::path file(filePath);
163dd74bd20SJayanth Othayoth     if (!fs::exists(file))
164dd74bd20SJayanth Othayoth     {
165dd74bd20SJayanth Othayoth         log<level::ERR>("File is Missing", entry("FILE=%s", filePath.c_str()));
166dd74bd20SJayanth Othayoth         elog<InternalFailure>();
167dd74bd20SJayanth Othayoth     }
168dd74bd20SJayanth Othayoth 
169dd74bd20SJayanth Othayoth     try
170dd74bd20SJayanth Othayoth     {
171dd74bd20SJayanth Othayoth         if (fs::file_size(filePath) == 0)
172dd74bd20SJayanth Othayoth         {
173dd74bd20SJayanth Othayoth             // file is empty
174dd74bd20SJayanth Othayoth             log<level::ERR>("File is empty",
175dd74bd20SJayanth Othayoth                             entry("FILE=%s", filePath.c_str()));
176dd74bd20SJayanth Othayoth             elog<InvalidCertificate>(Reason("File is empty"));
177dd74bd20SJayanth Othayoth         }
178dd74bd20SJayanth Othayoth     }
179dd74bd20SJayanth Othayoth     catch (const fs::filesystem_error& e)
180dd74bd20SJayanth Othayoth     {
181dd74bd20SJayanth Othayoth         // Log Error message
182dd74bd20SJayanth Othayoth         log<level::ERR>(e.what(), entry("FILE=%s", filePath.c_str()));
183dd74bd20SJayanth Othayoth         elog<InternalFailure>();
184dd74bd20SJayanth Othayoth     }
185dd74bd20SJayanth Othayoth 
186dd74bd20SJayanth Othayoth     // Defining store object as RAW to avoid double free.
187dd74bd20SJayanth Othayoth     // X509_LOOKUP_free free up store object.
188dd74bd20SJayanth Othayoth     // Create an empty X509_STORE structure for certificate validation.
189dd74bd20SJayanth Othayoth     auto x509Store = X509_STORE_new();
190dd74bd20SJayanth Othayoth     if (!x509Store)
191dd74bd20SJayanth Othayoth     {
192dd74bd20SJayanth Othayoth         log<level::ERR>("Error occured during X509_STORE_new call");
193dd74bd20SJayanth Othayoth         elog<InternalFailure>();
194dd74bd20SJayanth Othayoth     }
195dd74bd20SJayanth Othayoth 
196dd74bd20SJayanth Othayoth     OpenSSL_add_all_algorithms();
197dd74bd20SJayanth Othayoth 
198dd74bd20SJayanth Othayoth     // ADD Certificate Lookup method.
199dd74bd20SJayanth Othayoth     X509_LOOKUP_Ptr lookup(X509_STORE_add_lookup(x509Store, X509_LOOKUP_file()),
200dd74bd20SJayanth Othayoth                            ::X509_LOOKUP_free);
201dd74bd20SJayanth Othayoth     if (!lookup)
202dd74bd20SJayanth Othayoth     {
203dd74bd20SJayanth Othayoth         // Normally lookup cleanup function interanlly does X509Store cleanup
204dd74bd20SJayanth Othayoth         // Free up the X509Store.
205dd74bd20SJayanth Othayoth         X509_STORE_free(x509Store);
206dd74bd20SJayanth Othayoth         log<level::ERR>("Error occured during X509_STORE_add_lookup call");
207dd74bd20SJayanth Othayoth         elog<InternalFailure>();
208dd74bd20SJayanth Othayoth     }
209dd74bd20SJayanth Othayoth     // Load Certificate file.
210dd74bd20SJayanth Othayoth     int32_t rc = X509_LOOKUP_load_file(lookup.get(), filePath.c_str(),
211dd74bd20SJayanth Othayoth                                        X509_FILETYPE_PEM);
212dd74bd20SJayanth Othayoth     if (rc != 1)
213dd74bd20SJayanth Othayoth     {
214dd74bd20SJayanth Othayoth         log<level::ERR>("Error occured during X509_LOOKUP_load_file call",
215dd74bd20SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()));
216dd74bd20SJayanth Othayoth         elog<InvalidCertificate>(Reason("Invalid certificate file format"));
217dd74bd20SJayanth Othayoth     }
218dd74bd20SJayanth Othayoth 
219dd74bd20SJayanth Othayoth     // Load Certificate file into the X509 structre.
220dd74bd20SJayanth Othayoth     X509_Ptr cert = std::move(loadCert(filePath));
221dd74bd20SJayanth Othayoth     X509_STORE_CTX_Ptr storeCtx(X509_STORE_CTX_new(), ::X509_STORE_CTX_free);
222dd74bd20SJayanth Othayoth     if (!storeCtx)
223dd74bd20SJayanth Othayoth     {
224dd74bd20SJayanth Othayoth         log<level::ERR>("Error occured during X509_STORE_CTX_new call",
225dd74bd20SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()));
226dd74bd20SJayanth Othayoth         elog<InternalFailure>();
227dd74bd20SJayanth Othayoth     }
228dd74bd20SJayanth Othayoth 
229dd74bd20SJayanth Othayoth     rc = X509_STORE_CTX_init(storeCtx.get(), x509Store, cert.get(), NULL);
230dd74bd20SJayanth Othayoth     if (rc != 1)
231dd74bd20SJayanth Othayoth     {
232dd74bd20SJayanth Othayoth         log<level::ERR>("Error occured during X509_STORE_CTX_init call",
233dd74bd20SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()));
234dd74bd20SJayanth Othayoth         elog<InternalFailure>();
235dd74bd20SJayanth Othayoth     }
236dd74bd20SJayanth Othayoth 
237dd74bd20SJayanth Othayoth     // Set time to current time.
238dd74bd20SJayanth Othayoth     auto locTime = time(nullptr);
239dd74bd20SJayanth Othayoth 
240dd74bd20SJayanth Othayoth     X509_STORE_CTX_set_time(storeCtx.get(), X509_V_FLAG_USE_CHECK_TIME,
241dd74bd20SJayanth Othayoth                             locTime);
242dd74bd20SJayanth Othayoth 
243dd74bd20SJayanth Othayoth     rc = X509_verify_cert(storeCtx.get());
244dd74bd20SJayanth Othayoth     if (rc == 1)
245dd74bd20SJayanth Othayoth     {
246dd74bd20SJayanth Othayoth         errCode = X509_V_OK;
247dd74bd20SJayanth Othayoth     }
248dd74bd20SJayanth Othayoth     else if (rc == 0)
249dd74bd20SJayanth Othayoth     {
250dd74bd20SJayanth Othayoth         errCode = X509_STORE_CTX_get_error(storeCtx.get());
251dd74bd20SJayanth Othayoth         log<level::ERR>("Certificate verification failed",
252dd74bd20SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()),
253dd74bd20SJayanth Othayoth                         entry("ERRCODE=%d", errCode));
254dd74bd20SJayanth Othayoth     }
255dd74bd20SJayanth Othayoth     else
256dd74bd20SJayanth Othayoth     {
257dd74bd20SJayanth Othayoth         log<level::ERR>("Error occured during X509_verify_cert call",
258dd74bd20SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()));
259dd74bd20SJayanth Othayoth         elog<InternalFailure>();
260dd74bd20SJayanth Othayoth     }
261dd74bd20SJayanth Othayoth     return errCode;
262dd74bd20SJayanth Othayoth }
263dd74bd20SJayanth Othayoth 
264*589159f2SJayanth Othayoth bool Manager::compareKeys(const std::string& filePath)
265*589159f2SJayanth Othayoth {
266*589159f2SJayanth Othayoth     X509_Ptr cert(X509_new(), ::X509_free);
267*589159f2SJayanth Othayoth     if (!cert)
268*589159f2SJayanth Othayoth     {
269*589159f2SJayanth Othayoth         log<level::ERR>("Error occured during X509_new call",
270*589159f2SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()),
271*589159f2SJayanth Othayoth                         entry("ERRCODE=%lu", ERR_get_error()));
272*589159f2SJayanth Othayoth         elog<InternalFailure>();
273*589159f2SJayanth Othayoth     }
274*589159f2SJayanth Othayoth 
275*589159f2SJayanth Othayoth     BIO_MEM_Ptr bioCert(BIO_new_file(filePath.c_str(), "rb"), ::BIO_free);
276*589159f2SJayanth Othayoth     if (!bioCert)
277*589159f2SJayanth Othayoth     {
278*589159f2SJayanth Othayoth         log<level::ERR>("Error occured during BIO_new_file call",
279*589159f2SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()));
280*589159f2SJayanth Othayoth         elog<InternalFailure>();
281*589159f2SJayanth Othayoth     }
282*589159f2SJayanth Othayoth 
283*589159f2SJayanth Othayoth     X509* x509 = cert.get();
284*589159f2SJayanth Othayoth     PEM_read_bio_X509(bioCert.get(), &x509, nullptr, nullptr);
285*589159f2SJayanth Othayoth 
286*589159f2SJayanth Othayoth     EVP_PKEY_Ptr pubKey(X509_get_pubkey(cert.get()), ::EVP_PKEY_free);
287*589159f2SJayanth Othayoth     if (!pubKey)
288*589159f2SJayanth Othayoth     {
289*589159f2SJayanth Othayoth         log<level::ERR>("Error occurred during X509_get_pubkey",
290*589159f2SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()),
291*589159f2SJayanth Othayoth                         entry("ERRCODE=%lu", ERR_get_error()));
292*589159f2SJayanth Othayoth         elog<InvalidCertificate>(Reason("Failed to get public key info"));
293*589159f2SJayanth Othayoth     }
294*589159f2SJayanth Othayoth 
295*589159f2SJayanth Othayoth     BIO_MEM_Ptr keyBio(BIO_new(BIO_s_file()), ::BIO_free);
296*589159f2SJayanth Othayoth     if (!keyBio)
297*589159f2SJayanth Othayoth     {
298*589159f2SJayanth Othayoth         log<level::ERR>("Error occured during BIO_s_file call",
299*589159f2SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()));
300*589159f2SJayanth Othayoth         elog<InternalFailure>();
301*589159f2SJayanth Othayoth     }
302*589159f2SJayanth Othayoth     BIO_read_filename(keyBio.get(), filePath.c_str());
303*589159f2SJayanth Othayoth 
304*589159f2SJayanth Othayoth     EVP_PKEY_Ptr priKey(
305*589159f2SJayanth Othayoth         PEM_read_bio_PrivateKey(keyBio.get(), nullptr, nullptr, nullptr),
306*589159f2SJayanth Othayoth         ::EVP_PKEY_free);
307*589159f2SJayanth Othayoth 
308*589159f2SJayanth Othayoth     if (!priKey)
309*589159f2SJayanth Othayoth     {
310*589159f2SJayanth Othayoth         log<level::ERR>("Error occurred during PEM_read_bio_PrivateKey",
311*589159f2SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()),
312*589159f2SJayanth Othayoth                         entry("ERRCODE=%lu", ERR_get_error()));
313*589159f2SJayanth Othayoth         elog<InvalidCertificate>(Reason("Failed to get private key info"));
314*589159f2SJayanth Othayoth     }
315*589159f2SJayanth Othayoth 
316*589159f2SJayanth Othayoth     int32_t rc = EVP_PKEY_cmp(priKey.get(), pubKey.get());
317*589159f2SJayanth Othayoth     if (rc != 1)
318*589159f2SJayanth Othayoth     {
319*589159f2SJayanth Othayoth         log<level::ERR>("Private key is not matching with Certificate",
320*589159f2SJayanth Othayoth                         entry("FILE=%s", filePath.c_str()),
321*589159f2SJayanth Othayoth                         entry("ERRCODE=%d", rc));
322*589159f2SJayanth Othayoth         return false;
323*589159f2SJayanth Othayoth     }
324*589159f2SJayanth Othayoth 
325*589159f2SJayanth Othayoth     return true;
326*589159f2SJayanth Othayoth }
327cfbc8dc8SJayanth Othayoth } // namespace certs
328cfbc8dc8SJayanth Othayoth } // namespace phosphor
329