Return Certificate Signing Request(CSR) contents
Add support to return the CSR data from the file created by
GenerateCSR request.
CSRRead class implements CSR interface. InternalFailure
exception is thrown to the caller if CSR file does not exist
or for any read errors.
Change-Id: I20ddeb9570962bf04917c1b0e3a52c8f34f5efcd
Signed-off-by: Marri Devender Rao <devenrao@in.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 82e370f..02cc10d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,8 @@
noinst_HEADERS = \
certs_manager.hpp \
argument.hpp \
- certificate.hpp
+ certificate.hpp \
+ csr.hpp
bin_PROGRAMS = \
phosphor-certificate-manager
@@ -13,7 +14,8 @@
mainapp.cpp \
certs_manager.cpp \
argument.cpp \
- certificate.cpp
+ certificate.cpp \
+ csr.cpp
phosphor_certificate_manager_LDFLAGS = \
$(SDBUSPLUS_LIBS) \
diff --git a/configure.ac b/configure.ac
index 2e7cbcf..5bf1a40 100644
--- a/configure.ac
+++ b/configure.ac
@@ -119,6 +119,10 @@
AS_IF([test "x$OBJPATH" == "x"], [OBJPATH="/xyz/openbmc_project/certs"])
AC_DEFINE_UNQUOTED([OBJPATH], ["$OBJPATH"], [The certificate manager D-Bus root])
+AC_ARG_VAR(CSR_FILE_NAME, [The CSR file.])
+AS_IF([test "x$CSR_FILE_NAME" == "x"], [CSR_FILE_NAME="domain.csr"])
+AC_DEFINE_UNQUOTED([CSR_FILE_NAME], ["$CSR_FILE_NAME"], [The CSR file])
+
# Create configured output
AC_CONFIG_FILES([Makefile test/Makefile])
AC_OUTPUT
diff --git a/csr.cpp b/csr.cpp
new file mode 100644
index 0000000..1850935
--- /dev/null
+++ b/csr.cpp
@@ -0,0 +1,81 @@
+#include "config.h"
+
+#include "csr.hpp"
+
+#include <openssl/pem.h>
+
+#include <filesystem>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <xyz/openbmc_project/Certs/error.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+namespace phosphor
+{
+namespace certs
+{
+
+using X509_REQ_Ptr = std::unique_ptr<X509_REQ, decltype(&::X509_REQ_free)>;
+using BIO_Ptr = std::unique_ptr<BIO, decltype(&::BIO_free_all)>;
+using InternalFailure =
+ sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+using namespace phosphor::logging;
+namespace fs = std::filesystem;
+
+CSR::CSR(sdbusplus::bus::bus& bus, const char* path,
+ CertInstallPath&& installPath, const Status& status) :
+ CSRIface(bus, path, true),
+ bus(bus), objectPath(path), certInstallPath(std::move(installPath)),
+ csrStatus(status)
+{
+ // Emit deferred signal.
+ this->emit_object_added();
+}
+
+std::string CSR::cSR()
+{
+ if (csrStatus == Status::FAILURE)
+ {
+ log<level::ERR>("Failure in Generating CSR");
+ elog<InternalFailure>();
+ }
+ fs::path csrFilePath = certInstallPath;
+ csrFilePath = csrFilePath.parent_path() / CSR_FILE_NAME;
+ if (!fs::exists(csrFilePath))
+ {
+ log<level::ERR>("CSR file doesn't exists",
+ entry("FILENAME=%s", csrFilePath.c_str()));
+ elog<InternalFailure>();
+ }
+
+ FILE* fp = std::fopen(csrFilePath.c_str(), "r");
+ X509_REQ_Ptr x509Req(PEM_read_X509_REQ(fp, NULL, NULL, NULL),
+ ::X509_REQ_free);
+ if (x509Req == NULL || fp == NULL)
+ {
+ if (fp != NULL)
+ {
+ std::fclose(fp);
+ }
+ log<level::ERR>("ERROR occured while reading CSR file",
+ entry("FILENAME=%s", csrFilePath.c_str()));
+ elog<InternalFailure>();
+ }
+ std::fclose(fp);
+
+ BIO_Ptr bio(BIO_new(BIO_s_mem()), ::BIO_free_all);
+ int ret = PEM_write_bio_X509_REQ(bio.get(), x509Req.get());
+ if (ret <= 0)
+ {
+ log<level::ERR>("Error occured while calling PEM_write_bio_X509_REQ");
+ elog<InternalFailure>();
+ }
+
+ BUF_MEM* mem = NULL;
+ BIO_get_mem_ptr(bio.get(), &mem);
+ std::string pem(mem->data, mem->length);
+ return pem;
+}
+
+} // namespace certs
+} // namespace phosphor
diff --git a/csr.hpp b/csr.hpp
new file mode 100644
index 0000000..728cfef
--- /dev/null
+++ b/csr.hpp
@@ -0,0 +1,58 @@
+#pragma once
+#include <xyz/openbmc_project/Certs/CSR/server.hpp>
+
+namespace phosphor
+{
+namespace certs
+{
+using CSRRead = sdbusplus::xyz::openbmc_project::Certs::server::CSR;
+using CSRIface = sdbusplus::server::object::object<CSRRead>;
+
+enum class Status
+{
+ SUCCESS,
+ FAILURE,
+};
+
+using CertInstallPath = std::string;
+
+/** @class CSR
+ * @brief To read CSR certificate
+ */
+class CSR : public CSRIface
+{
+ public:
+ CSR() = delete;
+ ~CSR() = default;
+ CSR(const CSR&) = delete;
+ CSR& operator=(const CSR&) = delete;
+ CSR(CSR&&) = default;
+ CSR& operator=(CSR&&) = default;
+
+ /** @brief Constructor to put object onto bus at a D-Bus path.
+ * @param[in] bus - Bus to attach to.
+ * @param[in] path - The D-Bus object path to attach at.
+ * @param[in] installPath - Certificate installation path.
+ * @param[in] status - Status of Generate CSR request
+ */
+ CSR(sdbusplus::bus::bus& bus, const char* path,
+ CertInstallPath&& installPath, const Status& status);
+ /** @brief Return CSR
+ */
+ std::string cSR() override;
+
+ private:
+ /** @brief sdbusplus handler */
+ sdbusplus::bus::bus& bus;
+
+ /** @brief object path */
+ std::string objectPath;
+
+ /** @brief Certificate file installation path **/
+ CertInstallPath certInstallPath;
+
+ /** @brief Status of GenerateCSR request */
+ Status csrStatus;
+};
+} // namespace certs
+} // namespace phosphor