1 /*
2  * PROJECT:     ReactOS Applications Manager
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * FILE:        base/applications/rapps/integrity.cpp
5  * PURPOSE:     Various integrity check mechanisms
6  * COPYRIGHT:   Copyright Ismael Ferreras Morezuelas (swyterzone+ros@gmail.com)
7  *              Copyright Mark Jansen
8  */
9 #include "rapps.h"
10 
11 #include <sha1.h>
12 
13 BOOL VerifyInteg(const ATL::CStringW &SHA1Hash, const ATL::CStringW &FileName)
14 {
15     return VerifyInteg(SHA1Hash.GetString(), FileName.GetString());
16 }
17 
18 BOOL VerifyInteg(LPCWSTR lpSHA1Hash, LPCWSTR lpFileName)
19 {
20     BOOL ret = FALSE;
21 
22     /* first off, does it exist at all? */
23     HANDLE file = CreateFileW(lpFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
24 
25     if (file == INVALID_HANDLE_VALUE)
26         return FALSE;
27 
28     /* let's grab the actual file size to organize the mmap'ing rounds */
29     LARGE_INTEGER size;
30     GetFileSizeEx(file, &size);
31 
32     /* retrieve a handle to map the file contents to memory */
33     HANDLE map = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
34     if (map)
35     {
36         /* map that thing in address space */
37         const unsigned char *file_map = static_cast<const unsigned char *>(MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0));
38         if (file_map)
39         {
40             SHA_CTX ctx;
41             /* initialize the SHA-1 context */
42             A_SHAInit(&ctx);
43 
44             /* feed the data to the cookie monster */
45             A_SHAUpdate(&ctx, file_map, size.LowPart);
46 
47             /* cool, we don't need this anymore */
48             UnmapViewOfFile(file_map);
49 
50             /* we're done, compute the final hash */
51             ULONG sha[5];
52             A_SHAFinal(&ctx, sha);
53 
54             WCHAR buf[(sizeof(sha) * 2) + 1];
55             for (UINT i = 0; i < sizeof(sha); i++)
56                 swprintf(buf + 2 * i, L"%02x", ((unsigned char *) sha)[i]);
57             /* does the resulting SHA1 match with the provided one? */
58             if (!_wcsicmp(buf, lpSHA1Hash))
59                 ret = TRUE;
60         }
61         CloseHandle(map);
62     }
63     CloseHandle(file);
64     return ret;
65 }
66