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::bus& bus, const char* path, std::string&& installPath,
35          const Status& status) :
36     internal::CSRInterface(bus, path, true),
37     objectPath(path), certInstallPath(std::move(installPath)), csrStatus(status)
38 {
39     // Emit deferred signal.
40     this->emit_object_added();
41 }
42 
43 std::string CSR::csr()
44 {
45     if (csrStatus == Status::FAILURE)
46     {
47         log<level::ERR>("Failure in Generating CSR");
48         elog<InternalFailure>();
49     }
50     fs::path csrFilePath = certInstallPath;
51     csrFilePath = csrFilePath.parent_path() / defaultCSRFileName;
52     if (!fs::exists(csrFilePath))
53     {
54         log<level::ERR>("CSR file doesn't exists",
55                         entry("FILENAME=%s", csrFilePath.c_str()));
56         elog<InternalFailure>();
57     }
58 
59     FILE* fp = std::fopen(csrFilePath.c_str(), "r");
60     X509ReqPtr x509Req(PEM_read_X509_REQ(fp, nullptr, nullptr, nullptr),
61                        ::X509_REQ_free);
62     if (x509Req == nullptr || fp == nullptr)
63     {
64         if (fp != nullptr)
65         {
66             std::fclose(fp);
67         }
68         log<level::ERR>("ERROR occurred while reading CSR file",
69                         entry("FILENAME=%s", csrFilePath.c_str()));
70         elog<InternalFailure>();
71     }
72     std::fclose(fp);
73 
74     BIOPtr bio(BIO_new(BIO_s_mem()), ::BIO_free_all);
75     int ret = PEM_write_bio_X509_REQ(bio.get(), x509Req.get());
76     if (ret <= 0)
77     {
78         log<level::ERR>("Error occurred while calling PEM_write_bio_X509_REQ");
79         elog<InternalFailure>();
80     }
81 
82     BUF_MEM* mem = nullptr;
83     BIO_get_mem_ptr(bio.get(), &mem);
84     std::string pem(mem->data, mem->length);
85     return pem;
86 }
87 
88 } // namespace phosphor::certs
89