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/. */
12 * Converts a binary sequence into a hex string
14 * @param hash The binary data sequence
15 * @param hashSize The size of the binary data sequence
16 * @param hexString A buffer to store the hex string, must be of
20 BinaryDataToHexString(const BYTE
*hash
, DWORD
&hashSize
,
24 for (DWORD i
= 0; i
< hashSize
; ++i
)
26 wsprintfW(p
, L
"%.2x", hash
[i
]);
32 * Calculates an MD5 hash for the given input binary data
34 * @param data Any sequence of bytes
35 * @param dataSize The number of bytes inside @data
36 * @param hash Output buffer to store hash, must be freed by the caller
37 * @param hashSize The number of bytes in the output buffer
38 * @return TRUE on success
41 CalculateMD5(const char *data
, DWORD dataSize
,
42 BYTE
**hash
, DWORD
&hashSize
)
47 if (!CryptAcquireContext(&hProv
, nullptr, nullptr, PROV_RSA_FULL
,
50 if (NTE_BAD_KEYSET
!= GetLastError())
55 // Maybe it doesn't exist, try to create it.
56 if (!CryptAcquireContext(&hProv
, nullptr, nullptr, PROV_RSA_FULL
,
57 CRYPT_VERIFYCONTEXT
| CRYPT_NEWKEYSET
))
63 if (!CryptCreateHash(hProv
, CALG_MD5
, 0, 0, &hHash
))
68 if (!CryptHashData(hHash
, reinterpret_cast<const BYTE
*>(data
),
74 DWORD dwCount
= sizeof(DWORD
);
75 if (!CryptGetHashParam(hHash
, HP_HASHSIZE
, (BYTE
*)&hashSize
,
81 *hash
= new BYTE
[hashSize
];
82 ZeroMemory(*hash
, hashSize
);
83 if (!CryptGetHashParam(hHash
, HP_HASHVAL
, *hash
, &hashSize
, 0))
90 CryptDestroyHash(hHash
);
95 CryptReleaseContext(hProv
,0);
102 * Converts a file path into a unique registry location for cert storage
104 * @param filePath The input file path to get a registry path from
105 * @param registryPath A buffer to write the registry path to, must
106 * be of size in WCHARs MAX_PATH + 1
107 * @return TRUE if successful
110 CalculateRegistryPathFromFilePath(const LPCWSTR filePath
,
113 size_t filePathLen
= wcslen(filePath
);
119 // If the file path ends in a slash, ignore that character
120 if (filePath
[filePathLen
-1] == L
'\\' ||
121 filePath
[filePathLen
- 1] == L
'/')
126 // Copy in the full path into our own buffer.
127 // Copying in the extra slash is OK because we calculate the hash
128 // based on the filePathLen which excludes the slash.
129 // +2 to account for the possibly trailing slash and the null terminator.
130 WCHAR
*lowercasePath
= new WCHAR
[filePathLen
+ 2];
131 memset(lowercasePath
, 0, (filePathLen
+ 2) * sizeof(WCHAR
));
132 wcsncpy(lowercasePath
, filePath
, filePathLen
+ 1);
133 _wcslwr(lowercasePath
);
137 if (!CalculateMD5(reinterpret_cast<const char*>(lowercasePath
),
141 delete[] lowercasePath
;
144 delete[] lowercasePath
;
146 LPCWSTR baseRegPath
= L
"SOFTWARE\\LibreOffice\\MaintenanceService\\";
147 wcsncpy(registryPath
, baseRegPath
, MAX_PATH
);
148 BinaryDataToHexString(hash
, hashSize
,
149 registryPath
+ wcslen(baseRegPath
));