Move Openssl Generator

This commit moves the openssl random number generator into its own file,
so it can be used in EventService, and moves it to its own file.  Seeding a
random number generator with time is bad practice in general, so much so
that there's a CERT rule about it as well as a clang-tidy check.
https://clang.llvm.org/extra/clang-tidy/checks/cert-msc51-cpp.html

This doesn't matter much in this case, as we're generating a randomized
int for an ID, but it will matter in other cases, and we'd like to have
the check on to verify that.

Change-Id: I8e6aebb7962d259045ffd558eea22f07f9c23821
Signed-off-by: Ed Tanous <ed@tanous.net>
diff --git a/include/random.hpp b/include/random.hpp
new file mode 100644
index 0000000..d11c249
--- /dev/null
+++ b/include/random.hpp
@@ -0,0 +1,46 @@
+#pragma once
+
+#include <openssl/rand.h>
+
+namespace bmcweb
+{
+
+struct OpenSSLGenerator
+{
+    uint8_t operator()()
+    {
+        uint8_t index = 0;
+        int rc = RAND_bytes(&index, sizeof(index));
+        if (rc != opensslSuccess)
+        {
+            std::cerr << "Cannot get random number\n";
+            err = true;
+        }
+
+        return index;
+    }
+
+    uint8_t max()
+    {
+        return std::numeric_limits<uint8_t>::max();
+    }
+    uint8_t min()
+    {
+        return std::numeric_limits<uint8_t>::min();
+    }
+
+    bool error()
+    {
+        return err;
+    }
+
+    // all generators require this variable
+    using result_type = uint8_t;
+
+  private:
+    // RAND_bytes() returns 1 on success, 0 otherwise. -1 if bad function
+    static constexpr int opensslSuccess = 1;
+    bool err = false;
+};
+
+} // namespace bmcweb
diff --git a/include/sessions.hpp b/include/sessions.hpp
index 418f6f8..95459b3 100644
--- a/include/sessions.hpp
+++ b/include/sessions.hpp
@@ -3,6 +3,8 @@
 #include "logging.h"
 #include "utility.h"
 
+#include "random.hpp"
+
 #include <openssl/rand.h>
 
 #include <boost/container/flat_map.hpp>
@@ -168,44 +170,6 @@
     }
 };
 
-struct OpenSSLGenerator
-{
-    uint8_t operator()(void)
-    {
-        uint8_t index = 0;
-        int rc = RAND_bytes(&index, sizeof(index));
-        if (rc != opensslSuccess)
-        {
-            std::cerr << "Cannot get random number\n";
-            err = true;
-        }
-
-        return index;
-    }
-
-    uint8_t max()
-    {
-        return std::numeric_limits<uint8_t>::max();
-    }
-    uint8_t min()
-    {
-        return std::numeric_limits<uint8_t>::min();
-    }
-
-    bool error()
-    {
-        return err;
-    }
-
-    // all generators require this variable
-    using result_type = uint8_t;
-
-  private:
-    // RAND_bytes() returns 1 on success, 0 otherwise. -1 if bad function
-    static constexpr int opensslSuccess = 1;
-    bool err = false;
-};
-
 class SessionStore
 {
   public:
@@ -228,7 +192,7 @@
         sessionToken.resize(sessionTokenSize, '0');
         std::uniform_int_distribution<size_t> dist(0, alphanum.size() - 1);
 
-        OpenSSLGenerator gen;
+        bmcweb::OpenSSLGenerator gen;
 
         for (char& sessionChar : sessionToken)
         {
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index a6fe829..d29d9c6 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -25,6 +25,7 @@
 #include <boost/container/flat_map.hpp>
 #include <error_messages.hpp>
 #include <http_client.hpp>
+#include <random.hpp>
 #include <server_sent_events.hpp>
 #include <utils/json_utils.hpp>
 
@@ -926,13 +927,21 @@
     std::string addSubscription(const std::shared_ptr<Subscription> subValue,
                                 const bool updateFile = true)
     {
-        std::srand(static_cast<uint32_t>(std::time(nullptr)));
+
+        std::uniform_int_distribution<uint32_t> dist(0);
+        bmcweb::OpenSSLGenerator gen;
+
         std::string id;
 
         int retry = 3;
         while (retry)
         {
-            id = std::to_string(std::rand());
+            id = std::to_string(dist(gen));
+            if (gen.error())
+            {
+                retry = 0;
+                break;
+            }
             auto inserted = subscriptionsMap.insert(std::pair(id, subValue));
             if (inserted.second)
             {