Use CPRNG for session secrets generation

std::random_device is not a cryptographically secure
algorithm. Switch to RAND_bytes instead.

Tested: Login and logout works as expected

Change-Id: If24fa6c3a0652c011bc50ae611b180f342d68433
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/include/sessions.hpp b/include/sessions.hpp
index 8ff903a..c2fcf31 100644
--- a/include/sessions.hpp
+++ b/include/sessions.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include <openssl/rand.h>
+
 #include <boost/container/flat_map.hpp>
 #include <boost/uuid/uuid.hpp>
 #include <boost/uuid/uuid_generators.hpp>
@@ -147,6 +149,45 @@
 
 class Middleware;
 
+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:
@@ -166,23 +207,38 @@
         std::string sessionToken;
         sessionToken.resize(sessionTokenSize, '0');
         std::uniform_int_distribution<size_t> dist(0, alphanum.size() - 1);
+
+        OpenSSLGenerator gen;
+
         for (size_t i = 0; i < sessionToken.size(); ++i)
         {
-            sessionToken[i] = alphanum[dist(rd)];
+            sessionToken[i] = alphanum[dist(gen)];
+            if (gen.error())
+            {
+                return nullptr;
+            }
         }
         // Only need csrf tokens for cookie based auth, token doesn't matter
         std::string csrfToken;
         csrfToken.resize(sessionTokenSize, '0');
         for (size_t i = 0; i < csrfToken.size(); ++i)
         {
-            csrfToken[i] = alphanum[dist(rd)];
+            csrfToken[i] = alphanum[dist(gen)];
+            if (gen.error())
+            {
+                return nullptr;
+            }
         }
 
         std::string uniqueId;
         uniqueId.resize(10, '0');
         for (size_t i = 0; i < uniqueId.size(); ++i)
         {
-            uniqueId[i] = alphanum[dist(rd)];
+            uniqueId[i] = alphanum[dist(gen)];
+            if (gen.error())
+            {
+                return nullptr;
+            }
         }
 
         auto session = std::make_shared<UserSession>(UserSession{
@@ -324,7 +380,6 @@
                        std::hash<std::string>,
                        crow::utility::ConstantTimeCompare>
         authTokens;
-    std::random_device rd;
     bool needWrite{false};
     std::chrono::minutes timeoutInMinutes;
     AuthConfigMethods authMethodsConfig;