https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ee69ca786af5e2d13c3803...
commit ee69ca786af5e2d13c380323d784909f92f80649 Author: Mark Jansen mark.jansen@reactos.org AuthorDate: Thu Sep 10 23:40:52 2020 +0200 Commit: Mark Jansen mark.jansen@reactos.org CommitDate: Fri Sep 11 15:29:28 2020 +0200
[CERTUTIL] Add skeleton application with support for -hashfile --- base/applications/cmdutils/CMakeLists.txt | 1 + base/applications/cmdutils/certutil/CMakeLists.txt | 13 ++ base/applications/cmdutils/certutil/certutil.c | 155 +++++++++++++++++++++ base/applications/cmdutils/certutil/precomp.h | 16 +++ 4 files changed, 185 insertions(+)
diff --git a/base/applications/cmdutils/CMakeLists.txt b/base/applications/cmdutils/CMakeLists.txt index d2a800ca416..dd8a7ab2b06 100644 --- a/base/applications/cmdutils/CMakeLists.txt +++ b/base/applications/cmdutils/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(at) add_subdirectory(attrib) +add_subdirectory(certutil) add_subdirectory(chcp) add_subdirectory(clip) add_subdirectory(comp) diff --git a/base/applications/cmdutils/certutil/CMakeLists.txt b/base/applications/cmdutils/certutil/CMakeLists.txt new file mode 100644 index 00000000000..bb9cd3a2fde --- /dev/null +++ b/base/applications/cmdutils/certutil/CMakeLists.txt @@ -0,0 +1,13 @@ + +include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/conutils) + +list(APPEND SOURCE + certutil.c + precomp.h) + +add_executable(certutil ${SOURCE}) +set_module_type(certutil win32cui UNICODE) +target_link_libraries(certutil conutils ${PSEH_LIB}) +add_importlibs(certutil advapi32 msvcrt kernel32) +add_pch(certutil precomp.h SOURCE) +add_cd_file(TARGET certutil DESTINATION reactos/system32 FOR all) diff --git a/base/applications/cmdutils/certutil/certutil.c b/base/applications/cmdutils/certutil/certutil.c new file mode 100644 index 00000000000..7d6d2d68987 --- /dev/null +++ b/base/applications/cmdutils/certutil/certutil.c @@ -0,0 +1,155 @@ +/* + * PROJECT: ReactOS certutil + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: CertUtil stub + * COPYRIGHT: Copyright 2020 Mark Jansen (mark.jansen@reactos.org) + * + * Note: Only -hashfile is implemented for now, the rest is not present! + */ + +#include "precomp.h" +#include <wincrypt.h> +#include <stdlib.h> + + +static BOOL hash_file(LPCWSTR Filename) +{ + HCRYPTPROV hProv; + BOOL bSuccess = FALSE; + + HANDLE hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); + + if (hFile == INVALID_HANDLE_VALUE) + { + ConPrintf(StdOut, L"CertUtil: -hashfile command failed: %d\n", GetLastError()); + return bSuccess; + } + + if (CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + { + HCRYPTHASH hHash; + + if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) + { + BYTE Buffer[2048]; + DWORD cbRead; + + while ((bSuccess = ReadFile(hFile, Buffer, sizeof(Buffer), &cbRead, NULL))) + { + if (cbRead == 0) + break; + + if (!CryptHashData(hHash, Buffer, cbRead, 0)) + { + bSuccess = FALSE; + ConPrintf(StdOut, L"CertUtil: -hashfile command failed to hash: %d\n", GetLastError()); + break; + } + } + + if (bSuccess) + { + BYTE rgbHash[20]; + DWORD cbHash, n; + + if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) + { + ConPrintf(StdOut, L"SHA1 hash of %s:\n", Filename); + for (n = 0; n < cbHash; ++n) + { + ConPrintf(StdOut, L"%02x", rgbHash[n]); + } + ConPuts(StdOut, L"\n"); + } + else + { + ConPrintf(StdOut, L"CertUtil: -hashfile command failed to extract hash: %d\n", GetLastError()); + bSuccess = FALSE; + } + } + + CryptDestroyHash(hHash); + } + else + { + ConPrintf(StdOut, L"CertUtil: -hashfile command no algorithm: %d\n", GetLastError()); + } + + CryptReleaseContext(hProv, 0); + } + else + { + ConPrintf(StdOut, L"CertUtil: -hashfile command no context: %d\n", GetLastError()); + } + + CloseHandle(hFile); + return bSuccess; +} + + +static void print_usage() +{ + ConPuts(StdOut, L"Verbs:\n"); + ConPuts(StdOut, L" -hashfile -- Display cryptographic hash over a file\n"); + ConPuts(StdOut, L"\n"); + ConPuts(StdOut, L"CertUtil -? -- Display a list of all verbs\n"); + ConPuts(StdOut, L"CertUtil -hashfile -? -- Display help text for the 'hashfile' verb\n"); +} + +int wmain(int argc, WCHAR *argv[]) +{ + int n; + + /* Initialize the Console Standard Streams */ + ConInitStdStreams(); + + if (argc == 1) /* i.e. no commandline arguments given */ + { + print_usage(); + return EXIT_SUCCESS; + } + + for (n = 1; n < argc; ++n) + { + if (!_wcsicmp(argv[n], L"-?")) + { + print_usage(); + return EXIT_SUCCESS; + } + else if (!_wcsicmp(argv[n], L"-hashfile")) + { + if (argc == 3) + { + if (!_wcsicmp(argv[n+1], L"-?")) + { + print_usage(); + return EXIT_SUCCESS; + } + else + { + if (!hash_file(argv[n+1])) + { + /* hash_file prints the failure itself */ + return EXIT_FAILURE; + } + + ConPuts(StdOut, L"CertUtil: -hashfile command completed successfully\n"); + return EXIT_SUCCESS; + } + } + else + { + ConPrintf(StdOut, L"CertUtil: -hashfile expected 1 argument, got %d\n", argc - 2); + return EXIT_FAILURE; + } + } + else + { + ConPrintf(StdOut, L"CertUtil: Unknown verb: %s\n", argv[n]); + return EXIT_FAILURE; + } + } + + return EXIT_SUCCESS; +} diff --git a/base/applications/cmdutils/certutil/precomp.h b/base/applications/cmdutils/certutil/precomp.h new file mode 100644 index 00000000000..0c8e115bf5e --- /dev/null +++ b/base/applications/cmdutils/certutil/precomp.h @@ -0,0 +1,16 @@ +#ifndef __CERTUTIL_PRECOMP_H +#define __CERTUTIL_PRECOMP_H + +/* INCLUDES ******************************************************************/ + +#include <stdarg.h> + +#include <windef.h> +#include <winbase.h> +#include <winreg.h> +#include <winuser.h> + +#include <conutils.h> + + +#endif /* __CERTUTIL_PRECOMP_H */