mirror of
https://github.com/reactos/reactos.git
synced 2025-07-05 23:01:21 +00:00
[WINTRUST] Sync with Wine Staging 2.9. CORE-13362
e420549 wintrust: Verify image hash in WinVerifyTrust. (v2) f1dfc53 wintrust: Fix CryptCATAdminAcquireContext spec file entry. svn path=/trunk/; revision=74869
This commit is contained in:
parent
2464924026
commit
2e2012f926
3 changed files with 84 additions and 59 deletions
|
@ -203,77 +203,116 @@ static DWORD SOFTPUB_GetMessageFromFile(CRYPT_PROVIDER_DATA *data, HANDLE file,
|
||||||
/* See https://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
|
/* See https://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
|
||||||
* for details about the hashing.
|
* 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;
|
DWORD pos, checksum, security_dir;
|
||||||
IMAGE_NT_HEADERS *ntheader;
|
IMAGE_DOS_HEADER dos_header;
|
||||||
IMAGE_DATA_DIRECTORY *security_dir;
|
union
|
||||||
DWORD *checksum;
|
{
|
||||||
|
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;
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dosheader->e_lfanew >= 256 * 1024 * 1024) /* see RtlImageNtHeaderEx */
|
if (nt_header.nt32.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
ERR("Unrecognized IMAGE_NT_HEADERS signature %08x\n", ntheader->Signature);
|
if (bytes_read < sizeof(nt_header.nt32))
|
||||||
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)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
checksum = &nt32->OptionalHeader.CheckSum;
|
checksum = dos_header.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader.CheckSum);
|
||||||
security_dir = &nt32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
|
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 (bytes_read < sizeof(nt_header.nt64))
|
||||||
if (dosheader->e_lfanew + sizeof(nt64) > size->QuadPart)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
checksum = &nt64->OptionalHeader.CheckSum;
|
checksum = dos_header.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader.CheckSum);
|
||||||
security_dir = &nt64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
|
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
|
else
|
||||||
{
|
{
|
||||||
ERR("Unrecognized OptionalHeader magic %04x\n", ntheader->OptionalHeader.Magic);
|
ERR("Unrecognized OptionalHeader magic %04x\n", nt_header.nt32.OptionalHeader.Magic);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (security_dir->VirtualAddress < (BYTE *)(security_dir + 1) - file)
|
if (secdir.VirtualAddress < security_dir + sizeof(IMAGE_DATA_DIRECTORY))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (security_dir->VirtualAddress > size->QuadPart)
|
if (secdir.VirtualAddress > file_size.QuadPart)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (security_dir->VirtualAddress + security_dir->Size != size->QuadPart)
|
if (secdir.VirtualAddress + secdir.Size != file_size.QuadPart)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Hash until checksum. */
|
/* Hash until checksum. */
|
||||||
if (!CryptHashData(hash, file, (BYTE *)checksum - file, 0))
|
SetFilePointer(file, 0, NULL, FILE_BEGIN);
|
||||||
return FALSE;
|
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. */
|
/* Hash until the DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY] entry. */
|
||||||
if (!CryptHashData(hash, (BYTE *)(checksum + 1), (BYTE *)security_dir - (BYTE *)(checksum + 1), 0))
|
checksum += sizeof(DWORD);
|
||||||
return FALSE;
|
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. */
|
/* Hash until the end of the file. */
|
||||||
if (!CryptHashData(hash, (BYTE *)(security_dir + 1),
|
security_dir += sizeof(IMAGE_DATA_DIRECTORY);
|
||||||
file + security_dir->VirtualAddress - (BYTE *)(security_dir + 1), 0))
|
SetFilePointer(file, security_dir, NULL, FILE_BEGIN);
|
||||||
return FALSE;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -282,13 +321,11 @@ static DWORD SOFTPUB_VerifyImageHash(CRYPT_PROVIDER_DATA *data, HANDLE file)
|
||||||
{
|
{
|
||||||
SPC_INDIRECT_DATA_CONTENT *indirect = (SPC_INDIRECT_DATA_CONTENT *)data->u.pPDSip->psIndirectData;
|
SPC_INDIRECT_DATA_CONTENT *indirect = (SPC_INDIRECT_DATA_CONTENT *)data->u.pPDSip->psIndirectData;
|
||||||
DWORD err, hash_size, length;
|
DWORD err, hash_size, length;
|
||||||
BYTE *hash_data, *file_map = NULL;
|
BYTE *hash_data;
|
||||||
LARGE_INTEGER file_size;
|
|
||||||
BOOL release_prov = FALSE;
|
BOOL release_prov = FALSE;
|
||||||
HCRYPTPROV prov = data->hProv;
|
HCRYPTPROV prov = data->hProv;
|
||||||
HCRYPTHASH hash = 0;
|
HCRYPTHASH hash = 0;
|
||||||
ALG_ID algID;
|
ALG_ID algID;
|
||||||
HANDLE map = NULL;
|
|
||||||
|
|
||||||
if (((ULONG_PTR)indirect->Data.pszObjId >> 16) == 0 ||
|
if (((ULONG_PTR)indirect->Data.pszObjId >> 16) == 0 ||
|
||||||
strcmp(indirect->Data.pszObjId, SPC_PE_IMAGE_DATA_OBJID))
|
strcmp(indirect->Data.pszObjId, SPC_PE_IMAGE_DATA_OBJID))
|
||||||
|
@ -313,15 +350,7 @@ static DWORD SOFTPUB_VerifyImageHash(CRYPT_PROVIDER_DATA *data, HANDLE file)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetFileSizeEx(file, &file_size) ||
|
if (!SOFTPUB_HashPEFile(file, hash))
|
||||||
!(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))
|
|
||||||
{
|
{
|
||||||
err = TRUST_E_NOSIGNATURE;
|
err = TRUST_E_NOSIGNATURE;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -352,10 +381,6 @@ static DWORD SOFTPUB_VerifyImageHash(CRYPT_PROVIDER_DATA *data, HANDLE file)
|
||||||
data->psPfns->pfnFree(hash_data);
|
data->psPfns->pfnFree(hash_data);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (file_map)
|
|
||||||
UnmapViewOfFile(file_map);
|
|
||||||
if (map)
|
|
||||||
CloseHandle(map);
|
|
||||||
if (hash)
|
if (hash)
|
||||||
CryptDestroyHash(hash);
|
CryptDestroyHash(hash);
|
||||||
if (release_prov)
|
if (release_prov)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@ stub AddPersonalTrustDBPages
|
@ stub AddPersonalTrustDBPages
|
||||||
@ stub CatalogCompactHashDatabase
|
@ stub CatalogCompactHashDatabase
|
||||||
@ stdcall CryptCATAdminAcquireContext(long ptr long)
|
@ stdcall CryptCATAdminAcquireContext(ptr ptr long)
|
||||||
@ stdcall CryptCATAdminAddCatalog(long wstr wstr long)
|
@ stdcall CryptCATAdminAddCatalog(long wstr wstr long)
|
||||||
@ stdcall CryptCATAdminCalcHashFromFileHandle(long ptr ptr long)
|
@ stdcall CryptCATAdminCalcHashFromFileHandle(long ptr ptr long)
|
||||||
@ stdcall CryptCATAdminEnumCatalogFromHash(long ptr long long ptr)
|
@ stdcall CryptCATAdminEnumCatalogFromHash(long ptr long long ptr)
|
||||||
|
|
|
@ -206,7 +206,7 @@ reactos/dll/win32/winmm # Forked at Wine-20050628
|
||||||
reactos/dll/win32/winmm/midimap # Forked at Wine-20050628
|
reactos/dll/win32/winmm/midimap # Forked at Wine-20050628
|
||||||
reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628
|
reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628
|
||||||
reactos/dll/win32/winscard # Synced to WineStaging-2.2
|
reactos/dll/win32/winscard # Synced to WineStaging-2.2
|
||||||
reactos/dll/win32/wintrust # Synced to WineStaging-2.2
|
reactos/dll/win32/wintrust # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/wldap32 # Synced to WineStaging-2.2
|
reactos/dll/win32/wldap32 # Synced to WineStaging-2.2
|
||||||
reactos/dll/win32/wmi # Synced to WineStaging-1.9.11
|
reactos/dll/win32/wmi # Synced to WineStaging-1.9.11
|
||||||
reactos/dll/win32/wmiutils # Synced to WineStaging-1.9.11
|
reactos/dll/win32/wmiutils # Synced to WineStaging-1.9.11
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue