Refactoring of certificates managing and storing

This commit is about third stage code refactoring proposed by Zbigniew
Kurzynski (zbigniew.kurzynski@intel.com) on the mailing list
("phosphor-certificate-manager refactoring"): "Changing the way of
managing and storing TrustStore certificates".

Following changes are being implemented:
 - each certificate has its own and unique ID,
 - authority certificates are kept in files with random names under
/etc/ssl/certs/authority and symlinks (based on subject name hash) are
created to satisfy OpenSSL library,
 - restarting bmcweb was moved from certificate class to certs_manager
class
 - certificate uniqueness is based on certificate ID and checked while
installing and replacing operation in certs_manager class.

Tested by doing installing/replacing/removing operations on certificate
storage using RedFish API.

Signed-off-by: Zbigniew Lukwinski <zbigniew.lukwinski@linux.intel.com>
Change-Id: I0b02a10b940279c46ad9ee07925794262133b1b0
diff --git a/certificate.hpp b/certificate.hpp
index 9fa2cdd..feffecc 100644
--- a/certificate.hpp
+++ b/certificate.hpp
@@ -22,7 +22,6 @@
                                                      ReplaceIface, DeleteIface>;
 
 using CertificateType = std::string;
-using UnitsToRestart = std::string;
 using CertInstallPath = std::string;
 using CertUploadPath = std::string;
 using InputType = std::string;
@@ -67,17 +66,21 @@
      *  @param[in] bus - Bus to attach to.
      *  @param[in] objPath - Object path to attach to
      *  @param[in] type - Type of the certificate
-     *  @param[in] unit - Units to restart after a certificate is installed
      *  @param[in] installPath - Path of the certificate to install
      *  @param[in] uploadPath - Path of the certificate file to upload
-     *  @param[in] isSkipUnitReload - If true do not restart units
      *  @param[in] watchPtr - watch on self signed certificate pointer
      */
     Certificate(sdbusplus::bus::bus& bus, const std::string& objPath,
-                const CertificateType& type, const UnitsToRestart& unit,
-                const CertInstallPath& installPath,
-                const CertUploadPath& uploadPath, bool isSkipUnitReload,
-                const CertWatchPtr& watchPtr, Manager& parent);
+                const CertificateType& type, const CertInstallPath& installPath,
+                const CertUploadPath& uploadPath, const CertWatchPtr& watchPtr,
+                Manager& parent);
+
+    /** @brief Validate and Replace/Install the certificate file
+     *  Install/Replace the existing certificate file with another
+     *  (possibly CA signed) Certificate file.
+     *  @param[in] filePath - Certificate file path.
+     */
+    void install(const std::string& filePath);
 
     /** @brief Validate certificate and replace the existing certificate
      *  @param[in] filePath - Certificate file path.
@@ -85,16 +88,30 @@
     void replace(const std::string filePath) override;
 
     /** @brief Populate certificate properties by parsing certificate file
-     *  @return void
      */
     void populateProperties();
 
     /**
-     * @brief Obtain certificate's subject hash
+     * @brief Obtain certificate ID.
      *
-     * @return certificate's subject hash
+     * @return Certificate ID.
      */
-    const std::string& getHash() const;
+    std::string getCertId() const;
+
+    /**
+     * @brief Check if provied certificate is the same as the current one.
+     *
+     * @param[in] certPath - File path for certificate to check.
+     *
+     * @return Checking result. Return true if certificates are the same,
+     *         false if not.
+     */
+    bool isSame(const std::string& certPath);
+
+    /**
+     * @brief Update certificate storage.
+     */
+    void storageUpdate();
 
     /**
      * @brief Delete the certificate
@@ -111,15 +128,7 @@
      */
     void populateProperties(const std::string& certPath);
 
-    /** @brief Validate and Replace/Install the certificate file
-     *  Install/Replace the existing certificate file with another
-     *  (possibly CA signed) Certificate file.
-     *  @param[in] filePath - Certificate file path.
-     *  @param[in] isSkipUnitReload - If true do not restart units
-     */
-    void install(const std::string& filePath, bool isSkipUnitReload);
-
-    /** @brief Load Certificate file into the X509 structre.
+    /** @brief Load Certificate file into the X509 structure.
      *  @param[in] filePath - Certificate and key full file path.
      *  @return pointer to the X509 structure.
      */
@@ -142,23 +151,67 @@
      */
     bool compareKeys(const std::string& filePath);
 
-    /** @brief systemd unit reload or reset helper function
-     *  Reload if the unit supports it and use a restart otherwise.
-     *  @param[in] unit - service need to reload.
+    /**
+     * @brief Generate certificate ID based on provided certificate file.
+     *
+     * @param[in] certPath - Certificate file path.
+     *
+     * @return Certificate ID as formatted string.
      */
-    void reloadOrReset(const UnitsToRestart& unit);
+    std::string generateCertId(const std::string& certPath);
 
     /**
-     * @brief Extracts subject hash
+     * @brief Generate file name which is unique in the provided directory.
      *
-     * @param[in] storeCtx   Pointer to X509_STORE_CTX containing certificate
+     * @param[in] directoryPath - Directory path.
      *
-     * @return Subject hash as formatted string
+     * @return File path.
      */
-    static inline std::string
-        getSubjectHash(const X509_STORE_CTX_Ptr& storeCtx);
+    std::string generateUniqueFilePath(const std::string& directoryPath);
 
-    /** @brief Type specific function pointer map **/
+    /**
+     * @brief Generate authority certificate file path corresponding with
+     * OpenSSL requirements.
+     *
+     * Prepare authority certificate file path for provied certificate.
+     * OpenSSL puts some restrictions on the certificate file name pattern.
+     * Certificate full file name needs to consists of basic file name which
+     * is certificate subject name hash and file name extension which is an
+     * integer. More over, certificates files names extensions must be
+     * consecutive integer numbers in case many certificates with the same
+     * subject name.
+     * https://www.boost.org/doc/libs/1_69_0/doc/html/boost_asio/reference/ssl__context/add_verify_path.html
+     * https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_load_verify_locations.html
+     *
+     * @param[in] certSrcFilePath - Certificate source file path.
+     * @param[in] certDstDirPath - Certificate destination directory path.
+     *
+     * @return Authority certificate file path.
+     */
+    std::string generateAuthCertFileX509Path(const std::string& certSrcFilePath,
+                                             const std::string& certDstDirPath);
+
+    /**
+     * @brief Generate authority certificate file path based on provided
+     * certificate source file path.
+     *
+     * @param[in] certSrcFilePath - Certificate source file path.
+     *
+     * @return Authority certificate file path.
+     */
+    std::string generateAuthCertFilePath(const std::string& certSrcFilePath);
+
+    /**
+     * @brief Generate certificate file path based on provided certificate
+     * source file path.
+     *
+     * @param[in] certSrcFilePath - Certificate source file path.
+     *
+     * @return Certificate file path.
+     */
+    std::string generateCertFilePath(const std::string& certSrcFilePath);
+
+    /** @brief Type specific function pointer map */
     std::unordered_map<InputType, InstallFunc> typeFuncMap;
 
     /** @brief sdbusplus handler */
@@ -167,13 +220,16 @@
     /** @brief object path */
     std::string objectPath;
 
-    /** @brief Type of the certificate **/
+    /** @brief Type of the certificate */
     CertificateType certType;
 
-    /** @brief Unit name associated to the service **/
-    UnitsToRestart unitToRestart;
+    /** @brief Stores certificate ID */
+    std::string certId;
 
-    /** @brief Certificate file installation path **/
+    /** @brief Stores certificate file path */
+    std::string certFilePath;
+
+    /** @brief Certificate file installation path */
     CertInstallPath certInstallPath;
 
     /** @brief Type specific function pointer map for appending private key */
@@ -182,9 +238,6 @@
     /** @brief Certificate file create/update watch */
     const CertWatchPtr& certWatchPtr;
 
-    /** @brief Stores certificate subject hash */
-    std::string certHash;
-
     /** @brief Reference to Certificate Manager */
     Manager& manager;
 };