1 #include "config.h"
2 
3 #include "csr.hpp"
4 
5 #include <openssl/pem.h>
6 
7 #include <filesystem>
8 #include <phosphor-logging/elog-errors.hpp>
9 #include <phosphor-logging/elog.hpp>
10 #include <xyz/openbmc_project/Certs/error.hpp>
11 #include <xyz/openbmc_project/Common/error.hpp>
12 
13 namespace phosphor
14 {
15 namespace certs
16 {
17 
18 using X509_REQ_Ptr = std::unique_ptr<X509_REQ, decltype(&::X509_REQ_free)>;
19 using BIO_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free_all)>;
20 using InternalFailure =
21     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
22 using namespace phosphor::logging;
23 namespace fs = std::filesystem;
24 
25 CSR::CSR(sdbusplus::bus::bus& bus, const char* path,
26          CertInstallPath&& installPath, const Status& status) :
27     CSRIface(bus, path, true),
28     bus(bus), objectPath(path), certInstallPath(std::move(installPath)),
29     csrStatus(status)
30 {
31     // Emit deferred signal.
32     this->emit_object_added();
33 }
34 
35 #ifdef SDBUSPP_NEW_CAMELCASE
36 std::string CSR::csr()
37 #else
38 std::string CSR::cSR()
39 #endif
40 {
41     if (csrStatus == Status::FAILURE)
42     {
43         log<level::ERR>("Failure in Generating CSR");
44         elog<InternalFailure>();
45     }
46     fs::path csrFilePath = certInstallPath;
47     csrFilePath = csrFilePath.parent_path() / CSR_FILE_NAME;
48     if (!fs::exists(csrFilePath))
49     {
50         log<level::ERR>("CSR file doesn't exists",
51                         entry("FILENAME=%s", csrFilePath.c_str()));
52         elog<InternalFailure>();
53     }
54 
55     FILE* fp = std::fopen(csrFilePath.c_str(), "r");
56     X509_REQ_Ptr x509Req(PEM_read_X509_REQ(fp, NULL, NULL, NULL),
57                          ::X509_REQ_free);
58     if (x509Req == NULL || fp == NULL)
59     {
60         if (fp != NULL)
61         {
62             std::fclose(fp);
63         }
64         log<level::ERR>("ERROR occured while reading CSR file",
65                         entry("FILENAME=%s", csrFilePath.c_str()));
66         elog<InternalFailure>();
67     }
68     std::fclose(fp);
69 
70     BIO_Ptr bio(BIO_new(BIO_s_mem()), ::BIO_free_all);
71     int ret = PEM_write_bio_X509_REQ(bio.get(), x509Req.get());
72     if (ret <= 0)
73     {
74         log<level::ERR>("Error occured while calling PEM_write_bio_X509_REQ");
75         elog<InternalFailure>();
76     }
77 
78     BUF_MEM* mem = NULL;
79     BIO_get_mem_ptr(bio.get(), &mem);
80     std::string pem(mem->data, mem->length);
81     return pem;
82 }
83 
84 } // namespace certs
85 } // namespace phosphor
86