From 191dd6e89fdca2108cfaf405e968a980ec6728ee Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
Date: Mon, 12 Jun 2017 16:12:30 -0700
Subject: [PATCH] Change the mask generator to use QRandomGenerator instead of
 qs?rand

This makes it secure, instead of insecure, and requires no seeding.

Task-number: QTBUG-61694
Change-Id: Ia53158e207a94bf49489fffd14c782bd4ec24946
Reviewed-by: Jesus Fernandez <Jesus.Fernandez@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
---
 src/websockets/qdefaultmaskgenerator_p.cpp | 18 +++++++++---------
 src/websockets/qmaskgenerator.cpp          |  2 +-
 src/websockets/qwebsocket.cpp              |  4 ++--
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/websockets/qdefaultmaskgenerator_p.cpp b/src/websockets/qdefaultmaskgenerator_p.cpp
index 1035e8fb..7dc0cee8 100644
--- a/src/websockets/qdefaultmaskgenerator_p.cpp
+++ b/src/websockets/qdefaultmaskgenerator_p.cpp
@@ -48,7 +48,7 @@
     malicious scripts to attack bad behaving proxies.
     For more information about the importance of good masking,
     see \l {"Talking to Yourself for Fun and Profit" by Lin-Shung Huang et al}.
-    The default mask generator uses the cryptographically insecure qrand() function.
+    The default mask generator uses the reasonably secure QRandomGenerator::get32() function.
     The best measure against attacks mentioned in the document above,
     is to use QWebSocket over a secure connection (\e wss://).
     In general, always be careful to not have 3rd party script access to
@@ -58,8 +58,7 @@
 */
 
 #include "qdefaultmaskgenerator_p.h"
-#include <QDateTime>
-#include <limits>
+#include <QRandomGenerator>
 
 QT_BEGIN_NAMESPACE
 
@@ -83,25 +82,26 @@ QDefaultMaskGenerator::~QDefaultMaskGenerator()
 }
 
 /*!
-    Seeds the QDefaultMaskGenerator using qsrand().
-    When seed() is not called, no seed is used at all.
-
     \internal
 */
 bool QDefaultMaskGenerator::seed() Q_DECL_NOEXCEPT
 {
-    qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch()));
     return true;
 }
 
 /*!
-    Generates a new random mask using the insecure qrand() method.
+    Generates a new random mask using the insecure QRandomGenerator::get32() method.
 
     \internal
 */
 quint32 QDefaultMaskGenerator::nextMask() Q_DECL_NOEXCEPT
 {
-    return quint32((double(qrand()) / RAND_MAX) * std::numeric_limits<quint32>::max());
+    quint32 value = QRandomGenerator::get32();
+    while (Q_UNLIKELY(value == 0)) {
+        // a mask of zero has a special meaning
+        value = QRandomGenerator::get32();
+    }
+    return value;
 }
 
 QT_END_NAMESPACE
diff --git a/src/websockets/qmaskgenerator.cpp b/src/websockets/qmaskgenerator.cpp
index 064ada2b..56d12237 100644
--- a/src/websockets/qmaskgenerator.cpp
+++ b/src/websockets/qmaskgenerator.cpp
@@ -50,7 +50,7 @@
     malicious scripts from attacking badly behaving proxies.
     For more information about the importance of good masking,
     see \l {"Talking to Yourself for Fun and Profit" by Lin-Shung Huang et al}.
-    By default QWebSocket uses the cryptographically insecure qrand() function.
+    By default QWebSocket uses the reasonably secure QRandomGenerator::get32() function.
     The best measure against attacks mentioned in the document above,
     is to use QWebSocket over a secure connection (\e wss://).
     In general, always be careful to not have 3rd party script access to
diff --git a/src/websockets/qwebsocket.cpp b/src/websockets/qwebsocket.cpp
index ba343e43..30bb39d7 100644
--- a/src/websockets/qwebsocket.cpp
+++ b/src/websockets/qwebsocket.cpp
@@ -63,8 +63,8 @@
     In that case, non-secure WebSocket connections fail. The best way to mitigate against
     this problem is to use WebSocket over a secure connection.
 
-    \warning To generate masks, this implementation of WebSockets uses the cryptographically
-    insecure qrand() function.
+    \warning To generate masks, this implementation of WebSockets uses the reasonably
+    secure QRandomGenerator::get32() function.
     For more information about the importance of good masking,
     see \l {"Talking to Yourself for Fun and Profit" by Lin-Shung Huang et al}.
     The best measure against attacks mentioned in the document above,
-- 
GitLab