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/watch.hpp b/watch.hpp
new file mode 100644
index 0000000..bf16742
--- /dev/null
+++ b/watch.hpp
@@ -0,0 +1,72 @@
+#pragma once
+#include "watch.hpp"
+
+#include <memory>
+#include <sdeventplus/source/event.hpp>
+#include <sdeventplus/source/io.hpp>
+namespace phosphor
+{
+namespace certs
+{
+/** @class Watch
+ *
+ *  @brief Adds inotify watch on certificate directory
+ *
+ *  The inotify watch is hooked up with sd-event, so that on call back,
+ *  appropriate actions related to a certificate upload can be taken.
+ */
+class Watch
+{
+  public:
+    using Callback = std::function<void()>;
+    /** @brief ctor - hook inotify watch with sd-event
+     *
+     *  @param[in] loop - sd-event object
+     *  @param[in] cb - The callback function for processing
+     *                             certificate upload
+     */
+    Watch(sdeventplus::Event& event, std::string& certFile, Callback cb);
+    Watch(const Watch&) = delete;
+    Watch& operator=(const Watch&) = delete;
+    Watch(Watch&&) = delete;
+    Watch& operator=(Watch&&) = delete;
+
+    /** @brief dtor - remove inotify watch and close fd's
+     */
+    ~Watch();
+
+    /** @brief start watch on the specified path
+     */
+    void startWatch();
+
+    /** @brief stop watch on the specified path
+     */
+    void stopWatch();
+
+  private:
+    /** @brief certificate upload directory watch descriptor */
+    int wd = -1;
+
+    /** @brief inotify file descriptor */
+    int fd = -1;
+
+    /** @brief SDEventPlus IO pointer added to event loop */
+    std::unique_ptr<sdeventplus::source::IO> ioPtr = nullptr;
+
+    /** @brief sd-event object */
+    sdeventplus::Event& event;
+
+    /** @brief callback method to be called */
+    Callback callback;
+
+    /** @brief Certificate directory to watch */
+    std::string watchDir;
+
+    /** @brief Certificate file to watch */
+    std::string watchFile;
+
+    /** @brief Certificate file with path */
+    std::string certFile;
+};
+} // namespace certs
+} // namespace phosphor