Author: tfaber Date: Fri Jul 13 07:43:41 2012 New Revision: 56878
URL: http://svn.reactos.org/svn/reactos?rev=56878&view=rev Log: [WINTRUST_WINETEST] - Sync to Wine 1.5.4 - Fix MSVC build. Already applied upstream.
Modified: trunk/rostests/winetests/wintrust/CMakeLists.txt trunk/rostests/winetests/wintrust/asn.c trunk/rostests/winetests/wintrust/crypt.c trunk/rostests/winetests/wintrust/register.c trunk/rostests/winetests/wintrust/softpub.c
Modified: trunk/rostests/winetests/wintrust/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/wintrust/CMakeLi... ============================================================================== --- trunk/rostests/winetests/wintrust/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/winetests/wintrust/CMakeLists.txt [iso-8859-1] Fri Jul 13 07:43:41 2012 @@ -1,7 +1,5 @@
-add_definitions( - -D__ROS_LONG64__ - -D_DLL -D__USE_CRTIMP) +add_definitions(-D__ROS_LONG64__)
list(APPEND SOURCE asn.c
Modified: trunk/rostests/winetests/wintrust/asn.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/wintrust/asn.c?r... ============================================================================== --- trunk/rostests/winetests/wintrust/asn.c [iso-8859-1] (original) +++ trunk/rostests/winetests/wintrust/asn.c [iso-8859-1] Fri Jul 13 07:43:41 2012 @@ -150,7 +150,7 @@ CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); ok(!ret && (GetLastError() == CRYPT_E_INVALID_IA5_STRING || - GetLastError() == OSS_BAD_PTR /* Win9x */), + GetLastError() == OSS_BAD_PTR /* WinNT */), "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError()); /* Unlike the crypt32 string encoding routines, size is not set to the * index of the first invalid character. @@ -298,7 +298,7 @@ NULL, &buf, &size); ok(!ret && (GetLastError() == CRYPT_E_BAD_ENCODE || - GetLastError() == OSS_DATA_ERROR /* Win9x */), + GetLastError() == OSS_DATA_ERROR /* WinNT */), "Expected CRYPT_E_BAD_ENCODE, got %08x\n", GetLastError()); }
Modified: trunk/rostests/winetests/wintrust/crypt.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/wintrust/crypt.c... ============================================================================== --- trunk/rostests/winetests/wintrust/crypt.c [iso-8859-1] (original) +++ trunk/rostests/winetests/wintrust/crypt.c [iso-8859-1] Fri Jul 13 07:43:41 2012 @@ -115,6 +115,8 @@ static CRYPTCATMEMBER * (WINAPI * pCryptCATEnumerateMember)(HANDLE, CRYPTCATMEMBER *); static CRYPTCATATTRIBUTE * (WINAPI * pCryptCATEnumerateAttr)(HANDLE, CRYPTCATMEMBER *, CRYPTCATATTRIBUTE *); static BOOL (WINAPI * pCryptCATClose)(HANDLE); +static pCryptSIPGetSignedDataMsg pGetSignedDataMsg; +static pCryptSIPPutSignedDataMsg pPutSignedDataMsg;
static void InitFunctionPtrs(void) { @@ -144,6 +146,14 @@ WINTRUST_GET_PROC(CryptCATClose)
#undef WINTRUST_GET_PROC + + pGetSignedDataMsg = (void*)GetProcAddress(hWintrust, "CryptSIPGetSignedDataMsg"); + if(!pGetSignedDataMsg) + trace("GetProcAddress(CryptSIPGetSignedDataMsg) failed\n"); + + pPutSignedDataMsg = (void*)GetProcAddress(hWintrust, "CryptSIPPutSignedDataMsg"); + if(!pPutSignedDataMsg) + trace("GetProcAddress(CryptSIPPutSignedDataMsg) failed\n"); }
static GUID dummy = {0xdeadbeef,0xdead,0xbeef,{0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef}}; @@ -616,6 +626,7 @@ /* Set the attributes so we can delete the file */ attrs = FILE_ATTRIBUTE_NORMAL; ret = SetFileAttributesA(tmpfile, attrs); + ok(ret, "SetFileAttributesA failed %u\n", GetLastError()); DeleteFileA(tmpfile); }
@@ -784,7 +795,7 @@
/* Only enumerate the members */ trace("Only members\n"); - attrcount = membercount = 0; + membercount = 0; catcdf = pCryptCATCDFOpen(cdffileW, NULL);
catmember = NULL; @@ -892,8 +903,7 @@ catcdf = pCryptCATCDFOpen(cdffileW, cdf_callback); ok(catcdf == NULL, "CryptCATCDFOpen succeeded\n"); todo_wine - ok(GetLastError() == ERROR_SHARING_VIOLATION || - broken(GetLastError() == ERROR_SUCCESS), /* win9x */ + ok(GetLastError() == ERROR_SHARING_VIOLATION, "Expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError()); DeleteFileA(cdffileA);
@@ -908,8 +918,7 @@ catcdf = pCryptCATCDFOpen(cdffileW, cdf_callback); ok(catcdf == NULL, "CryptCATCDFOpen succeeded\n"); todo_wine - ok(GetLastError() == ERROR_SHARING_VIOLATION || - broken(GetLastError() == ERROR_SUCCESS), /* win9x */ + ok(GetLastError() == ERROR_SHARING_VIOLATION, "Expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError()); DeleteFileA(cdffileA); ok(!DeleteFileA(catfileA), "Didn't expect a catalog file to be created\n"); @@ -924,8 +933,7 @@ catcdf = pCryptCATCDFOpen(cdffileW, cdf_callback); ok(catcdf == NULL, "CryptCATCDFOpen succeeded\n"); todo_wine - ok(GetLastError() == ERROR_SHARING_VIOLATION || - broken(GetLastError() == ERROR_SUCCESS), /* win9x */ + ok(GetLastError() == ERROR_SHARING_VIOLATION, "Expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError()); DeleteFileA(cdffileA); ok(!DeleteFileA(catfileA), "Didn't expect a catalog file to be created\n"); @@ -1117,6 +1125,162 @@ DeleteFileA(cdffileA); todo_wine ok(DeleteFileA(catfileA), "Expected a catalog file to be created\n"); +} + +static const struct +{ + WORD e_magic; /* 00: MZ Header signature */ + WORD unused[29]; + DWORD e_lfanew; /* 3c: Offset to extended header */ +} dos_header = +{ + IMAGE_DOS_SIGNATURE, { 0 }, sizeof(dos_header) +}; + +static IMAGE_NT_HEADERS nt_header = +{ + IMAGE_NT_SIGNATURE, /* Signature */ + { + IMAGE_FILE_MACHINE_I386, /* Machine */ + 1, /* NumberOfSections */ + 0, /* TimeDateStamp */ + 0, /* PointerToSymbolTable */ + 0, /* NumberOfSymbols */ + sizeof(IMAGE_OPTIONAL_HEADER), /* SizeOfOptionalHeader */ + IMAGE_FILE_EXECUTABLE_IMAGE /* Characteristics */ + }, + { + IMAGE_NT_OPTIONAL_HDR_MAGIC, /* Magic */ + 2, /* MajorLinkerVersion */ + 15, /* MinorLinkerVersion */ + 0, /* SizeOfCode */ + 0, /* SizeOfInitializedData */ + 0, /* SizeOfUninitializedData */ + 0, /* AddressOfEntryPoint */ + 0x10, /* BaseOfCode, also serves as e_lfanew in the truncated MZ header */ +#ifndef _WIN64 + 0, /* BaseOfData */ +#endif + 0x10000000, /* ImageBase */ + 0, /* SectionAlignment */ + 0, /* FileAlignment */ + 4, /* MajorOperatingSystemVersion */ + 0, /* MinorOperatingSystemVersion */ + 1, /* MajorImageVersion */ + 0, /* MinorImageVersion */ + 4, /* MajorSubsystemVersion */ + 0, /* MinorSubsystemVersion */ + 0, /* Win32VersionValue */ + 0x200, /* SizeOfImage */ + sizeof(dos_header) + sizeof(nt_header), /* SizeOfHeaders */ + 0, /* CheckSum */ + IMAGE_SUBSYSTEM_WINDOWS_CUI, /* Subsystem */ + 0, /* DllCharacteristics */ + 0, /* SizeOfStackReserve */ + 0, /* SizeOfStackCommit */ + 0, /* SizeOfHeapReserve */ + 3, /* SizeOfHeapCommit */ + 2, /* LoaderFlags */ + 1, /* NumberOfRvaAndSizes */ + { { 0 } } /* DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] */ + } +}; + +static void test_sip(void) +{ + static WCHAR nameW[] = {'t','e','s','t','.','e','x','e',0}; + SIP_SUBJECTINFO info; + DWORD index, encoding, size; + HANDLE file; + GUID guid; + BOOL ret; + char buf[1024]; + + file = CreateFileW(nameW, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "can't create file\n"); + if(file == INVALID_HANDLE_VALUE) + return; + WriteFile(file, &dos_header, sizeof(dos_header), &size, NULL); + WriteFile(file, &nt_header, sizeof(nt_header), &size, NULL); + memset(buf, 0, sizeof(buf)); + WriteFile(file, buf, 0x200 - sizeof(dos_header) - sizeof(nt_header), &size, NULL); + CloseHandle(file); + + file= CreateFileW(nameW, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "can't open file\n"); + + memset(&info, 0, sizeof(SIP_SUBJECTINFO)); + info.cbSize = sizeof(SIP_SUBJECTINFO); + info.pgSubjectType = &guid; + ret = CryptSIPRetrieveSubjectGuid(NULL, file, info.pgSubjectType); + ok(ret, "CryptSIPRetrieveSubjectGuid failed (%x)\n", GetLastError()); + + ret = pPutSignedDataMsg(&info, X509_ASN_ENCODING, &index, 4, (BYTE*)"test"); + ok(!ret, "CryptSIPPutSignedDataMsg succeedded\n"); + index = GetLastError(); + ok(index == ERROR_PATH_NOT_FOUND, "GetLastError returned %x\n", index); + + info.hFile = file; + info.pwsFileName = nameW; + ret = pPutSignedDataMsg(&info, X509_ASN_ENCODING, &index, 4, (BYTE*)"test"); + ok(!ret, "CryptSIPPutSignedDataMsg succeedded\n"); + index = GetLastError(); + todo_wine ok(index == ERROR_INVALID_PARAMETER, "GetLastError returned %x\n", index); + + info.hFile = INVALID_HANDLE_VALUE; + info.pwsFileName = nameW; + ret = pPutSignedDataMsg(&info, X509_ASN_ENCODING, &index, 4, (BYTE*)"test"); + ok(!ret, "CryptSIPPutSignedDataMsg succeedded\n"); + index = GetLastError(); + ok(index == ERROR_SHARING_VIOLATION, "GetLastError returned %x\n", index); + + CloseHandle(file); + file= CreateFileW(nameW, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + info.hFile = file; + info.pwsFileName = (void*)0xdeadbeef; + ret = pPutSignedDataMsg(&info, X509_ASN_ENCODING, &index, 4, (BYTE*)"test"); + ok(ret, "CryptSIPPutSignedDataMsg failed (%x)\n", GetLastError()); + ok(index == 0, "index = %x\n", index); + + CloseHandle(file); + file= CreateFileW(nameW, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + info.hFile = INVALID_HANDLE_VALUE; + info.pwsFileName = nameW; + ret = pPutSignedDataMsg(&info, X509_ASN_ENCODING, &index, 14, (BYTE*)"longer message"); + ok(ret, "CryptSIPPutSignedDataMsg failed (%x)\n", GetLastError()); + ok(index == 1, "index = %x\n", index); + + size = 0; + encoding = 0xdeadbeef; + ret = pGetSignedDataMsg(&info, &encoding, 0, &size, NULL); + ok(ret, "CryptSIPGetSignedDataMsg failed (%x)\n", GetLastError()); + ok(encoding == 0xdeadbeef, "encoding = %x\n", encoding); + ok(size == 16, "size = %d\n", size); + + ret = pGetSignedDataMsg(&info, &encoding, 0, &size, (BYTE*)buf); + ok(ret, "CryptSIPGetSignedDataMsg failed (%x)\n", GetLastError()); + ok(encoding == (X509_ASN_ENCODING|PKCS_7_ASN_ENCODING), "encoding = %x\n", encoding); + ok(size == 8, "size = %d\n", size); + ok(!memcmp(buf, "test\0\0\0\0", 8), "buf = %s\n", buf); + + size = 0; + encoding = 0xdeadbeef; + ret = pGetSignedDataMsg(&info, &encoding, 1, &size, NULL); + ok(ret, "CryptSIPGetSignedDataMsg failed (%x)\n", GetLastError()); + ok(encoding == 0xdeadbeef, "encoding = %x\n", encoding); + ok(size == 24, "size = %d\n", size); + + ret = pGetSignedDataMsg(&info, &encoding, 1, &size, (BYTE*)buf); + ok(ret, "CryptSIPGetSignedDataMsg failed (%x)\n", GetLastError()); + ok(encoding == (X509_ASN_ENCODING|PKCS_7_ASN_ENCODING), "encoding = %x\n", encoding); + ok(size == 16, "size = %d\n", size); + ok(!strcmp(buf, "longer message"), "buf = %s\n", buf); + + CryptReleaseContext(info.hProv, 0); + CloseHandle(file); + DeleteFileW(nameW); }
START_TEST(crypt) @@ -1153,4 +1317,5 @@ /* Create a catalog file out of our own catalog definition file */ test_create_catalog_file(); test_CryptCATAdminAddRemoveCatalog(); + test_sip(); }
Modified: trunk/rostests/winetests/wintrust/register.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/wintrust/registe... ============================================================================== --- trunk/rostests/winetests/wintrust/register.c [iso-8859-1] (original) +++ trunk/rostests/winetests/wintrust/register.c [iso-8859-1] Fri Jul 13 07:43:41 2012 @@ -299,6 +299,7 @@ ok(ret, "WintrustSetRegPolicyFlags failed: %d\n", GetLastError()); size = sizeof(flags1); r = RegQueryValueExA(key, State, NULL, NULL, (LPBYTE)&flags1, &size); + ok(!r, "RegQueryValueEx failed: %d\n", r); ok(flags1 == flags3, "Got %08x flags instead of %08x\n", flags1, flags3);
pWintrustSetRegPolicyFlags(flags2);
Modified: trunk/rostests/winetests/wintrust/softpub.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/wintrust/softpub... ============================================================================== --- trunk/rostests/winetests/wintrust/softpub.c [iso-8859-1] (original) +++ trunk/rostests/winetests/wintrust/softpub.c [iso-8859-1] Fri Jul 13 07:43:41 2012 @@ -1,7 +1,8 @@ /* * wintrust softpub functions tests * - * Copyright 2007 Juan Lang + * Copyright 2007,2010 Juan Lang + * Copyright 2010 Andrey Turkin * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,9 +18,10 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include <assert.h> + #include <stdio.h> #include <stdarg.h> + #include <windef.h> #include <winbase.h> #include <winerror.h> @@ -74,6 +76,37 @@ struct _CRYPT_PROVUI_FUNCS *psUIpfns; SAFE_PROVIDER_CLEANUP_CALL pfnCleanupPolicy; } SAFE_PROVIDER_FUNCTIONS; + +static BOOL (WINAPI * pWTHelperGetKnownUsages)(DWORD action, PCCRYPT_OID_INFO **usages); +static BOOL (WINAPI * CryptSIPCreateIndirectData_p)(SIP_SUBJECTINFO *, DWORD *, SIP_INDIRECT_DATA *); +static VOID (WINAPI * CertFreeCertificateChain_p)(PCCERT_CHAIN_CONTEXT); + +static void InitFunctionPtrs(void) +{ + HMODULE hWintrust = GetModuleHandleA("wintrust.dll"); + HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll"); + +#define WINTRUST_GET_PROC(func) \ + p ## func = (void*)GetProcAddress(hWintrust, #func); \ + if(!p ## func) { \ + trace("GetProcAddress(%s) failed\n", #func); \ + } + + WINTRUST_GET_PROC(WTHelperGetKnownUsages) + +#undef WINTRUST_GET_PROC + +#define CRYPT32_GET_PROC(func) \ + func ## _p = (void*)GetProcAddress(hCrypt32, #func); \ + if(!func ## _p) { \ + trace("GetProcAddress(%s) failed\n", #func); \ + } + + CRYPT32_GET_PROC(CryptSIPCreateIndirectData) + CRYPT32_GET_PROC(CertFreeCertificateChain) + +#undef CRYPT32_GET_PROC +}
static const BYTE v1CertWithPubKey[] = { 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, @@ -244,6 +277,25 @@ MultiByteToWideChar(0, 0, notepadPath, -1, notepadPathW, size); }
+/* Creates a test file and returns a handle to it. The file's path is returned + * in temp_file, which must be at least MAX_PATH characters in length. + */ +static HANDLE create_temp_file(WCHAR *temp_file) +{ + HANDLE file = INVALID_HANDLE_VALUE; + WCHAR temp_path[MAX_PATH]; + + if (GetTempPathW(sizeof(temp_path) / sizeof(temp_path[0]), temp_path)) + { + static const WCHAR img[] = { 'i','m','g',0 }; + + if (GetTempFileNameW(temp_path, img, 0, temp_file)) + file = CreateFileW(temp_file, GENERIC_READ | GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + } + return file; +} + static void testObjTrust(SAFE_PROVIDER_FUNCTIONS *funcs, GUID *actionID) { HRESULT ret; @@ -266,7 +318,7 @@ funcs->pfnAlloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD)); if (data.padwTrustStepErrors) { - WCHAR notepadPathW[MAX_PATH]; + WCHAR pathW[MAX_PATH]; PROVDATA_SIP provDataSIP = { 0 }; static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47, 0x00,0xC0,0x4F,0xC2,0x95,0xEE } }; @@ -301,11 +353,31 @@ /* Crashes ret = funcs->pfnObjectTrust(&data); */ - getNotepadPath(notepadPathW, MAX_PATH); - fileInfo.pcwszFilePath = notepadPathW; + /* Create and test with an empty file */ + fileInfo.hFile = create_temp_file(pathW); /* pfnObjectTrust now crashes unless both pPDSip and psPfns are set */ U(data).pPDSip = &provDataSIP; data.psPfns = (CRYPT_PROVIDER_FUNCTIONS *)funcs; + ret = funcs->pfnObjectTrust(&data); + ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret); + ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] == + TRUST_E_SUBJECT_FORM_UNKNOWN, + "expected TRUST_E_SUBJECT_FORM_UNKNOWN, got %08x\n", + data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]); + CloseHandle(fileInfo.hFile); + fileInfo.hFile = NULL; + fileInfo.pcwszFilePath = pathW; + ret = funcs->pfnObjectTrust(&data); + ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret); + ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] == + TRUST_E_SUBJECT_FORM_UNKNOWN, + "expected TRUST_E_SUBJECT_FORM_UNKNOWN, got %08x\n", + data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]); + DeleteFileW(pathW); + /* Test again with a file we expect to exist, and to contain no + * signature. + */ + getNotepadPath(pathW, MAX_PATH); ret = funcs->pfnObjectTrust(&data); ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret); ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] == @@ -346,6 +418,7 @@ { fileInfo.pgKnownSubject = (GUID *)0xdeadbeef; ret = funcs->pfnObjectTrust(&data); + ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret); } funcs->pfnFree(data.padwTrustStepErrors); } @@ -382,6 +455,12 @@ CRYPT_PROVIDER_SGNR sgnr = { sizeof(sgnr), { 0 } }; HRESULT ret;
+ if (!CertFreeCertificateChain_p) + { + win_skip("CertFreeCertificateChain not found\n"); + return; + } + data.padwTrustStepErrors = funcs->pfnAlloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD)); if (!data.padwTrustStepErrors) @@ -409,6 +488,8 @@ WINTRUST_DATA wintrust_data = { 0 };
ret = funcs->pfnAddCert2Chain(&data, 0, FALSE, 0, cert); + ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret); + /* If pWintrustData isn't set, crashes attempting to access * pWintrustData->fdwRevocationChecks */ @@ -439,10 +520,11 @@ data.pasSigners[0].pasCertChain[0].dwConfidence); CertFreeCertificateContext( data.pasSigners[0].pasCertChain[0].pCert); - CertFreeCertificateChain(data.pasSigners[0].pChainContext); + CertFreeCertificateChain_p(data.pasSigners[0].pChainContext); CertFreeCertificateContext(cert); } } + funcs->pfnFree(data.padwTrustStepErrors); }
static void test_provider_funcs(void) @@ -464,6 +546,195 @@ } }
+/* minimal PE file image */ +#define VA_START 0x400000 +#define FILE_PE_START 0x50 +#define NUM_SECTIONS 3 +#define FILE_TEXT 0x200 +#define RVA_TEXT 0x1000 +#define RVA_BSS 0x2000 +#define FILE_IDATA 0x400 +#define RVA_IDATA 0x3000 +#define FILE_TOTAL 0x600 +#define RVA_TOTAL 0x4000 +#include <pshpack1.h> +struct Imports { + IMAGE_IMPORT_DESCRIPTOR descriptors[2]; + IMAGE_THUNK_DATA32 original_thunks[2]; + IMAGE_THUNK_DATA32 thunks[2]; + struct __IMPORT_BY_NAME { + WORD hint; + char funcname[0x20]; + } ibn; + char dllname[0x10]; +}; +#define EXIT_PROCESS (VA_START+RVA_IDATA+FIELD_OFFSET(struct Imports, thunks)) + +static struct _PeImage { + IMAGE_DOS_HEADER dos_header; + char __alignment1[FILE_PE_START - sizeof(IMAGE_DOS_HEADER)]; + IMAGE_NT_HEADERS32 nt_headers; + IMAGE_SECTION_HEADER sections[NUM_SECTIONS]; + char __alignment2[FILE_TEXT - FILE_PE_START - sizeof(IMAGE_NT_HEADERS32) - + NUM_SECTIONS * sizeof(IMAGE_SECTION_HEADER)]; + unsigned char text_section[FILE_IDATA-FILE_TEXT]; + struct Imports idata_section; + char __alignment3[FILE_TOTAL-FILE_IDATA-sizeof(struct Imports)]; +} bin = { + /* dos header */ + {IMAGE_DOS_SIGNATURE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, 0, {0}, FILE_PE_START}, + /* alignment before PE header */ + {0}, + /* nt headers */ + {IMAGE_NT_SIGNATURE, + /* basic headers - 3 sections, no symbols, EXE file */ + {IMAGE_FILE_MACHINE_I386, NUM_SECTIONS, 0, 0, 0, sizeof(IMAGE_OPTIONAL_HEADER32), + IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_EXECUTABLE_IMAGE}, + /* optional header */ + {IMAGE_NT_OPTIONAL_HDR32_MAGIC, 4, 0, FILE_IDATA-FILE_TEXT, + FILE_TOTAL-FILE_IDATA + FILE_IDATA-FILE_TEXT, 0x400, + RVA_TEXT, RVA_TEXT, RVA_BSS, VA_START, 0x1000, 0x200, 4, 0, 1, 0, 4, 0, 0, + RVA_TOTAL, FILE_TEXT, 0, IMAGE_SUBSYSTEM_WINDOWS_GUI, 0, + 0x200000, 0x1000, 0x100000, 0x1000, 0, 0x10, + {{0, 0}, + {RVA_IDATA, sizeof(struct Imports)} + } + } + }, + /* sections */ + { + {".text", {0x100}, RVA_TEXT, FILE_IDATA-FILE_TEXT, FILE_TEXT, + 0, 0, 0, 0, IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ}, + {".bss", {0x400}, RVA_BSS, 0, 0, 0, 0, 0, 0, + IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE}, + {".idata", {sizeof(struct Imports)}, RVA_IDATA, FILE_TOTAL-FILE_IDATA, FILE_IDATA, 0, + 0, 0, 0, IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE} + }, + /* alignment before first section */ + {0}, + /* .text section */ + { + 0x31, 0xC0, /* xor eax, eax */ + 0xFF, 0x25, EXIT_PROCESS&0xFF, (EXIT_PROCESS>>8)&0xFF, (EXIT_PROCESS>>16)&0xFF, + (EXIT_PROCESS>>24)&0xFF, /* jmp ExitProcess */ + 0 + }, + /* .idata section */ + { + { + {{RVA_IDATA + FIELD_OFFSET(struct Imports, original_thunks)}, 0, 0, + RVA_IDATA + FIELD_OFFSET(struct Imports, dllname), + RVA_IDATA + FIELD_OFFSET(struct Imports, thunks) + }, + {{0}, 0, 0, 0, 0} + }, + {{{RVA_IDATA+FIELD_OFFSET(struct Imports, ibn)}}, {{0}}}, + {{{RVA_IDATA+FIELD_OFFSET(struct Imports, ibn)}}, {{0}}}, + {0,"ExitProcess"}, + "KERNEL32.DLL" + }, + /* final alignment */ + {0} +}; +#include <poppack.h> + +static void test_sip_create_indirect_data(void) +{ + static GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47, + 0x00,0xC0,0x4F,0xC2,0x95,0xEE } }; + static char oid_sha1[] = szOID_OIWSEC_sha1; + BOOL ret; + SIP_SUBJECTINFO subjinfo = { 0 }; + WCHAR temp_file[MAX_PATH]; + HANDLE file; + DWORD count; + + if (!CryptSIPCreateIndirectData_p) + { + skip("Missing CryptSIPCreateIndirectData\n"); + return; + } + SetLastError(0xdeadbeef); + ret = CryptSIPCreateIndirectData_p(NULL, NULL, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + SetLastError(0xdeadbeef); + ret = CryptSIPCreateIndirectData_p(&subjinfo, NULL, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + subjinfo.cbSize = sizeof(subjinfo); + SetLastError(0xdeadbeef); + ret = CryptSIPCreateIndirectData_p(&subjinfo, NULL, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + file = create_temp_file(temp_file); + if (file == INVALID_HANDLE_VALUE) + { + skip("couldn't create temp file\n"); + return; + } + WriteFile(file, &bin, sizeof(bin), &count, NULL); + FlushFileBuffers(file); + + subjinfo.hFile = file; + SetLastError(0xdeadbeef); + ret = CryptSIPCreateIndirectData_p(&subjinfo, NULL, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + subjinfo.pgSubjectType = &unknown; + SetLastError(0xdeadbeef); + ret = CryptSIPCreateIndirectData_p(&subjinfo, NULL, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + count = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = CryptSIPCreateIndirectData_p(&subjinfo, &count, NULL); + todo_wine + ok(!ret && (GetLastError() == NTE_BAD_ALGID || + GetLastError() == ERROR_INVALID_PARAMETER /* Win7 */), + "expected NTE_BAD_ALGID or ERROR_INVALID_PARAMETER, got %08x\n", + GetLastError()); + ok(count == 0xdeadbeef, "expected count to be unmodified, got %d\n", count); + subjinfo.DigestAlgorithm.pszObjId = oid_sha1; + count = 0xdeadbeef; + ret = CryptSIPCreateIndirectData_p(&subjinfo, &count, NULL); + todo_wine + ok(ret, "CryptSIPCreateIndirectData failed: %d\n", GetLastError()); + ok(count, "expected a positive count\n"); + if (ret) + { + SIP_INDIRECT_DATA *indirect = HeapAlloc(GetProcessHeap(), 0, count); + + count = 256; + ret = CryptSIPCreateIndirectData_p(&subjinfo, &count, indirect); + ok(ret, "CryptSIPCreateIndirectData failed: %d\n", GetLastError()); + /* If the count is larger than needed, it's unmodified */ + ok(count == 256, "unexpected count %d\n", count); + ok(!strcmp(indirect->Data.pszObjId, SPC_PE_IMAGE_DATA_OBJID), + "unexpected data oid %s\n", + indirect->Data.pszObjId); + ok(!strcmp(indirect->DigestAlgorithm.pszObjId, oid_sha1), + "unexpected digest algorithm oid %s\n", + indirect->DigestAlgorithm.pszObjId); + ok(indirect->Digest.cbData == 20, "unexpected hash size %d\n", + indirect->Digest.cbData); + if (indirect->Digest.cbData == 20) + { + const BYTE hash[20] = { + 0x8a,0xd5,0x45,0x53,0x3d,0x67,0xdf,0x2f,0x78,0xe0, + 0x55,0x0a,0xe0,0xd9,0x7a,0x28,0x3e,0xbf,0x45,0x2b }; + + ok(!memcmp(indirect->Digest.pbData, hash, 20), + "unexpected value\n"); + } + + HeapFree(GetProcessHeap(), 0, indirect); + } + CloseHandle(file); + DeleteFileW(temp_file); +} + static void test_wintrust(void) { static GUID generic_action_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2; @@ -471,7 +742,7 @@ WINTRUST_FILE_INFO file; LONG r; HRESULT hr; - WCHAR notepadPathW[MAX_PATH]; + WCHAR pathW[MAX_PATH];
memset(&wtd, 0, sizeof(wtd)); wtd.cbStruct = sizeof(wtd); @@ -482,31 +753,30 @@ wtd.dwStateAction = WTD_STATEACTION_VERIFY; memset(&file, 0, sizeof(file)); file.cbStruct = sizeof(file); - getNotepadPath(notepadPathW, MAX_PATH); - file.pcwszFilePath = notepadPathW; + file.pcwszFilePath = pathW; + /* Test with an empty file */ + file.hFile = create_temp_file(pathW); + r = WinVerifyTrust(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd); + ok(r == TRUST_E_SUBJECT_FORM_UNKNOWN, + "expected TRUST_E_SUBJECT_FORM_UNKNOWN, got %08x\n", r); + CloseHandle(file.hFile); + DeleteFileW(pathW); + file.hFile = NULL; + /* Test with a known file path, which we expect not have a signature */ + getNotepadPath(pathW, MAX_PATH); r = WinVerifyTrust(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd); ok(r == TRUST_E_NOSIGNATURE || r == CRYPT_E_FILE_ERROR, "expected TRUST_E_NOSIGNATURE or CRYPT_E_FILE_ERROR, got %08x\n", r); + wtd.dwStateAction = WTD_STATEACTION_CLOSE; + r = WinVerifyTrust(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd); + ok(r == S_OK, "WinVerifyTrust failed: %08x\n", r); + wtd.dwStateAction = WTD_STATEACTION_VERIFY; hr = WinVerifyTrustEx(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd); - ok(hr == TRUST_E_NOSIGNATURE || r == CRYPT_E_FILE_ERROR, + ok(hr == TRUST_E_NOSIGNATURE || hr == CRYPT_E_FILE_ERROR, "expected TRUST_E_NOSIGNATURE or CRYPT_E_FILE_ERROR, got %08x\n", hr); -} - -static BOOL (WINAPI * pWTHelperGetKnownUsages)(DWORD action, PCCRYPT_OID_INFO **usages); - -static void InitFunctionPtrs(void) -{ - HMODULE hWintrust = GetModuleHandleA("wintrust.dll"); - -#define WINTRUST_GET_PROC(func) \ - p ## func = (void*)GetProcAddress(hWintrust, #func); \ - if(!p ## func) { \ - trace("GetProcAddress(%s) failed\n", #func); \ - } - - WINTRUST_GET_PROC(WTHelperGetKnownUsages) - -#undef WINTRUST_GET_PROC + wtd.dwStateAction = WTD_STATEACTION_CLOSE; + r = WinVerifyTrust(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd); + ok(r == S_OK, "WinVerifyTrust failed: %08x\n", r); }
static void test_get_known_usages(void) @@ -577,6 +847,7 @@ { InitFunctionPtrs(); test_provider_funcs(); + test_sip_create_indirect_data(); test_wintrust(); test_get_known_usages(); }