toolkit/components/downloads/SQLFunctions.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "mozilla/storage.h"
     7 #include "mozilla/storage/Variant.h"
     8 #include "mozilla/mozalloc.h"
     9 #include "nsString.h"
    10 #include "SQLFunctions.h"
    11 #include "nsUTF8Utils.h"
    12 #include "plbase64.h"
    13 #include "prio.h"
    15 // The length of guids that are used by the download manager
    16 #define GUID_LENGTH 12
    18 namespace mozilla {
    19 namespace downloads {
    21 // Keep this file in sync with the GUID-related code in toolkit/places/SQLFunctions.cpp
    22 // and toolkit/places/Helpers.cpp!
    24 ////////////////////////////////////////////////////////////////////////////////
    25 //// GUID Creation Function
    27 //////////////////////////////////////////////////////////////////////////////
    28 //// GenerateGUIDFunction
    30 /* static */
    31 nsresult
    32 GenerateGUIDFunction::create(mozIStorageConnection *aDBConn)
    33 {
    34   nsRefPtr<GenerateGUIDFunction> function = new GenerateGUIDFunction();
    35   nsresult rv = aDBConn->CreateFunction(
    36     NS_LITERAL_CSTRING("generate_guid"), 0, function
    37   );
    38   NS_ENSURE_SUCCESS(rv, rv);
    40   return NS_OK;
    41 }
    43 NS_IMPL_ISUPPORTS(
    44     GenerateGUIDFunction,
    45     mozIStorageFunction
    46 )
    48 static
    49 nsresult
    50 Base64urlEncode(const uint8_t* aBytes,
    51                 uint32_t aNumBytes,
    52                 nsCString& _result)
    53 {
    54   // SetLength does not set aside space for null termination.  PL_Base64Encode
    55   // will not null terminate, however, nsCStrings must be null terminated.  As a
    56   // result, we set the capacity to be one greater than what we need, and the
    57   // length to our desired length.
    58   uint32_t length = (aNumBytes + 2) / 3 * 4; // +2 due to integer math.
    59   NS_ENSURE_TRUE(_result.SetCapacity(length + 1, mozilla::fallible_t()),
    60                  NS_ERROR_OUT_OF_MEMORY);
    61   _result.SetLength(length);
    62   (void)PL_Base64Encode(reinterpret_cast<const char*>(aBytes), aNumBytes,
    63                         _result.BeginWriting());
    65   // base64url encoding is defined in RFC 4648.  It replaces the last two
    66   // alphabet characters of base64 encoding with '-' and '_' respectively.
    67   _result.ReplaceChar('+', '-');
    68   _result.ReplaceChar('/', '_');
    69   return NS_OK;
    70 }
    72 #ifdef XP_WIN
    73 // Included here because windows.h conflicts with the use of mozIStorageError
    74 // above.
    75 #include <windows.h>
    76 #include <wincrypt.h>
    77 #endif
    79 static
    80 nsresult
    81 GenerateRandomBytes(uint32_t aSize,
    82                     uint8_t* _buffer)
    83 {
    84   // On Windows, we'll use its built-in cryptographic API.
    85 #if defined(XP_WIN)
    86   HCRYPTPROV cryptoProvider;
    87   BOOL rc = CryptAcquireContext(&cryptoProvider, 0, 0, PROV_RSA_FULL,
    88                                 CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
    89   if (rc) {
    90     rc = CryptGenRandom(cryptoProvider, aSize, _buffer);
    91     (void)CryptReleaseContext(cryptoProvider, 0);
    92   }
    93   return rc ? NS_OK : NS_ERROR_FAILURE;
    95   // On Unix, we'll just read in from /dev/urandom.
    96 #elif defined(XP_UNIX)
    97   NS_ENSURE_ARG_MAX(aSize, INT32_MAX);
    98   PRFileDesc* urandom = PR_Open("/dev/urandom", PR_RDONLY, 0);
    99   nsresult rv = NS_ERROR_FAILURE;
   100   if (urandom) {
   101     int32_t bytesRead = PR_Read(urandom, _buffer, aSize);
   102     if (bytesRead == static_cast<int32_t>(aSize)) {
   103       rv = NS_OK;
   104     }
   105     (void)PR_Close(urandom);
   106   }
   107   return rv;
   108 #endif
   109 }
   111 nsresult
   112 GenerateGUID(nsCString& _guid)
   113 {
   114   _guid.Truncate();
   116   // Request raw random bytes and base64url encode them.  For each set of three
   117   // bytes, we get one character.
   118   const uint32_t kRequiredBytesLength =
   119     static_cast<uint32_t>(GUID_LENGTH / 4 * 3);
   121   uint8_t buffer[kRequiredBytesLength];
   122   nsresult rv = GenerateRandomBytes(kRequiredBytesLength, buffer);
   123   NS_ENSURE_SUCCESS(rv, rv);
   125   rv = Base64urlEncode(buffer, kRequiredBytesLength, _guid);
   126   NS_ENSURE_SUCCESS(rv, rv);
   128   NS_ASSERTION(_guid.Length() == GUID_LENGTH, "GUID is not the right size!");
   129   return NS_OK;
   130 }
   132 //////////////////////////////////////////////////////////////////////////////
   133 //// mozIStorageFunction
   135 NS_IMETHODIMP
   136 GenerateGUIDFunction::OnFunctionCall(mozIStorageValueArray *aArguments,
   137                                      nsIVariant **_result)
   138 {
   139   nsAutoCString guid;
   140   nsresult rv = GenerateGUID(guid);
   141   NS_ENSURE_SUCCESS(rv, rv);
   143   NS_ADDREF(*_result = new mozilla::storage::UTF8TextVariant(guid));
   144   return NS_OK;
   145 }
   147 } // namespace mozilla
   148 } // namespace downloads

mercurial