mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
wintrust-WinVerifyTrust: Do not use memory mapping.
This commit is contained in:
parent
943ffbfbbf
commit
9e463db339
@ -9039,7 +9039,7 @@ if test "$enable_wintrust_WinVerifyTrust" -eq 1; then
|
||||
(
|
||||
printf '%s\n' '+ { "Mark Jansen", "wintrust/tests: Add tests for WinVerifyTrust.", 2 },';
|
||||
printf '%s\n' '+ { "Sebastian Lackner", "wintrust/tests: Add some additional tests.", 1 },';
|
||||
printf '%s\n' '+ { "Mark Jansen", "wintrust: Verify image hash in WinVerifyTrust.", 1 },';
|
||||
printf '%s\n' '+ { "Mark Jansen", "wintrust: Verify image hash in WinVerifyTrust.", 2 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
|
@ -1,16 +1,19 @@
|
||||
From 108397c3d5e227ac2d83740a7f437fa275f1e65d Mon Sep 17 00:00:00 2001
|
||||
From 34d2916d1616b418395c6f543ba9cd362a82d7ab Mon Sep 17 00:00:00 2001
|
||||
From: Mark Jansen <learn0more+wine@gmail.com>
|
||||
Date: Sat, 2 Apr 2016 02:57:47 +0200
|
||||
Subject: wintrust: Verify image hash in WinVerifyTrust.
|
||||
Subject: wintrust: Verify image hash in WinVerifyTrust. (v2)
|
||||
|
||||
Includes various improvements by Sebastian Lackner <sebastian@fds-team.de>.
|
||||
|
||||
Changes in v2:
|
||||
* Do not use memory mapping (based on a patch by Mark Jansen).
|
||||
---
|
||||
dlls/wintrust/softpub.c | 169 ++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/wintrust/softpub.c | 194 ++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/wintrust/tests/softpub.c | 8 +-
|
||||
2 files changed, 173 insertions(+), 4 deletions(-)
|
||||
2 files changed, 198 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/wintrust/softpub.c b/dlls/wintrust/softpub.c
|
||||
index 4e8582e..bb2fbd4 100644
|
||||
index 4e8582e2183..35c0d7b5abb 100644
|
||||
--- a/dlls/wintrust/softpub.c
|
||||
+++ b/dlls/wintrust/softpub.c
|
||||
@@ -1,5 +1,6 @@
|
||||
@ -28,84 +31,123 @@ index 4e8582e..bb2fbd4 100644
|
||||
#include "wintrust.h"
|
||||
#include "mssip.h"
|
||||
#include "softpub.h"
|
||||
@@ -208,6 +210,170 @@ static DWORD SOFTPUB_GetMessageFromFile(CRYPT_PROVIDER_DATA *data, HANDLE file,
|
||||
@@ -208,6 +210,195 @@ static DWORD SOFTPUB_GetMessageFromFile(CRYPT_PROVIDER_DATA *data, HANDLE file,
|
||||
return err;
|
||||
}
|
||||
|
||||
+/* See https://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
|
||||
+ * for details about the hashing.
|
||||
+ */
|
||||
+static BOOL SOFTPUB_HashPEFile(BYTE *file, LARGE_INTEGER *size, HCRYPTHASH hash)
|
||||
+static BOOL SOFTPUB_HashPEFile(HANDLE file, HCRYPTHASH hash)
|
||||
+{
|
||||
+ IMAGE_DOS_HEADER *dosheader = (IMAGE_DOS_HEADER *)file;
|
||||
+ IMAGE_NT_HEADERS *ntheader;
|
||||
+ IMAGE_DATA_DIRECTORY *security_dir;
|
||||
+ DWORD *checksum;
|
||||
+ DWORD pos, checksum, security_dir;
|
||||
+ IMAGE_DOS_HEADER dos_header;
|
||||
+ union
|
||||
+ {
|
||||
+ IMAGE_NT_HEADERS32 nt32;
|
||||
+ IMAGE_NT_HEADERS64 nt64;
|
||||
+ } nt_header;
|
||||
+ IMAGE_DATA_DIRECTORY secdir;
|
||||
+ LARGE_INTEGER file_size;
|
||||
+ DWORD bytes_read;
|
||||
+ BYTE buffer[1024];
|
||||
+ BOOL ret;
|
||||
+
|
||||
+ if (sizeof(dosheader) > size->QuadPart)
|
||||
+ if (!GetFileSizeEx(file, &file_size))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (dosheader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
+ SetFilePointer(file, 0, NULL, FILE_BEGIN);
|
||||
+ ret = ReadFile(file, &dos_header, sizeof(dos_header), &bytes_read, NULL);
|
||||
+ if (!ret || bytes_read != sizeof(dos_header))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (dos_header.e_magic != IMAGE_DOS_SIGNATURE)
|
||||
+ {
|
||||
+ ERR("Unrecognized IMAGE_DOS_HEADER magic %04x\n", dosheader->e_magic);
|
||||
+ ERR("Unrecognized IMAGE_DOS_HEADER magic %04x\n", dos_header.e_magic);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ if (dos_header.e_lfanew >= 256 * 1024 * 1024) /* see RtlImageNtHeaderEx */
|
||||
+ return FALSE;
|
||||
+ if (dos_header.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader.MajorLinkerVersion) > file_size.QuadPart)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ SetFilePointer(file, dos_header.e_lfanew, NULL, FILE_BEGIN);
|
||||
+ ret = ReadFile(file, &nt_header, sizeof(nt_header), &bytes_read, NULL);
|
||||
+ if (!ret || bytes_read < FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader.Magic) +
|
||||
+ sizeof(nt_header.nt32.OptionalHeader.Magic))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (nt_header.nt32.Signature != IMAGE_NT_SIGNATURE)
|
||||
+ {
|
||||
+ ERR("Unrecognized IMAGE_NT_HEADERS signature %08x\n", nt_header.nt32.Signature);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (dosheader->e_lfanew >= 256 * 1024 * 1024) /* see RtlImageNtHeaderEx */
|
||||
+ return FALSE;
|
||||
+ if (dosheader->e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader.MajorLinkerVersion) > size->QuadPart)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ ntheader = (IMAGE_NT_HEADERS *)(file + dosheader->e_lfanew);
|
||||
+ if (ntheader->Signature != IMAGE_NT_SIGNATURE)
|
||||
+ if (nt_header.nt32.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||
+ {
|
||||
+ ERR("Unrecognized IMAGE_NT_HEADERS signature %08x\n", ntheader->Signature);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (ntheader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||
+ {
|
||||
+ IMAGE_NT_HEADERS32 *nt32 = (IMAGE_NT_HEADERS32 *)ntheader;
|
||||
+ if (dosheader->e_lfanew + sizeof(nt32) > size->QuadPart)
|
||||
+ if (bytes_read < sizeof(nt_header.nt32))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ checksum = &nt32->OptionalHeader.CheckSum;
|
||||
+ security_dir = &nt32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
|
||||
+ checksum = dos_header.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader.CheckSum);
|
||||
+ security_dir = dos_header.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY]);
|
||||
+ secdir = nt_header.nt32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
|
||||
+ }
|
||||
+ else if (ntheader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
|
||||
+ else if (nt_header.nt32.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
|
||||
+ {
|
||||
+ IMAGE_NT_HEADERS64 *nt64 = (IMAGE_NT_HEADERS64 *)ntheader;
|
||||
+ if (dosheader->e_lfanew + sizeof(nt64) > size->QuadPart)
|
||||
+ if (bytes_read < sizeof(nt_header.nt64))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ checksum = &nt64->OptionalHeader.CheckSum;
|
||||
+ security_dir = &nt64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
|
||||
+ checksum = dos_header.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader.CheckSum);
|
||||
+ security_dir = dos_header.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY]);
|
||||
+ secdir = nt_header.nt64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ERR("Unrecognized OptionalHeader magic %04x\n", ntheader->OptionalHeader.Magic);
|
||||
+ ERR("Unrecognized OptionalHeader magic %04x\n", nt_header.nt32.OptionalHeader.Magic);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (security_dir->VirtualAddress < (BYTE *)(security_dir + 1) - file)
|
||||
+ if (secdir.VirtualAddress < security_dir + sizeof(IMAGE_DATA_DIRECTORY))
|
||||
+ return FALSE;
|
||||
+ if (security_dir->VirtualAddress > size->QuadPart)
|
||||
+ if (secdir.VirtualAddress > file_size.QuadPart)
|
||||
+ return FALSE;
|
||||
+ if (security_dir->VirtualAddress + security_dir->Size != size->QuadPart)
|
||||
+ if (secdir.VirtualAddress + secdir.Size != file_size.QuadPart)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /* Hash until checksum. */
|
||||
+ if (!CryptHashData(hash, file, (BYTE *)checksum - file, 0))
|
||||
+ return FALSE;
|
||||
+ SetFilePointer(file, 0, NULL, FILE_BEGIN);
|
||||
+ for (pos = 0; pos < checksum; pos += bytes_read)
|
||||
+ {
|
||||
+ ret = ReadFile(file, buffer, min(sizeof(buffer), checksum - pos), &bytes_read, NULL);
|
||||
+ if (!ret || !bytes_read)
|
||||
+ return FALSE;
|
||||
+ if (!CryptHashData(hash, buffer, bytes_read, 0))
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /* Hash until the DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY] entry. */
|
||||
+ if (!CryptHashData(hash, (BYTE *)(checksum + 1), (BYTE *)security_dir - (BYTE *)(checksum + 1), 0))
|
||||
+ return FALSE;
|
||||
+ checksum += sizeof(DWORD);
|
||||
+ SetFilePointer(file, checksum, NULL, FILE_BEGIN);
|
||||
+ for (pos = checksum; pos < security_dir; pos += bytes_read)
|
||||
+ {
|
||||
+ ret = ReadFile(file, buffer, min(sizeof(buffer), security_dir - pos), &bytes_read, NULL);
|
||||
+ if (!ret || !bytes_read)
|
||||
+ return FALSE;
|
||||
+ if (!CryptHashData(hash, buffer, bytes_read, 0))
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /* Hash until the end of the file. */
|
||||
+ if (!CryptHashData(hash, (BYTE *)(security_dir + 1),
|
||||
+ file + security_dir->VirtualAddress - (BYTE *)(security_dir + 1), 0))
|
||||
+ return FALSE;
|
||||
+ security_dir += sizeof(IMAGE_DATA_DIRECTORY);
|
||||
+ SetFilePointer(file, security_dir, NULL, FILE_BEGIN);
|
||||
+ for (pos = security_dir; pos < secdir.VirtualAddress; pos += bytes_read)
|
||||
+ {
|
||||
+ ret = ReadFile(file, buffer, min(sizeof(buffer), secdir.VirtualAddress - pos), &bytes_read, NULL);
|
||||
+ if (!ret || !bytes_read)
|
||||
+ return FALSE;
|
||||
+ if (!CryptHashData(hash, buffer, bytes_read, 0))
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
@ -114,13 +156,11 @@ index 4e8582e..bb2fbd4 100644
|
||||
+{
|
||||
+ SPC_INDIRECT_DATA_CONTENT *indirect = (SPC_INDIRECT_DATA_CONTENT *)data->u.pPDSip->psIndirectData;
|
||||
+ DWORD err, hash_size, length;
|
||||
+ BYTE *hash_data, *file_map = NULL;
|
||||
+ LARGE_INTEGER file_size;
|
||||
+ BYTE *hash_data;
|
||||
+ BOOL release_prov = FALSE;
|
||||
+ HCRYPTPROV prov = data->hProv;
|
||||
+ HCRYPTHASH hash = 0;
|
||||
+ ALG_ID algID;
|
||||
+ HANDLE map = NULL;
|
||||
+
|
||||
+ if (((ULONG_PTR)indirect->Data.pszObjId >> 16) == 0 ||
|
||||
+ strcmp(indirect->Data.pszObjId, SPC_PE_IMAGE_DATA_OBJID))
|
||||
@ -145,15 +185,7 @@ index 4e8582e..bb2fbd4 100644
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (!GetFileSizeEx(file, &file_size) ||
|
||||
+ !(map = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL)) ||
|
||||
+ !(file_map = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0)))
|
||||
+ {
|
||||
+ err = GetLastError();
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (!SOFTPUB_HashPEFile(file_map, &file_size, hash))
|
||||
+ if (!SOFTPUB_HashPEFile(file, hash))
|
||||
+ {
|
||||
+ err = TRUST_E_NOSIGNATURE;
|
||||
+ goto done;
|
||||
@ -184,10 +216,6 @@ index 4e8582e..bb2fbd4 100644
|
||||
+ data->psPfns->pfnFree(hash_data);
|
||||
+
|
||||
+done:
|
||||
+ if (file_map)
|
||||
+ UnmapViewOfFile(file_map);
|
||||
+ if (map)
|
||||
+ CloseHandle(map);
|
||||
+ if (hash)
|
||||
+ CryptDestroyHash(hash);
|
||||
+ if (release_prov)
|
||||
@ -199,7 +227,7 @@ index 4e8582e..bb2fbd4 100644
|
||||
static DWORD SOFTPUB_CreateStoreFromMessage(CRYPT_PROVIDER_DATA *data)
|
||||
{
|
||||
DWORD err = ERROR_SUCCESS;
|
||||
@@ -371,6 +537,9 @@ static DWORD SOFTPUB_LoadFileMessage(CRYPT_PROVIDER_DATA *data)
|
||||
@@ -371,6 +562,9 @@ static DWORD SOFTPUB_LoadFileMessage(CRYPT_PROVIDER_DATA *data)
|
||||
if (err)
|
||||
goto error;
|
||||
err = SOFTPUB_DecodeInnerContent(data);
|
||||
@ -210,10 +238,10 @@ index 4e8582e..bb2fbd4 100644
|
||||
error:
|
||||
if (err && data->fOpenedFile && data->pWintrustData->u.pFile)
|
||||
diff --git a/dlls/wintrust/tests/softpub.c b/dlls/wintrust/tests/softpub.c
|
||||
index a2fa764..526b0eb 100644
|
||||
index aa481e407fc..1f872341357 100644
|
||||
--- a/dlls/wintrust/tests/softpub.c
|
||||
+++ b/dlls/wintrust/tests/softpub.c
|
||||
@@ -1156,7 +1156,7 @@ static void test_wintrust_digest(void)
|
||||
@@ -1152,7 +1152,7 @@ static void test_wintrust_digest(void)
|
||||
{
|
||||
{{ SelfSignedFile32, sizeof(SelfSignedFile32) },
|
||||
{ Dummy, sizeof(Dummy) }},
|
||||
@ -222,7 +250,7 @@ index a2fa764..526b0eb 100644
|
||||
},
|
||||
{
|
||||
{{ Dummy, sizeof(Dummy) },
|
||||
@@ -1167,7 +1167,7 @@ static void test_wintrust_digest(void)
|
||||
@@ -1163,7 +1163,7 @@ static void test_wintrust_digest(void)
|
||||
{{ SelfSignedFile32, 19 },
|
||||
{ Dummy, sizeof(Dummy) },
|
||||
{ SelfSignedFile32 + 19 + sizeof(Dummy), sizeof(SelfSignedFile32) - 19 - sizeof(Dummy) }},
|
||||
@ -231,7 +259,7 @@ index a2fa764..526b0eb 100644
|
||||
},
|
||||
{
|
||||
{{ SelfSignedFile32, sizeof(IMAGE_DOS_HEADER) }},
|
||||
@@ -1186,7 +1186,7 @@ static void test_wintrust_digest(void)
|
||||
@@ -1182,7 +1182,7 @@ static void test_wintrust_digest(void)
|
||||
{
|
||||
{{ SelfSignedFile64, sizeof(SelfSignedFile64) },
|
||||
{ Dummy, sizeof(Dummy) }},
|
||||
@ -240,7 +268,7 @@ index a2fa764..526b0eb 100644
|
||||
},
|
||||
{
|
||||
{{ Dummy, sizeof(Dummy) },
|
||||
@@ -1197,7 +1197,7 @@ static void test_wintrust_digest(void)
|
||||
@@ -1193,7 +1193,7 @@ static void test_wintrust_digest(void)
|
||||
{{ SelfSignedFile64, 19 },
|
||||
{ Dummy, sizeof(Dummy) },
|
||||
{ SelfSignedFile64 + 19 + sizeof(Dummy), sizeof(SelfSignedFile64) - 19 - sizeof(Dummy) }},
|
||||
@ -250,5 +278,5 @@ index a2fa764..526b0eb 100644
|
||||
{
|
||||
{{ SelfSignedFile64, sizeof(IMAGE_DOS_HEADER) }},
|
||||
--
|
||||
2.7.1
|
||||
2.11.0
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user