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.

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

mercurial