Manage certificates created by applications
Added watch on certificate path to watch on certificates
created/updated by apps.
As part of watch notification, create new D-Bus new certificate
and for existing D-Bus object update the properties.
Tested:
Test case 1
1) Ensure no certificate is present
2) Restart certificate service
3) Restart bmcweb service
4) Verified that certificate object is created for the
self-signed certificate created by bmcweb.
Test case 2
1) After a certificate is present
2) Modify the bmcweb certificate by replacing it
with a valid certificate manually.
3) Verified that certificate manager is notified
and certificate objects properties are updated.
Test case 3
1) Upload CSR based certificate file
2) Verified that private key is appended to the file
Test case 4
1) Create a dummy file in certificate folder
2) Verified that notification is received and file is ignored
Test case 5
1) Verified install, replace, generate csr.
Change-Id: I7d1e3624958e4b68e5ba7bc6150c19b11fca501a
Signed-off-by: Marri Devender Rao <devenrao@in.ibm.com>
diff --git a/certs_manager.cpp b/certs_manager.cpp
index 38f77c2..b189bb9 100644
--- a/certs_manager.cpp
+++ b/certs_manager.cpp
@@ -12,6 +12,9 @@
{
using InternalFailure =
sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+using InvalidCertificate =
+ sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate;
+using Reason = xyz::openbmc_project::Certs::InvalidCertificate::REASON;
using X509_REQ_Ptr = std::unique_ptr<X509_REQ, decltype(&::X509_REQ_free)>;
using BIGNUM_Ptr = std::unique_ptr<BIGNUM, decltype(&::BN_free)>;
@@ -21,33 +24,45 @@
UnitsToRestart&& unit, CertInstallPath&& installPath) :
Ifaces(bus, path),
bus(bus), event(event), objectPath(path), certType(type),
- unitToRestart(std::move(unit)), certInstallPath(std::move(installPath)),
- childPtr(nullptr)
+ unitToRestart(std::move(unit)), certInstallPath(std::move(installPath))
{
- using InvalidCertificate =
- sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate;
- using Reason = xyz::openbmc_project::Certs::InvalidCertificate::REASON;
+ // restore any existing certificates
if (fs::exists(certInstallPath))
{
- try
- {
- // TODO: Issue#3 At present supporting only one certificate to be
- // uploaded this need to be revisited to support multiple
- // certificates
- auto certObjectPath = objectPath + '/' + '1';
- certificatePtr = std::make_unique<Certificate>(
- bus, certObjectPath, certType, unitToRestart, certInstallPath,
- certInstallPath, true);
- }
- catch (const InternalFailure& e)
- {
- report<InternalFailure>();
- }
- catch (const InvalidCertificate& e)
- {
- report<InvalidCertificate>(
- Reason("Existing certificate file is corrupted"));
- }
+ createCertificate();
+ }
+
+ // watch is not required for authority certificates
+ if (certType != AUTHORITY)
+ {
+ // watch for certificate file create/replace
+ certWatchPtr = std::make_unique<
+ Watch>(event, certInstallPath, [this]() {
+ try
+ {
+ // if certificate file existing update it
+ if (certificatePtr != nullptr)
+ {
+ log<level::INFO>(
+ "Inotify callback to update certificate properties");
+ certificatePtr->populateProperties();
+ }
+ else
+ {
+ log<level::INFO>(
+ "Inotify callback to create certificate object");
+ createCertificate();
+ }
+ }
+ catch (const InternalFailure& e)
+ {
+ commit<InternalFailure>();
+ }
+ catch (const InvalidCertificate& e)
+ {
+ commit<InvalidCertificate>();
+ }
+ });
}
}
@@ -63,10 +78,11 @@
{
elog<NotAllowed>(Reason("Certificate already exist"));
}
+
auto certObjectPath = objectPath + '/' + '1';
certificatePtr = std::make_unique<Certificate>(
bus, certObjectPath, certType, unitToRestart, certInstallPath, filePath,
- false);
+ false, certWatchPtr);
}
void Manager::delete_()
@@ -170,6 +186,11 @@
return csrObjectPath;
}
+CertificatePtr& Manager::getCertificate()
+{
+ return certificatePtr;
+}
+
void Manager::generateCSRHelper(
std::vector<std::string> alternativeNames, std::string challengePassword,
std::string city, std::string commonName, std::string contactPerson,
@@ -460,5 +481,27 @@
std::fclose(fp);
}
+void Manager::createCertificate()
+{
+ try
+ {
+ // TODO: Issue#3 At present supporting only one certificate to be
+ // uploaded this need to be revisited to support multiple
+ // certificates
+ auto certObjectPath = objectPath + '/' + '1';
+ certificatePtr = std::make_unique<Certificate>(
+ bus, certObjectPath, certType, unitToRestart, certInstallPath,
+ certInstallPath, true, certWatchPtr);
+ }
+ catch (const InternalFailure& e)
+ {
+ report<InternalFailure>();
+ }
+ catch (const InvalidCertificate& e)
+ {
+ report<InvalidCertificate>(
+ Reason("Existing certificate file is corrupted"));
+ }
+}
} // namespace certs
} // namespace phosphor