Reactos
1/*
2 * PROJECT: ReactOS certutil
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: CertUtil hashfile implementation
5 * COPYRIGHT: Copyright 2020 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8#include "precomp.h"
9#include <wincrypt.h>
10#include <stdlib.h>
11
12
13BOOL hash_file(LPCWSTR Filename)
14{
15 HCRYPTPROV hProv;
16 BOOL bSuccess = FALSE;
17
18 HANDLE hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL,
19 OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
20
21 if (hFile == INVALID_HANDLE_VALUE)
22 {
23 ConPrintf(StdOut, L"CertUtil: -hashfile command failed: %d\n", GetLastError());
24 return bSuccess;
25 }
26
27 if (CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
28 {
29 HCRYPTHASH hHash;
30
31 if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
32 {
33 BYTE Buffer[2048];
34 DWORD cbRead;
35
36 while ((bSuccess = ReadFile(hFile, Buffer, sizeof(Buffer), &cbRead, NULL)))
37 {
38 if (cbRead == 0)
39 break;
40
41 if (!CryptHashData(hHash, Buffer, cbRead, 0))
42 {
43 bSuccess = FALSE;
44 ConPrintf(StdOut, L"CertUtil: -hashfile command failed to hash: %d\n", GetLastError());
45 break;
46 }
47 }
48
49 if (bSuccess)
50 {
51 BYTE rgbHash[20];
52 DWORD cbHash, n;
53
54 if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
55 {
56 ConPrintf(StdOut, L"SHA1 hash of %s:\n", Filename);
57 for (n = 0; n < cbHash; ++n)
58 {
59 ConPrintf(StdOut, L"%02x", rgbHash[n]);
60 }
61 ConPuts(StdOut, L"\n");
62 }
63 else
64 {
65 ConPrintf(StdOut, L"CertUtil: -hashfile command failed to extract hash: %d\n", GetLastError());
66 bSuccess = FALSE;
67 }
68 }
69
70 CryptDestroyHash(hHash);
71 }
72 else
73 {
74 ConPrintf(StdOut, L"CertUtil: -hashfile command no algorithm: %d\n", GetLastError());
75 }
76
77 CryptReleaseContext(hProv, 0);
78 }
79 else
80 {
81 ConPrintf(StdOut, L"CertUtil: -hashfile command no context: %d\n", GetLastError());
82 }
83
84 CloseHandle(hFile);
85 return bSuccess;
86}
87