toolkit/mozapps/update/common/pathhash.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 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include <windows.h>
     6 #include <wincrypt.h>
     7 #include "pathhash.h"
    10 /**
    11  * Converts a binary sequence into a hex string
    12  *
    13  * @param hash      The binary data sequence
    14  * @param hashSize  The size of the binary data sequence
    15  * @param hexString A buffer to store the hex string, must be of 
    16  *                  size 2 * @hashSize
    17 */
    18 static void
    19 BinaryDataToHexString(const BYTE *hash, DWORD &hashSize, 
    20                       LPWSTR hexString)
    21 {
    22   WCHAR *p = hexString;
    23   for (DWORD i = 0; i < hashSize; ++i) {
    24     wsprintfW(p, L"%.2x", hash[i]);
    25     p += 2;
    26   }
    27 }
    29 /**
    30  * Calculates an MD5 hash for the given input binary data
    31  *
    32  * @param  data     Any sequence of bytes
    33  * @param  dataSize The number of bytes inside @data
    34  * @param  hash     Output buffer to store hash, must be freed by the caller
    35  * @param  hashSize The number of bytes in the output buffer
    36  * @return TRUE on success
    37 */
    38 static BOOL
    39 CalculateMD5(const char *data, DWORD dataSize, 
    40              BYTE **hash, DWORD &hashSize)
    41 {
    42   HCRYPTPROV hProv = 0;
    43   HCRYPTHASH hHash = 0;
    45   if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL,
    46                            CRYPT_VERIFYCONTEXT)) {
    47     if (NTE_BAD_KEYSET != GetLastError()) {
    48       return FALSE;
    49     }
    51     // Maybe it doesn't exist, try to create it.
    52     if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL, 
    53                              CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET)) {
    54       return FALSE;
    55     }
    56   }
    58   if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
    59     return FALSE;
    60   }
    62   if (!CryptHashData(hHash, reinterpret_cast<const BYTE*>(data), 
    63                     dataSize, 0)) {
    64     return FALSE;
    65   }
    67   DWORD dwCount = sizeof(DWORD);
    68   if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashSize, 
    69                         &dwCount, 0)) {
    70     return FALSE;
    71   }
    73   *hash = new BYTE[hashSize];
    74   ZeroMemory(*hash, hashSize);
    75   if (!CryptGetHashParam(hHash, HP_HASHVAL, *hash, &hashSize, 0)) {
    76     return FALSE;
    77   }
    79   if (hHash) {
    80     CryptDestroyHash(hHash);
    81   }
    83   if (hProv) {
    84     CryptReleaseContext(hProv,0);
    85   }
    87   return TRUE;
    88 }
    90 /**
    91  * Converts a file path into a unique registry location for cert storage
    92  *
    93  * @param  filePath     The input file path to get a registry path from
    94  * @param  registryPath A buffer to write the registry path to, must 
    95  *                      be of size in WCHARs MAX_PATH + 1
    96  * @return TRUE if successful
    97 */
    98 BOOL
    99 CalculateRegistryPathFromFilePath(const LPCWSTR filePath, 
   100                                   LPWSTR registryPath)
   101 {
   102   size_t filePathLen = wcslen(filePath); 
   103   if (!filePathLen) {
   104     return FALSE;
   105   }
   107   // If the file path ends in a slash, ignore that character
   108   if (filePath[filePathLen -1] == L'\\' || 
   109       filePath[filePathLen - 1] == L'/') {
   110     filePathLen--;
   111   }
   113   // Copy in the full path into our own buffer.
   114   // Copying in the extra slash is OK because we calculate the hash
   115   // based on the filePathLen which excludes the slash.
   116   // +2 to account for the possibly trailing slash and the null terminator.
   117   WCHAR *lowercasePath = new WCHAR[filePathLen + 2];
   118   memset(lowercasePath, 0, (filePathLen + 2) * sizeof(WCHAR));
   119   wcsncpy(lowercasePath, filePath, filePathLen + 1);
   120   _wcslwr(lowercasePath);
   122   BYTE *hash;
   123   DWORD hashSize = 0;
   124   if (!CalculateMD5(reinterpret_cast<const char*>(lowercasePath), 
   125                     filePathLen * 2, 
   126                     &hash, hashSize)) {
   127     delete[] lowercasePath;
   128     return FALSE;
   129   }
   130   delete[] lowercasePath;
   132   LPCWSTR baseRegPath = L"SOFTWARE\\Mozilla\\"
   133     L"MaintenanceService\\";
   134   wcsncpy(registryPath, baseRegPath, MAX_PATH);
   135   BinaryDataToHexString(hash, hashSize, 
   136                         registryPath + wcslen(baseRegPath));
   137   delete[] hash;
   138   return TRUE;
   139 }

mercurial