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