Authorities list: implement InstallAll & ReplaceAll

This change implements the design in
https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/49317.

InstallAll: enumerate all certs in the input file and install all of
them;
ReplaceAll: replace all certs with the new authorities list
Atomic: implemented via creating temporary folder and issuing swap.

Added ability to unit test service reload as well.

Tested:
1. Unit tests
2. Tested loading/deleting authorities list in QEMU.

```
root@xxx:~# busctl call xyz.openbmc_project.Certs.Manager.Authority.Ldap \
> /xyz/openbmc_project/certs/authority/ldap \
> xyz.openbmc_project.Certs.InstallAll \
> InstallAll s /tmp/trust_bundle.pem
as 3 "/xyz/openbmc_project/certs/authority/ldap/1"
"/xyz/openbmc_project/certs/authority/ldap/2"
"/xyz/openbmc_project/certs/authority/ldap/3"
root@xxx:~# ls /etc/ssl/certs/authority/
10a5d8b0.0  5b49ceaa.0	f3ddaa86.0  file0qmgPV	fileDbjTzW  fileR4TtjO
trust_bundle
root@xxx:~# busctl call
xyz.openbmc_project.Certs.Manager.Authority.Ldap
/xyz/openbmc_project/certs/authority/ldap
xyz.openbmc_project.Certs.ReplaceAll ReplaceAll s /tmp/trust_bundle.pem
root@xxx:~# ls /etc/ssl/certs/authority/
10a5d8b0.0  5b49ceaa.0	f3ddaa86.0  file1obsEZ	fileOqVoaC  filerUBZCj
trust_bundle

root@xxx:~# wget -qO- http://localhost/redfish/v1/Managers/bmc/Truststore/Certificates/
{
  "@odata.id": "/redfish/v1/Managers/bmc/Truststore/Certificates/",
  "@odata.type": "#CertificateCollection.CertificateCollection",
  "Description": "A Collection of TrustStore certificate instances",
  "Members": [
    {
      "@odata.id": "/redfish/v1/Managers/bmc/Truststore/Certificates/1"
    },
    {
      "@odata.id": "/redfish/v1/Managers/bmc/Truststore/Certificates/2"
    },
    {
      "@odata.id": "/redfish/v1/Managers/bmc/Truststore/Certificates/3"
    }
  ],
  "Members@odata.count": 3,
  "Name": "TrustStore Certificates Collection"
}
root@xxx:~# wget -qO- http://localhost/redfish/v1/Managers/bmc/Truststore/Certificates/1
{
  "@odata.id": "/redfish/v1/Managers/bmc/Truststore/Certificates/1",
  "@odata.type": "#Certificate.v1_0_0.Certificate",
  "CertificateString": "-----BEGIN CERTIFICATE-----\nMIICZTCCAgugAwIBAgIUANIf0jvaRNq1MdwxrXPnk25VrmYwCgYIKoZIzj0EAwIw\nVTETMBEGA1UEChMKY2FtcHVzLWFzaDENMAsGA1UECxMEcm9vdDEvMC0GA1UEAwwm\ne2QyZWQ1MGJkLTczMTQtNDgxZC04OWE0LTVkMjkxMmYyMGQ5NH0wIBcNNzAwMTAx\nMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMFUxEzARBgNVBAoTCmNhbXB1cy1hc2gx\nDTALBgNVBAsTBHJvb3QxLzAtBgNVBAMMJntkMmVkNTBiZC03MzE0LTQ4MWQtODlh\nNC01ZDI5MTJmMjBkOTR9MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7lp/J3Gj\nc4TKubuYtzpxu2D3STlwTwEjgFbTaLZnQ0KXt7pBrcYc3yY1t74WBluvzM9iok6Q\nDcEFX5aIYcoaAKOBtjCBszAOBgNVHQ8BAf8EBAMCAQYwKQYDVR0lBCIwIAYIKwYB\nBQUHAwEGCCsGAQUFBwMCBgorBgEEAdZ5AgcBMA8GA1UdEwEB/wQFMAMBAf8wHQYD\nVR0OBBYEFIPrX7lbeJhvHHcQ7iYOry50aYKYMBcGA1UdIAQQMA4wDAYKKwYBBAHW\neQIFBDAtBgNVHR4BAf8EIzAhoB8wHYYbLmNhbXB1cy1hc2gucHJvZC5nb29nbGUu\nY29tMAoGCCqGSM49BAMCA0gAMEUCIAS/ZrMPBj992vVVplwzH9DWDCSMu1rCgvqw\nam3byOT1AiEAyrr3FAP+7js7z+h8d94hTyy1kTn+4NOvUWrVzHUmJI8=\n-----END CERTIFICATE-----\n",
  "Description": "TrustStore Certificate",
  "Id": "1",
  "Issuer": {
    "CommonName": "{d2ed50bd-7314-481d-89a4-5d2912f20d94}",
    "Organization": "campus-ash",
    "OrganizationalUnit": "root"
  },
  "KeyUsage": [
    "CRLSigning",
    "ServerAuthentication",
    "ClientAuthentication",
    ""
  ],
  "Name": "TrustStore Certificate",
  "Subject": {
    "CommonName": "{d2ed50bd-7314-481d-89a4-5d2912f20d94}",
    "Organization": "campus-ash",
    "OrganizationalUnit": "root"
  },
  "ValidNotAfter": "9999-12-31T23:59:59+00:00",
  "ValidNotBefore": "1970-01-01T00:00:00+00:00"
}
```

Signed-off-by: Nan Zhou <nanzhoumails@gmail.com>
Change-Id: I495f5c1c1c4a2ac880dd3233be31b84a78d79a43
diff --git a/certificate.hpp b/certificate.hpp
index fa3191a..4e90ea1 100644
--- a/certificate.hpp
+++ b/certificate.hpp
@@ -101,6 +101,25 @@
                 CertificateType type, const std::string& installPath,
                 const std::string& uploadPath, Watch* watch, Manager& parent);
 
+    /** @brief Constructor for the Certificate Object; a variant for authorities
+     * list install
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] objPath - Object path to attach to
+     *  @param[in] type - Type of the certificate
+     *  @param[in] installPath - Path of the certificate to install
+     *  @param[in] x509Store - an initialized X509 store used for certificate
+     * validation; Certificate object doesn't own it
+     *  @param[in] pem - Content of the certificate file to upload; it shall be
+     * a single PEM encoded x509 certificate
+     *  @param[in] watchPtr - watch on self signed certificate
+     *  @param[in] parent - Pointer to the manager which owns the constructed
+     * Certificate object
+     */
+    Certificate(sdbusplus::bus::bus& bus, const std::string& objPath,
+                const CertificateType& type, const std::string& installPath,
+                X509_STORE& x509Store, const std::string& pem, Watch* watchPtr,
+                Manager& parent);
+
     /** @brief Validate and Replace/Install the certificate file
      *  Install/Replace the existing certificate file with another
      *  (possibly CA signed) Certificate file.
@@ -108,6 +127,15 @@
      */
     void install(const std::string& filePath);
 
+    /** @brief Validate and Replace/Install the certificate file
+     *  Install/Replace the existing certificate file with another
+     *  (possibly CA signed) Certificate file.
+     *  @param[in] x509Store - an initialized X509 store used for certificate
+     * validation; Certificate object doesn't own it
+     *  @param[in] pem - a string buffer which stores a PEM encoded certificate.
+     */
+    void install(X509_STORE& x509Store, const std::string& pem);
+
     /** @brief Validate certificate and replace the existing certificate
      *  @param[in] filePath - Certificate file path.
      */
@@ -144,6 +172,44 @@
      */
     void delete_() override;
 
+    /**
+     * @brief Generate file name which is unique in the provided directory.
+     *
+     * @param[in] directoryPath - Directory path.
+     *
+     * @return File path.
+     */
+    static std::string generateUniqueFilePath(const std::string& directoryPath);
+
+    /**
+     * @brief Copies the certificate from sourceFilePath to installFilePath
+     *
+     * @param[in] sourceFilePath - Path to the source file.
+     * @param[in] certFilePath - Path to the destination file.
+     *
+     * @return void
+     */
+    static void copyCertificate(const std::string& certSrcFilePath,
+                                const std::string& certFilePath);
+
+    /**
+     * @brief Returns the associated dbus object path.
+     */
+    std::string getObjectPath();
+
+    /**
+     * @brief Returns the associated cert file path.
+     */
+    std::string getCertFilePath();
+
+    /** @brief: Set the data member |certFilePath| to |path|
+     */
+    void setCertFilePath(const std::string& path);
+
+    /** @brief: Set the data member |certInstallPath| to |path|
+     */
+    void setCertInstallPath(const std::string& path);
+
   private:
     /**
      * @brief Populate certificate properties by parsing given certificate
@@ -173,15 +239,6 @@
     bool compareKeys(const std::string& filePath);
 
     /**
-     * @brief Generate file name which is unique in the provided directory.
-     *
-     * @param[in] directoryPath - Directory path.
-     *
-     * @return File path.
-     */
-    std::string generateUniqueFilePath(const std::string& directoryPath);
-
-    /**
      * @brief Generate authority certificate file path corresponding with
      * OpenSSL requirements.
      *