bug 660613 - websockets fix where platform has < 32bits of RAND_MAX r=biesi

--HG--
extra : rebase_source : 276be91e1eb90b5101536cc95e41d9b4e892f0e1
This commit is contained in:
Patrick McManus 2011-06-02 20:48:06 -04:00
parent 3199602600
commit 0afb802199
2 changed files with 26 additions and 18 deletions

View File

@ -102,18 +102,6 @@ static PRLogModuleInfo *webSocketLog = nsnull;
// An implementation of draft-ietf-hybi-thewebsocketprotocol-07
#define SEC_WEBSOCKET_VERSION "7"
/*
* About using rand() without a srand() or initstate()
*
* rand() is commonly called throughout the codebase with the assumption
* that it has been seeded securely. That does indeed happen in
* the initialization of the nsUUIDGenerator sevice - getting secure
* seed information from PR_GetRandomNoise() and giving that to
* initstate(). We won't repeat that here "just in case" because
* it is easy to drain some systems of their true random sources.
*/
/*
* About SSL unsigned certificates
*
@ -1162,7 +1150,18 @@ nsWebSocketHandler::PrimeNewOutgoingMessage()
// Perfom the sending mask. never use a zero mask
PRUint32 mask;
while (!(mask = (PRUint32) rand()));
do {
PRUint8 *buffer;
nsresult rv = mRandomGenerator->GenerateRandomBytes(4, &buffer);
if (NS_FAILED(rv)) {
LOG(("WebSocketHandler:: PrimeNewOutgoingMessage() "
"GenerateRandomBytes failure %x\n", rv));
StopSession(rv);
return;
}
mask = * reinterpret_cast<PRUint32 *>(buffer);
NS_Free(buffer);
} while (!mask);
*(((PRUint32 *)payload) - 1) = PR_htonl(mask);
LOG(("WebSocketHandler:: PrimeNewOutgoingMessage() "
@ -1475,13 +1474,13 @@ nsWebSocketHandler::SetupRequest()
NS_LITERAL_CSTRING("Sec-WebSocket-Extensions"),
NS_LITERAL_CSTRING("deflate-stream"), PR_FALSE);
PRUint32 secKey[4];
PRUint8 *secKey;
nsCAutoString secKeyString;
secKey[0] = (PRUint32) rand();
secKey[1] = (PRUint32) rand();
secKey[2] = (PRUint32) rand();
secKey[3] = (PRUint32) rand();
rv = mRandomGenerator->GenerateRandomBytes(16, &secKey);
NS_ENSURE_SUCCESS(rv, rv);
char* b64 = PL_Base64Encode((const char *)secKey, 16, nsnull);
NS_Free(secKey);
if (!b64) return NS_ERROR_OUT_OF_MEMORY;
secKeyString.Assign(b64);
PR_Free(b64);
@ -1851,6 +1850,13 @@ nsWebSocketHandler::AsyncOpen(nsIURI *aURI,
return rv;
}
mRandomGenerator = do_GetService("@mozilla.org/security/random-generator;1",
&rv);
if (NS_FAILED(rv)) {
NS_WARNING("unable to continue without random number generator");
return rv;
}
nsCOMPtr<nsIPrefBranch> prefService;
prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);

View File

@ -56,6 +56,7 @@
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsIStringStream.h"
#include "nsIHttpChannelInternal.h"
#include "nsIRandomGenerator.h"
#include "nsCOMPtr.h"
#include "nsString.h"
@ -196,6 +197,7 @@ private:
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsICancelable> mDNSRequest;
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
nsCOMPtr<nsIRandomGenerator> mRandomGenerator;
nsCString mProtocol;
nsCString mOrigin;