Bug 617111 - Avoid initializing NSS at all costs (ts regression)

r=dietrich
This commit is contained in:
Shawn Wilsher 2010-12-07 09:27:40 -08:00
parent 2ed7d826a8
commit 7431929447
3 changed files with 60 additions and 25 deletions

View File

@ -38,8 +38,8 @@
#include "Helpers.h"
#include "mozIStorageError.h"
#include "nsIRandomGenerator.h"
#include "plbase64.h"
#include "prio.h"
#include "nsString.h"
#include "nsNavHistory.h"
@ -256,6 +256,45 @@ Base64urlEncode(const PRUint8* aBytes,
return NS_OK;
}
#ifdef XP_WIN
// Included here because windows.h conflicts with the use of mozIStorageError
// above.
#include <windows.h>
#include <Wincrypt.h>
#endif
static
nsresult
GenerateRandomBytes(PRUint32 aSize,
PRUint8* _buffer)
{
// On Windows, we'll use its built-in cryptographic API.
#if defined(XP_WIN)
HCRYPTPROV cryptoProvider;
BOOL rc = CryptAcquireContext(&cryptoProvider, 0, 0, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
if (rc) {
rc = CryptGenRandom(cryptoProvider, aSize, _buffer);
}
(void)CryptReleaseContext(cryptoProvider, 0);
return rc ? NS_OK : NS_ERROR_FAILURE;
// On Unix, we'll just read in from /dev/urandom.
#elif defined(XP_UNIX)
NS_ENSURE_ARG_MAX(aSize, PR_INT32_MAX);
PRFileDesc* urandom = PR_Open("/dev/urandom", PR_RDONLY, 0);
nsresult rv = NS_ERROR_FAILURE;
if (urandom) {
PRInt32 bytesRead = PR_Read(urandom, _buffer, aSize);
if (bytesRead == static_cast<PRInt32>(aSize)) {
rv = NS_OK;
}
(void)PR_Close(urandom);
}
return rv;
#endif
}
nsresult
GenerateGUID(nsCString& _guid)
{
@ -266,16 +305,11 @@ GenerateGUID(nsCString& _guid)
const PRUint32 kRequiredBytesLength =
static_cast<PRUint32>(GUID_LENGTH / 4 * 3);
nsCOMPtr<nsIRandomGenerator> rg =
do_GetService("@mozilla.org/security/random-generator;1");
NS_ENSURE_STATE(rg);
PRUint8* buffer;
nsresult rv = rg->GenerateRandomBytes(kRequiredBytesLength, &buffer);
PRUint8 buffer[kRequiredBytesLength];
nsresult rv = GenerateRandomBytes(kRequiredBytesLength, buffer);
NS_ENSURE_SUCCESS(rv, rv);
rv = Base64urlEncode(buffer, kRequiredBytesLength, _guid);
NS_Free(buffer);
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(_guid.Length() == GUID_LENGTH, "GUID is not the right size!");

View File

@ -48,7 +48,6 @@
#include "nsINavHistoryService.h"
#include "nsPrintfCString.h"
#include "nsNavHistory.h"
#include "nsIRandomGenerator.h"
using namespace mozilla::storage;
@ -597,13 +596,6 @@ namespace places {
nsresult
GenerateGUIDFunction::create(mozIStorageConnection *aDBConn)
{
// We need this service to be initialized on the main thread because it is
// not threadsafe. We are about to use it asynchronously, so initialize it
// now.
nsCOMPtr<nsIRandomGenerator> rg =
do_GetService("@mozilla.org/security/random-generator;1");
NS_ENSURE_STATE(rg);
nsCOMPtr<GenerateGUIDFunction> function = new GenerateGUIDFunction();
nsresult rv = aDBConn->CreateFunction(
NS_LITERAL_CSTRING("generate_guid"), 0, function

View File

@ -29,22 +29,29 @@ function test_guid_invariants()
const kAllowedChars =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
do_check_eq(kAllowedChars.length, kExpectedChars);
let checkedChars = {};
for (let i = 0; i < kAllowedChars; i++) {
checkedChars[kAllowedChars[i]] = false;
const kGuidLength = 12;
let checkedChars = [];
for (let i = 0; i < kGuidLength; i++) {
checkedChars[i] = {};
for (let j = 0; j < kAllowedChars; j++) {
checkedChars[i][kAllowedChars[j]] = false;
}
}
// We run this until we've seen every character that we expect to see.
// We run this until we've seen every character that we expect to see in every
// position.
let seenChars = 0;
let stmt = DBConn().createStatement("SELECT GENERATE_GUID()");
while (seenChars != kExpectedChars) {
while (seenChars != (kExpectedChars * kGuidLength)) {
do_check_true(stmt.executeStep());
let guid = stmt.getString(0);
check_invariants(guid);
for (let i = 0; i < guid.length; i++) {
if (!checkedChars[guid[i]]) {
checkedChars[guid[i]] = true;
let character = guid[i];
if (!checkedChars[i][character]) {
checkedChars[i][character] = true;
seenChars++;
}
}
@ -53,8 +60,10 @@ function test_guid_invariants()
stmt.finalize();
// One last reality check - make sure all of our characters were seen.
for (let i = 0; i < kAllowedChars; i++) {
do_check_true(checkedChars[kAllowedChars[i]]);
for (let i = 0; i < kGuidLength; i++) {
for (let j = 0; j < kAllowedChars; j++) {
do_check_true(checkedChars[i][kAllowedChars[j]]);
}
}
run_next_test();