regedit: Check if any hex data exists before attempting to parse it.
[wine.git] / dlls / wintrust / tests / softpub.c
blob6e7913f710c01fa00449481a012356d4db5303ee
1 /*
2 * wintrust softpub functions tests
4 * Copyright 2007,2010 Juan Lang
5 * Copyright 2010 Andrey Turkin
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdio.h>
23 #include <stdarg.h>
25 #include <windef.h>
26 #include <winbase.h>
27 #include <winerror.h>
28 #include <wintrust.h>
29 #include <softpub.h>
30 #include <mssip.h>
31 #include <winuser.h>
32 #include "winnls.h"
34 #include "wine/test.h"
36 /* Just in case we're being built with borked headers, redefine function
37 * pointers to have the correct calling convention.
39 typedef void *(WINAPI *SAFE_MEM_ALLOC)(DWORD);
40 typedef void (WINAPI *SAFE_MEM_FREE)(void *);
41 typedef BOOL (WINAPI *SAFE_ADD_STORE)(CRYPT_PROVIDER_DATA *,
42 HCERTSTORE);
43 typedef BOOL (WINAPI *SAFE_ADD_SGNR)(CRYPT_PROVIDER_DATA *,
44 BOOL, DWORD, struct _CRYPT_PROVIDER_SGNR *);
45 typedef BOOL (WINAPI *SAFE_ADD_CERT)(CRYPT_PROVIDER_DATA *,
46 DWORD, BOOL, DWORD, PCCERT_CONTEXT);
47 typedef BOOL (WINAPI *SAFE_ADD_PRIVDATA)(CRYPT_PROVIDER_DATA *,
48 CRYPT_PROVIDER_PRIVDATA *);
49 typedef HRESULT (WINAPI *SAFE_PROVIDER_INIT_CALL)(CRYPT_PROVIDER_DATA *);
50 typedef HRESULT (WINAPI *SAFE_PROVIDER_OBJTRUST_CALL)(CRYPT_PROVIDER_DATA *);
51 typedef HRESULT (WINAPI *SAFE_PROVIDER_SIGTRUST_CALL)(CRYPT_PROVIDER_DATA *);
52 typedef HRESULT (WINAPI *SAFE_PROVIDER_CERTTRUST_CALL)(CRYPT_PROVIDER_DATA *);
53 typedef HRESULT (WINAPI *SAFE_PROVIDER_FINALPOLICY_CALL)(CRYPT_PROVIDER_DATA *);
54 typedef HRESULT (WINAPI *SAFE_PROVIDER_TESTFINALPOLICY_CALL)(
55 CRYPT_PROVIDER_DATA *);
56 typedef HRESULT (WINAPI *SAFE_PROVIDER_CLEANUP_CALL)(CRYPT_PROVIDER_DATA *);
57 typedef BOOL (WINAPI *SAFE_PROVIDER_CERTCHKPOLICY_CALL)(
58 CRYPT_PROVIDER_DATA *, DWORD, BOOL, DWORD);
60 typedef struct _SAFE_PROVIDER_FUNCTIONS
62 DWORD cbStruct;
63 SAFE_MEM_ALLOC pfnAlloc;
64 SAFE_MEM_FREE pfnFree;
65 SAFE_ADD_STORE pfnAddStore2Chain;
66 SAFE_ADD_SGNR pfnAddSgnr2Chain;
67 SAFE_ADD_CERT pfnAddCert2Chain;
68 SAFE_ADD_PRIVDATA pfnAddPrivData2Chain;
69 SAFE_PROVIDER_INIT_CALL pfnInitialize;
70 SAFE_PROVIDER_OBJTRUST_CALL pfnObjectTrust;
71 SAFE_PROVIDER_SIGTRUST_CALL pfnSignatureTrust;
72 SAFE_PROVIDER_CERTTRUST_CALL pfnCertificateTrust;
73 SAFE_PROVIDER_FINALPOLICY_CALL pfnFinalPolicy;
74 SAFE_PROVIDER_CERTCHKPOLICY_CALL pfnCertCheckPolicy;
75 SAFE_PROVIDER_TESTFINALPOLICY_CALL pfnTestFinalPolicy;
76 struct _CRYPT_PROVUI_FUNCS *psUIpfns;
77 SAFE_PROVIDER_CLEANUP_CALL pfnCleanupPolicy;
78 } SAFE_PROVIDER_FUNCTIONS;
80 static BOOL (WINAPI * pWTHelperGetKnownUsages)(DWORD action, PCCRYPT_OID_INFO **usages);
81 static BOOL (WINAPI * CryptSIPCreateIndirectData_p)(SIP_SUBJECTINFO *, DWORD *, SIP_INDIRECT_DATA *);
82 static VOID (WINAPI * CertFreeCertificateChain_p)(PCCERT_CHAIN_CONTEXT);
84 static void InitFunctionPtrs(void)
86 HMODULE hWintrust = GetModuleHandleA("wintrust.dll");
87 HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll");
89 #define WINTRUST_GET_PROC(func) \
90 p ## func = (void*)GetProcAddress(hWintrust, #func); \
91 if(!p ## func) { \
92 trace("GetProcAddress(%s) failed\n", #func); \
95 WINTRUST_GET_PROC(WTHelperGetKnownUsages)
97 #undef WINTRUST_GET_PROC
99 #define CRYPT32_GET_PROC(func) \
100 func ## _p = (void*)GetProcAddress(hCrypt32, #func); \
101 if(!func ## _p) { \
102 trace("GetProcAddress(%s) failed\n", #func); \
105 CRYPT32_GET_PROC(CryptSIPCreateIndirectData)
106 CRYPT32_GET_PROC(CertFreeCertificateChain)
108 #undef CRYPT32_GET_PROC
111 static const BYTE v1CertWithPubKey[] = {
112 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
113 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
114 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
115 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
116 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
117 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
118 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
119 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
120 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
121 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
122 0x01,0x01 };
124 static void test_utils(SAFE_PROVIDER_FUNCTIONS *funcs)
126 CRYPT_PROVIDER_DATA data = { 0 };
127 HCERTSTORE store;
128 CRYPT_PROVIDER_SGNR sgnr = { 0 };
129 BOOL ret;
131 /* Crash
132 ret = funcs->pfnAddStore2Chain(NULL, NULL);
133 ret = funcs->pfnAddStore2Chain(&data, NULL);
135 store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
136 CERT_STORE_CREATE_NEW_FLAG, NULL);
137 if (store)
139 ret = funcs->pfnAddStore2Chain(&data, store);
140 ok(ret, "pfnAddStore2Chain failed: %08x\n", GetLastError());
141 ok(data.chStores == 1, "Expected 1 store, got %d\n", data.chStores);
142 ok(data.pahStores != NULL, "Expected pahStores to be allocated\n");
143 if (data.pahStores)
145 ok(data.pahStores[0] == store, "Unexpected store\n");
146 CertCloseStore(data.pahStores[0], 0);
147 funcs->pfnFree(data.pahStores);
148 data.pahStores = NULL;
149 data.chStores = 0;
150 CertCloseStore(store, 0);
151 store = NULL;
154 else
155 skip("CertOpenStore failed: %08x\n", GetLastError());
157 /* Crash
158 ret = funcs->pfnAddSgnr2Chain(NULL, FALSE, 0, NULL);
159 ret = funcs->pfnAddSgnr2Chain(&data, FALSE, 0, NULL);
161 ret = funcs->pfnAddSgnr2Chain(&data, FALSE, 0, &sgnr);
162 ok(ret, "pfnAddSgnr2Chain failed: %08x\n", GetLastError());
163 ok(data.csSigners == 1, "Expected 1 signer, got %d\n", data.csSigners);
164 ok(data.pasSigners != NULL, "Expected pasSigners to be allocated\n");
165 if (data.pasSigners)
167 PCCERT_CONTEXT cert;
169 ok(!memcmp(&data.pasSigners[0], &sgnr, sizeof(sgnr)),
170 "Unexpected data in signer\n");
171 /* Adds into the location specified by the index */
172 sgnr.cbStruct = sizeof(CRYPT_PROVIDER_SGNR);
173 sgnr.sftVerifyAsOf.dwLowDateTime = 0xdeadbeef;
174 ret = funcs->pfnAddSgnr2Chain(&data, FALSE, 1, &sgnr);
175 ok(ret, "pfnAddSgnr2Chain failed: %08x\n", GetLastError());
176 ok(data.csSigners == 2, "Expected 2 signers, got %d\n", data.csSigners);
177 ok(!memcmp(&data.pasSigners[1], &sgnr, sizeof(sgnr)),
178 "Unexpected data in signer\n");
179 /* This also adds, but the index is ignored */
180 sgnr.cbStruct = sizeof(DWORD);
181 ret = funcs->pfnAddSgnr2Chain(&data, FALSE, 0, &sgnr);
182 ok(ret, "pfnAddSgnr2Chain failed: %08x\n", GetLastError());
183 ok(data.csSigners == 3, "Expected 3 signers, got %d\n", data.csSigners);
184 sgnr.sftVerifyAsOf.dwLowDateTime = 0;
185 todo_wine
186 ok(!memcmp(&data.pasSigners[2], &sgnr, sizeof(sgnr)),
187 "Unexpected data in signer\n");
188 /* But too large a thing isn't added */
189 sgnr.cbStruct = sizeof(sgnr) + sizeof(DWORD);
190 SetLastError(0xdeadbeef);
191 ret = funcs->pfnAddSgnr2Chain(&data, FALSE, 0, &sgnr);
192 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
193 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
195 /* Crash
196 ret = funcs->pfnAddCert2Chain(NULL, 0, FALSE, 0, NULL);
197 ret = funcs->pfnAddCert2Chain(&data, 0, FALSE, 0, NULL);
199 cert = CertCreateCertificateContext(X509_ASN_ENCODING, v1CertWithPubKey,
200 sizeof(v1CertWithPubKey));
201 if (cert)
203 /* Notes on behavior that are hard to test:
204 * 1. If pasSigners is invalid, pfnAddCert2Chain crashes
205 * 2. An invalid signer index isn't checked.
207 ret = funcs->pfnAddCert2Chain(&data, 0, FALSE, 0, cert);
208 ok(ret, "pfnAddCert2Chain failed: %08x\n", GetLastError());
209 ok(data.pasSigners[0].csCertChain == 1, "Expected 1 cert, got %d\n",
210 data.pasSigners[0].csCertChain);
211 ok(data.pasSigners[0].pasCertChain != NULL,
212 "Expected pasCertChain to be allocated\n");
213 if (data.pasSigners[0].pasCertChain)
215 ok(data.pasSigners[0].pasCertChain[0].pCert == cert,
216 "Unexpected cert\n");
217 CertFreeCertificateContext(
218 data.pasSigners[0].pasCertChain[0].pCert);
220 CertFreeCertificateContext(cert);
222 else
223 skip("CertCreateCertificateContext failed: %08x\n", GetLastError());
224 funcs->pfnFree(data.pasSigners);
228 static void testInitialize(SAFE_PROVIDER_FUNCTIONS *funcs, GUID *actionID)
230 HRESULT ret;
231 CRYPT_PROVIDER_DATA data = { 0 };
232 WINTRUST_DATA wintrust_data = { 0 };
234 if (!funcs->pfnInitialize)
236 skip("missing pfnInitialize\n");
237 return;
240 /* Crashes
241 ret = funcs->pfnInitialize(NULL);
243 memset(&data, 0, sizeof(data));
244 ret = funcs->pfnInitialize(&data);
245 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
246 data.padwTrustStepErrors =
247 funcs->pfnAlloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
248 /* Without wintrust data set, crashes when padwTrustStepErrors is set */
249 data.pWintrustData = &wintrust_data;
250 if (data.padwTrustStepErrors)
252 /* Apparently, cdwTrustStepErrors does not need to be set. */
253 memset(data.padwTrustStepErrors, 0,
254 TRUSTERROR_MAX_STEPS * sizeof(DWORD));
255 ret = funcs->pfnInitialize(&data);
256 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
257 data.cdwTrustStepErrors = 1;
258 ret = funcs->pfnInitialize(&data);
259 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
260 memset(data.padwTrustStepErrors, 0xba,
261 TRUSTERROR_MAX_STEPS * sizeof(DWORD));
262 ret = funcs->pfnInitialize(&data);
263 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
264 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT] = 0;
265 ret = funcs->pfnInitialize(&data);
266 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
267 funcs->pfnFree(data.padwTrustStepErrors);
271 static void getNotepadPath(WCHAR *notepadPathW, DWORD size)
273 static const CHAR notepad[] = "\\notepad.exe";
274 CHAR notepadPath[MAX_PATH];
276 /* Workaround missing W-functions for win9x */
277 GetWindowsDirectoryA(notepadPath, MAX_PATH);
278 lstrcatA(notepadPath, notepad);
279 MultiByteToWideChar(CP_ACP, 0, notepadPath, -1, notepadPathW, size);
282 /* Creates a test file and returns a handle to it. The file's path is returned
283 * in temp_file, which must be at least MAX_PATH characters in length.
285 static HANDLE create_temp_file(WCHAR *temp_file)
287 HANDLE file = INVALID_HANDLE_VALUE;
288 WCHAR temp_path[MAX_PATH];
290 if (GetTempPathW(sizeof(temp_path) / sizeof(temp_path[0]), temp_path))
292 static const WCHAR img[] = { 'i','m','g',0 };
294 if (GetTempFileNameW(temp_path, img, 0, temp_file))
295 file = CreateFileW(temp_file, GENERIC_READ | GENERIC_WRITE, 0, NULL,
296 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
298 return file;
301 static void testObjTrust(SAFE_PROVIDER_FUNCTIONS *funcs, GUID *actionID)
303 HRESULT ret;
304 CRYPT_PROVIDER_DATA data = { 0 };
305 CRYPT_PROVIDER_SIGSTATE sig_state = { 0 };
306 WINTRUST_DATA wintrust_data = { 0 };
307 WINTRUST_CERT_INFO certInfo = { sizeof(WINTRUST_CERT_INFO), 0 };
308 WINTRUST_FILE_INFO fileInfo = { sizeof(WINTRUST_FILE_INFO), 0 };
310 if (!funcs->pfnObjectTrust)
312 skip("missing pfnObjectTrust\n");
313 return;
316 /* Crashes
317 ret = funcs->pfnObjectTrust(NULL);
319 data.pSigState = &sig_state;
320 data.pWintrustData = &wintrust_data;
321 data.padwTrustStepErrors =
322 funcs->pfnAlloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
323 if (data.padwTrustStepErrors)
325 WCHAR pathW[MAX_PATH];
326 PROVDATA_SIP provDataSIP = { 0 };
327 static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
328 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
329 static GUID bogusGuid = { 0xdeadbeef, 0xbaad, 0xf00d, { 0x00,0x00,0x00,
330 0x00,0x00,0x00,0x00,0x00 } };
332 ret = funcs->pfnObjectTrust(&data);
333 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
334 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
335 ERROR_INVALID_PARAMETER,
336 "Expected ERROR_INVALID_PARAMETER, got %08x\n",
337 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
338 U(wintrust_data).pCert = &certInfo;
339 wintrust_data.dwUnionChoice = WTD_CHOICE_CERT;
340 ret = funcs->pfnObjectTrust(&data);
341 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
342 certInfo.psCertContext = (PCERT_CONTEXT)CertCreateCertificateContext(
343 X509_ASN_ENCODING, v1CertWithPubKey, sizeof(v1CertWithPubKey));
344 ret = funcs->pfnObjectTrust(&data);
345 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
346 CertFreeCertificateContext(certInfo.psCertContext);
347 certInfo.psCertContext = NULL;
348 wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
349 U(wintrust_data).pFile = NULL;
350 ret = funcs->pfnObjectTrust(&data);
351 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
352 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
353 ERROR_INVALID_PARAMETER,
354 "Expected ERROR_INVALID_PARAMETER, got %08x\n",
355 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
356 U(wintrust_data).pFile = &fileInfo;
357 /* Crashes
358 ret = funcs->pfnObjectTrust(&data);
360 /* Create and test with an empty file */
361 fileInfo.hFile = create_temp_file(pathW);
362 /* pfnObjectTrust now crashes unless both pPDSip and psPfns are set */
363 U(data).pPDSip = &provDataSIP;
364 data.psPfns = (CRYPT_PROVIDER_FUNCTIONS *)funcs;
365 ret = funcs->pfnObjectTrust(&data);
366 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
367 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
368 TRUST_E_SUBJECT_FORM_UNKNOWN,
369 "expected TRUST_E_SUBJECT_FORM_UNKNOWN, got %08x\n",
370 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
371 CloseHandle(fileInfo.hFile);
372 fileInfo.hFile = NULL;
373 fileInfo.pcwszFilePath = pathW;
374 ret = funcs->pfnObjectTrust(&data);
375 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
376 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
377 TRUST_E_SUBJECT_FORM_UNKNOWN,
378 "expected TRUST_E_SUBJECT_FORM_UNKNOWN, got %08x\n",
379 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
380 DeleteFileW(pathW);
381 /* Test again with a file we expect to exist, and to contain no
382 * signature.
384 getNotepadPath(pathW, MAX_PATH);
385 ret = funcs->pfnObjectTrust(&data);
386 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
387 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
388 TRUST_E_NOSIGNATURE ||
389 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
390 TRUST_E_SUBJECT_FORM_UNKNOWN,
391 "Expected TRUST_E_NOSIGNATURE or TRUST_E_SUBJECT_FORM_UNKNOWN, got %08x\n",
392 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
393 if (data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
394 TRUST_E_NOSIGNATURE)
396 ok(!memcmp(&provDataSIP.gSubject, &unknown, sizeof(unknown)),
397 "Unexpected subject GUID\n");
398 ok(provDataSIP.pSip != NULL, "Expected a SIP\n");
399 ok(provDataSIP.psSipSubjectInfo != NULL,
400 "Expected a subject info\n");
402 /* Specifying the GUID results in that GUID being the subject GUID */
403 fileInfo.pgKnownSubject = &bogusGuid;
404 ret = funcs->pfnObjectTrust(&data);
405 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
406 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
407 TRUST_E_NOSIGNATURE ||
408 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
409 TRUST_E_SUBJECT_FORM_UNKNOWN ||
410 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
411 TRUST_E_PROVIDER_UNKNOWN,
412 "Expected TRUST_E_NOSIGNATURE or TRUST_E_SUBJECT_FORM_UNKNOWN or TRUST_E_PROVIDER_UNKNOWN, got %08x\n",
413 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
414 if (data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
415 TRUST_E_NOSIGNATURE)
417 ok(!memcmp(&provDataSIP.gSubject, &bogusGuid, sizeof(bogusGuid)),
418 "unexpected subject GUID\n");
420 /* Specifying a bogus GUID pointer crashes */
421 if (0)
423 fileInfo.pgKnownSubject = (GUID *)0xdeadbeef;
424 ret = funcs->pfnObjectTrust(&data);
425 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
427 funcs->pfnFree(data.padwTrustStepErrors);
431 static const BYTE selfSignedCert[] = {
432 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
433 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
434 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x70, 0x7a, 0x43, 0x43,
435 0x41, 0x6f, 0x2b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4a,
436 0x41, 0x4c, 0x59, 0x51, 0x67, 0x65, 0x66, 0x7a, 0x51, 0x41, 0x61, 0x43,
437 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
438 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x4d, 0x47, 0x6f, 0x78,
439 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41, 0x59,
440 0x54, 0x41, 0x6b, 0x46, 0x56, 0x4d, 0x52, 0x4d, 0x77, 0x45, 0x51, 0x59,
441 0x44, 0x56, 0x51, 0x51, 0x49, 0x44, 0x41, 0x70, 0x54, 0x62, 0x32, 0x31,
442 0x6c, 0x4c, 0x56, 0x4e, 0x30, 0x59, 0x58, 0x52, 0x6c, 0x4d, 0x53, 0x45,
443 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x42, 0x68,
444 0x4a, 0x62, 0x6e, 0x52, 0x6c, 0x63, 0x6d, 0x35, 0x6c, 0x64, 0x43, 0x42,
445 0x58, 0x0a, 0x61, 0x57, 0x52, 0x6e, 0x61, 0x58, 0x52, 0x7a, 0x49, 0x46,
446 0x42, 0x30, 0x65, 0x53, 0x42, 0x4d, 0x64, 0x47, 0x51, 0x78, 0x49, 0x7a,
447 0x41, 0x68, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x4d, 0x47, 0x6e,
448 0x4e, 0x6c, 0x62, 0x47, 0x5a, 0x7a, 0x61, 0x57, 0x64, 0x75, 0x5a, 0x57,
449 0x51, 0x75, 0x64, 0x47, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x33, 0x61, 0x57,
450 0x35, 0x6c, 0x61, 0x48, 0x45, 0x75, 0x0a, 0x62, 0x33, 0x4a, 0x6e, 0x4d,
451 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x7a, 0x4d, 0x44, 0x59, 0x79, 0x4d,
452 0x54, 0x45, 0x78, 0x4d, 0x6a, 0x55, 0x78, 0x4d, 0x46, 0x6f, 0x58, 0x44,
453 0x54, 0x49, 0x7a, 0x4d, 0x44, 0x59, 0x78, 0x4f, 0x54, 0x45, 0x78, 0x4d,
454 0x6a, 0x55, 0x78, 0x4d, 0x46, 0x6f, 0x77, 0x61, 0x6a, 0x45, 0x4c, 0x4d,
455 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x0a,
456 0x51, 0x56, 0x55, 0x78, 0x45, 0x7a, 0x41, 0x52, 0x42, 0x67, 0x4e, 0x56,
457 0x42, 0x41, 0x67, 0x4d, 0x43, 0x6c, 0x4e, 0x76, 0x62, 0x57, 0x55, 0x74,
458 0x55, 0x33, 0x52, 0x68, 0x64, 0x47, 0x55, 0x78, 0x49, 0x54, 0x41, 0x66,
459 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x47, 0x45, 0x6c, 0x75,
460 0x64, 0x47, 0x56, 0x79, 0x62, 0x6d, 0x56, 0x30, 0x49, 0x46, 0x64, 0x70,
461 0x5a, 0x47, 0x64, 0x70, 0x0a, 0x64, 0x48, 0x4d, 0x67, 0x55, 0x48, 0x52,
462 0x35, 0x49, 0x45, 0x78, 0x30, 0x5a, 0x44, 0x45, 0x6a, 0x4d, 0x43, 0x45,
463 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x61, 0x63, 0x32, 0x56,
464 0x73, 0x5a, 0x6e, 0x4e, 0x70, 0x5a, 0x32, 0x35, 0x6c, 0x5a, 0x43, 0x35,
465 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6e, 0x64, 0x70, 0x62, 0x6d, 0x56,
466 0x6f, 0x63, 0x53, 0x35, 0x76, 0x63, 0x6d, 0x63, 0x77, 0x0a, 0x67, 0x67,
467 0x45, 0x69, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49,
468 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34,
469 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f,
470 0x49, 0x42, 0x41, 0x51, 0x44, 0x77, 0x4e, 0x6d, 0x2b, 0x46, 0x7a, 0x78,
471 0x6e, 0x6b, 0x48, 0x57, 0x2f, 0x4e, 0x70, 0x37, 0x59, 0x48, 0x34, 0x4d,
472 0x79, 0x45, 0x0a, 0x77, 0x4d, 0x6c, 0x49, 0x67, 0x71, 0x30, 0x66, 0x45,
473 0x77, 0x70, 0x47, 0x6f, 0x41, 0x75, 0x78, 0x44, 0x64, 0x61, 0x46, 0x55,
474 0x32, 0x6f, 0x70, 0x76, 0x41, 0x51, 0x56, 0x61, 0x2b, 0x41, 0x43, 0x46,
475 0x38, 0x63, 0x6f, 0x38, 0x4d, 0x4a, 0x6c, 0x33, 0x78, 0x77, 0x76, 0x46,
476 0x44, 0x2b, 0x67, 0x61, 0x46, 0x45, 0x7a, 0x59, 0x78, 0x53, 0x58, 0x30,
477 0x43, 0x47, 0x72, 0x4a, 0x45, 0x4c, 0x63, 0x0a, 0x74, 0x34, 0x4d, 0x69,
478 0x30, 0x68, 0x4b, 0x50, 0x76, 0x42, 0x70, 0x65, 0x73, 0x59, 0x6c, 0x46,
479 0x4d, 0x51, 0x65, 0x6b, 0x2b, 0x63, 0x70, 0x51, 0x50, 0x33, 0x4b, 0x35,
480 0x75, 0x36, 0x71, 0x58, 0x5a, 0x52, 0x49, 0x67, 0x48, 0x75, 0x59, 0x45,
481 0x4c, 0x2f, 0x73, 0x55, 0x6f, 0x39, 0x32, 0x70, 0x44, 0x30, 0x7a, 0x4a,
482 0x65, 0x4c, 0x47, 0x41, 0x31, 0x49, 0x30, 0x4b, 0x5a, 0x34, 0x73, 0x2f,
483 0x0a, 0x51, 0x7a, 0x77, 0x61, 0x4f, 0x38, 0x62, 0x62, 0x4b, 0x6d, 0x37,
484 0x42, 0x72, 0x6e, 0x56, 0x77, 0x30, 0x6e, 0x5a, 0x2f, 0x4b, 0x41, 0x5a,
485 0x6a, 0x75, 0x78, 0x75, 0x6f, 0x4e, 0x33, 0x52, 0x64, 0x72, 0x69, 0x30,
486 0x4a, 0x48, 0x77, 0x7a, 0x6a, 0x41, 0x55, 0x34, 0x2b, 0x71, 0x57, 0x65,
487 0x55, 0x63, 0x2f, 0x64, 0x33, 0x45, 0x70, 0x4f, 0x47, 0x78, 0x69, 0x42,
488 0x77, 0x5a, 0x4e, 0x61, 0x7a, 0x0a, 0x39, 0x6f, 0x4a, 0x41, 0x37, 0x54,
489 0x2f, 0x51, 0x6f, 0x62, 0x75, 0x61, 0x4e, 0x53, 0x6b, 0x65, 0x55, 0x48,
490 0x43, 0x61, 0x50, 0x53, 0x6a, 0x44, 0x37, 0x71, 0x7a, 0x6c, 0x43, 0x4f,
491 0x52, 0x48, 0x47, 0x68, 0x75, 0x31, 0x76, 0x79, 0x79, 0x35, 0x31, 0x45,
492 0x36, 0x79, 0x46, 0x43, 0x4e, 0x47, 0x66, 0x65, 0x7a, 0x71, 0x2f, 0x4d,
493 0x59, 0x34, 0x4e, 0x4b, 0x68, 0x77, 0x72, 0x61, 0x59, 0x64, 0x0a, 0x62,
494 0x79, 0x49, 0x2f, 0x6c, 0x42, 0x46, 0x62, 0x36, 0x35, 0x6b, 0x5a, 0x45,
495 0x66, 0x49, 0x4b, 0x4b, 0x54, 0x7a, 0x79, 0x36, 0x76, 0x30, 0x44, 0x65,
496 0x79, 0x50, 0x37, 0x52, 0x6b, 0x34, 0x75, 0x48, 0x44, 0x38, 0x77, 0x62,
497 0x49, 0x79, 0x50, 0x32, 0x47, 0x6c, 0x42, 0x30, 0x67, 0x37, 0x2f, 0x69,
498 0x79, 0x33, 0x4c, 0x61, 0x74, 0x49, 0x74, 0x49, 0x70, 0x2b, 0x49, 0x35,
499 0x53, 0x50, 0x56, 0x0a, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a,
500 0x55, 0x44, 0x42, 0x4f, 0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64,
501 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x36, 0x49, 0x4c, 0x5a, 0x2f,
502 0x71, 0x38, 0x66, 0x2f, 0x4b, 0x45, 0x68, 0x4b, 0x76, 0x68, 0x69, 0x2b,
503 0x73, 0x6b, 0x59, 0x45, 0x31, 0x79, 0x48, 0x71, 0x39, 0x7a, 0x41, 0x66,
504 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, 0x0a, 0x47, 0x44, 0x41,
505 0x57, 0x67, 0x42, 0x53, 0x36, 0x49, 0x4c, 0x5a, 0x2f, 0x71, 0x38, 0x66,
506 0x2f, 0x4b, 0x45, 0x68, 0x4b, 0x76, 0x68, 0x69, 0x2b, 0x73, 0x6b, 0x59,
507 0x45, 0x31, 0x79, 0x48, 0x71, 0x39, 0x7a, 0x41, 0x4d, 0x42, 0x67, 0x4e,
508 0x56, 0x48, 0x52, 0x4d, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48,
509 0x2f, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62,
510 0x33, 0x0a, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41, 0x34,
511 0x49, 0x42, 0x41, 0x51, 0x41, 0x79, 0x5a, 0x59, 0x77, 0x47, 0x4b, 0x46,
512 0x34, 0x34, 0x43, 0x68, 0x47, 0x51, 0x72, 0x6e, 0x74, 0x57, 0x6c, 0x38,
513 0x48, 0x53, 0x4a, 0x30, 0x63, 0x69, 0x55, 0x58, 0x4d, 0x44, 0x4b, 0x32,
514 0x46, 0x6c, 0x6f, 0x74, 0x47, 0x49, 0x6a, 0x30, 0x32, 0x6c, 0x4d, 0x39,
515 0x38, 0x71, 0x45, 0x49, 0x65, 0x68, 0x0a, 0x56, 0x67, 0x66, 0x41, 0x34,
516 0x7a, 0x69, 0x37, 0x4d, 0x45, 0x6c, 0x51, 0x61, 0x76, 0x6b, 0x52, 0x76,
517 0x32, 0x54, 0x43, 0x50, 0x50, 0x55, 0x51, 0x62, 0x35, 0x51, 0x64, 0x61,
518 0x6f, 0x37, 0x57, 0x78, 0x37, 0x6c, 0x66, 0x61, 0x54, 0x6f, 0x5a, 0x68,
519 0x4f, 0x54, 0x2b, 0x4e, 0x52, 0x68, 0x32, 0x6b, 0x35, 0x78, 0x2b, 0x6b,
520 0x6a, 0x5a, 0x46, 0x77, 0x38, 0x70, 0x45, 0x48, 0x74, 0x35, 0x51, 0x0a,
521 0x69, 0x68, 0x62, 0x46, 0x4c, 0x35, 0x58, 0x2b, 0x57, 0x7a, 0x6f, 0x2b,
522 0x42, 0x36, 0x36, 0x59, 0x79, 0x49, 0x76, 0x68, 0x77, 0x54, 0x63, 0x48,
523 0x30, 0x46, 0x2b, 0x6e, 0x66, 0x55, 0x71, 0x66, 0x74, 0x38, 0x59, 0x74,
524 0x72, 0x2f, 0x38, 0x37, 0x47, 0x45, 0x62, 0x73, 0x41, 0x48, 0x6a, 0x48,
525 0x43, 0x36, 0x4c, 0x2b, 0x77, 0x6b, 0x31, 0x76, 0x4e, 0x6e, 0x64, 0x49,
526 0x59, 0x47, 0x30, 0x51, 0x0a, 0x79, 0x62, 0x73, 0x7a, 0x78, 0x49, 0x72,
527 0x32, 0x6d, 0x46, 0x45, 0x49, 0x4a, 0x6f, 0x69, 0x51, 0x44, 0x44, 0x67,
528 0x66, 0x6c, 0x71, 0x67, 0x64, 0x76, 0x4c, 0x54, 0x32, 0x79, 0x64, 0x46,
529 0x6d, 0x79, 0x33, 0x73, 0x32, 0x68, 0x49, 0x74, 0x51, 0x6c, 0x49, 0x71,
530 0x4b, 0x4c, 0x42, 0x36, 0x49, 0x4a, 0x51, 0x49, 0x75, 0x69, 0x37, 0x72,
531 0x37, 0x34, 0x76, 0x64, 0x72, 0x63, 0x58, 0x71, 0x58, 0x0a, 0x44, 0x7a,
532 0x68, 0x6d, 0x4c, 0x66, 0x67, 0x6a, 0x67, 0x4c, 0x77, 0x33, 0x2b, 0x55,
533 0x79, 0x69, 0x59, 0x74, 0x44, 0x54, 0x76, 0x63, 0x78, 0x65, 0x7a, 0x62,
534 0x4c, 0x73, 0x76, 0x51, 0x6f, 0x52, 0x6b, 0x74, 0x77, 0x4b, 0x5a, 0x4c,
535 0x44, 0x54, 0x42, 0x42, 0x35, 0x76, 0x59, 0x32, 0x78, 0x4b, 0x36, 0x6b,
536 0x4f, 0x4f, 0x44, 0x70, 0x7a, 0x50, 0x48, 0x73, 0x4b, 0x67, 0x30, 0x42,
537 0x59, 0x77, 0x0a, 0x4d, 0x6b, 0x48, 0x56, 0x56, 0x54, 0x34, 0x79, 0x2f,
538 0x4d, 0x59, 0x36, 0x63, 0x63, 0x4b, 0x51, 0x2f, 0x4c, 0x56, 0x74, 0x32,
539 0x66, 0x4a, 0x49, 0x74, 0x69, 0x41, 0x71, 0x49, 0x47, 0x32, 0x38, 0x64,
540 0x37, 0x31, 0x53, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44,
541 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
542 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a
545 static void testCertTrust(SAFE_PROVIDER_FUNCTIONS *funcs, GUID *actionID)
547 CRYPT_PROVIDER_DATA data = { 0 };
548 CRYPT_PROVIDER_SIGSTATE sig_state = { 0 };
549 CRYPT_PROVIDER_SGNR sgnr = { sizeof(sgnr), { 0 } };
550 HRESULT ret;
551 BOOL b;
553 if (!CertFreeCertificateChain_p)
555 win_skip("CertFreeCertificateChain not found\n");
556 return;
559 data.pSigState = &sig_state;
560 data.padwTrustStepErrors =
561 funcs->pfnAlloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
562 if (!data.padwTrustStepErrors)
564 skip("pfnAlloc failed\n");
565 return;
567 ret = funcs->pfnCertificateTrust(&data);
568 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
569 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] ==
570 TRUST_E_NOSIGNATURE, "Expected TRUST_E_NOSIGNATURE, got %08x\n",
571 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV]);
572 b = funcs->pfnAddSgnr2Chain(&data, FALSE, 0, &sgnr);
573 if (b)
575 PCCERT_CONTEXT cert;
577 /* An empty signer "succeeds," even though there's no cert */
578 ret = funcs->pfnCertificateTrust(&data);
579 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
580 cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
581 sizeof(selfSignedCert));
582 if (cert)
584 WINTRUST_DATA wintrust_data = { 0 };
586 b = funcs->pfnAddCert2Chain(&data, 0, FALSE, 0, cert);
587 ok(b == TRUE, "Expected TRUE, got %d\n", b);
589 /* If pWintrustData isn't set, crashes attempting to access
590 * pWintrustData->fdwRevocationChecks
592 data.pWintrustData = &wintrust_data;
593 /* If psPfns isn't set, crashes attempting to access
594 * psPfns->pfnCertCheckPolicy
596 data.psPfns = (CRYPT_PROVIDER_FUNCTIONS *)funcs;
597 ret = funcs->pfnCertificateTrust(&data);
598 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
599 ok(data.csSigners == 1, "Unexpected number of signers %d\n",
600 data.csSigners);
601 ok(data.pasSigners[0].pChainContext != NULL,
602 "Expected a certificate chain\n");
603 ok(data.pasSigners[0].csCertChain == 1,
604 "Unexpected number of chain elements %d\n",
605 data.pasSigners[0].csCertChain);
606 /* pasSigners and pasSigners[0].pasCertChain are guaranteed to be
607 * initialized, see tests for pfnAddSgnr2Chain and pfnAddCert2Chain
609 ok(!data.pasSigners[0].pasCertChain[0].fTrustedRoot,
610 "Didn't expect cert to be trusted\n");
611 ok(data.pasSigners[0].pasCertChain[0].fSelfSigned,
612 "Expected cert to be self-signed\n");
613 ok(data.pasSigners[0].pasCertChain[0].dwConfidence ==
614 (CERT_CONFIDENCE_SIG | CERT_CONFIDENCE_TIMENEST),
615 "Expected CERT_CONFIDENCE_SIG | CERT_CONFIDENCE_TIMENEST, got %08x\n",
616 data.pasSigners[0].pasCertChain[0].dwConfidence);
617 CertFreeCertificateContext(
618 data.pasSigners[0].pasCertChain[0].pCert);
619 CertFreeCertificateChain_p(data.pasSigners[0].pChainContext);
620 CertFreeCertificateContext(cert);
623 funcs->pfnFree(data.padwTrustStepErrors);
626 static void test_provider_funcs(void)
628 static GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
629 SAFE_PROVIDER_FUNCTIONS funcs = { sizeof(SAFE_PROVIDER_FUNCTIONS), 0 };
630 BOOL ret;
632 ret = WintrustLoadFunctionPointers(&generic_verify_v2,
633 (CRYPT_PROVIDER_FUNCTIONS *)&funcs);
634 if (!ret)
635 skip("WintrustLoadFunctionPointers failed\n");
636 else
638 test_utils(&funcs);
639 testInitialize(&funcs, &generic_verify_v2);
640 testObjTrust(&funcs, &generic_verify_v2);
641 testCertTrust(&funcs, &generic_verify_v2);
645 /* minimal PE file image */
646 #define VA_START 0x400000
647 #define FILE_PE_START 0x50
648 #define NUM_SECTIONS 3
649 #define FILE_TEXT 0x200
650 #define RVA_TEXT 0x1000
651 #define RVA_BSS 0x2000
652 #define FILE_IDATA 0x400
653 #define RVA_IDATA 0x3000
654 #define FILE_TOTAL 0x600
655 #define RVA_TOTAL 0x4000
656 #include <pshpack1.h>
657 struct Imports {
658 IMAGE_IMPORT_DESCRIPTOR descriptors[2];
659 IMAGE_THUNK_DATA32 original_thunks[2];
660 IMAGE_THUNK_DATA32 thunks[2];
661 struct __IMPORT_BY_NAME {
662 WORD hint;
663 char funcname[0x20];
664 } ibn;
665 char dllname[0x10];
667 #define EXIT_PROCESS (VA_START+RVA_IDATA+FIELD_OFFSET(struct Imports, thunks))
669 static struct _PeImage {
670 IMAGE_DOS_HEADER dos_header;
671 char __alignment1[FILE_PE_START - sizeof(IMAGE_DOS_HEADER)];
672 IMAGE_NT_HEADERS32 nt_headers;
673 IMAGE_SECTION_HEADER sections[NUM_SECTIONS];
674 char __alignment2[FILE_TEXT - FILE_PE_START - sizeof(IMAGE_NT_HEADERS32) -
675 NUM_SECTIONS * sizeof(IMAGE_SECTION_HEADER)];
676 unsigned char text_section[FILE_IDATA-FILE_TEXT];
677 struct Imports idata_section;
678 char __alignment3[FILE_TOTAL-FILE_IDATA-sizeof(struct Imports)];
679 } bin = {
680 /* dos header */
681 {IMAGE_DOS_SIGNATURE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, 0, {0}, FILE_PE_START},
682 /* alignment before PE header */
683 {0},
684 /* nt headers */
685 {IMAGE_NT_SIGNATURE,
686 /* basic headers - 3 sections, no symbols, EXE file */
687 {IMAGE_FILE_MACHINE_I386, NUM_SECTIONS, 0, 0, 0, sizeof(IMAGE_OPTIONAL_HEADER32),
688 IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_EXECUTABLE_IMAGE},
689 /* optional header */
690 {IMAGE_NT_OPTIONAL_HDR32_MAGIC, 4, 0, FILE_IDATA-FILE_TEXT,
691 FILE_TOTAL-FILE_IDATA + FILE_IDATA-FILE_TEXT, 0x400,
692 RVA_TEXT, RVA_TEXT, RVA_BSS, VA_START, 0x1000, 0x200, 4, 0, 1, 0, 4, 0, 0,
693 RVA_TOTAL, FILE_TEXT, 0, IMAGE_SUBSYSTEM_WINDOWS_GUI, 0,
694 0x200000, 0x1000, 0x100000, 0x1000, 0, 0x10,
695 {{0, 0},
696 {RVA_IDATA, sizeof(struct Imports)}
700 /* sections */
702 {".text", {0x100}, RVA_TEXT, FILE_IDATA-FILE_TEXT, FILE_TEXT,
703 0, 0, 0, 0, IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ},
704 {".bss", {0x400}, RVA_BSS, 0, 0, 0, 0, 0, 0,
705 IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE},
706 {".idata", {sizeof(struct Imports)}, RVA_IDATA, FILE_TOTAL-FILE_IDATA, FILE_IDATA, 0,
707 0, 0, 0, IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE}
709 /* alignment before first section */
710 {0},
711 /* .text section */
713 0x31, 0xC0, /* xor eax, eax */
714 0xFF, 0x25, EXIT_PROCESS&0xFF, (EXIT_PROCESS>>8)&0xFF, (EXIT_PROCESS>>16)&0xFF,
715 (EXIT_PROCESS>>24)&0xFF, /* jmp ExitProcess */
718 /* .idata section */
721 {{RVA_IDATA + FIELD_OFFSET(struct Imports, original_thunks)}, 0, 0,
722 RVA_IDATA + FIELD_OFFSET(struct Imports, dllname),
723 RVA_IDATA + FIELD_OFFSET(struct Imports, thunks)
725 {{0}, 0, 0, 0, 0}
727 {{{RVA_IDATA+FIELD_OFFSET(struct Imports, ibn)}}, {{0}}},
728 {{{RVA_IDATA+FIELD_OFFSET(struct Imports, ibn)}}, {{0}}},
729 {0,"ExitProcess"},
730 "KERNEL32.DLL"
732 /* final alignment */
735 #include <poppack.h>
737 static void test_sip_create_indirect_data(void)
739 static GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
740 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
741 static char oid_sha1[] = szOID_OIWSEC_sha1;
742 BOOL ret;
743 SIP_SUBJECTINFO subjinfo = { 0 };
744 WCHAR temp_file[MAX_PATH];
745 HANDLE file;
746 DWORD count;
748 if (!CryptSIPCreateIndirectData_p)
750 skip("Missing CryptSIPCreateIndirectData\n");
751 return;
753 SetLastError(0xdeadbeef);
754 ret = CryptSIPCreateIndirectData_p(NULL, NULL, NULL);
755 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
756 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
757 SetLastError(0xdeadbeef);
758 ret = CryptSIPCreateIndirectData_p(&subjinfo, NULL, NULL);
759 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
760 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
761 subjinfo.cbSize = sizeof(subjinfo);
762 SetLastError(0xdeadbeef);
763 ret = CryptSIPCreateIndirectData_p(&subjinfo, NULL, NULL);
764 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
765 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
766 file = create_temp_file(temp_file);
767 if (file == INVALID_HANDLE_VALUE)
769 skip("couldn't create temp file\n");
770 return;
772 WriteFile(file, &bin, sizeof(bin), &count, NULL);
773 FlushFileBuffers(file);
775 subjinfo.hFile = file;
776 SetLastError(0xdeadbeef);
777 ret = CryptSIPCreateIndirectData_p(&subjinfo, NULL, NULL);
778 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
779 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
780 subjinfo.pgSubjectType = &unknown;
781 SetLastError(0xdeadbeef);
782 ret = CryptSIPCreateIndirectData_p(&subjinfo, NULL, NULL);
783 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
784 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
785 subjinfo.DigestAlgorithm.pszObjId = oid_sha1;
786 count = 0xdeadbeef;
787 ret = CryptSIPCreateIndirectData_p(&subjinfo, &count, NULL);
788 todo_wine
789 ok(ret, "CryptSIPCreateIndirectData failed: %d\n", GetLastError());
790 ok(count, "expected a positive count\n");
791 if (ret)
793 SIP_INDIRECT_DATA *indirect = HeapAlloc(GetProcessHeap(), 0, count);
795 count = 256;
796 ret = CryptSIPCreateIndirectData_p(&subjinfo, &count, indirect);
797 ok(ret, "CryptSIPCreateIndirectData failed: %d\n", GetLastError());
798 /* If the count is larger than needed, it's unmodified */
799 ok(count == 256, "unexpected count %d\n", count);
800 ok(!strcmp(indirect->Data.pszObjId, SPC_PE_IMAGE_DATA_OBJID),
801 "unexpected data oid %s\n",
802 indirect->Data.pszObjId);
803 ok(!strcmp(indirect->DigestAlgorithm.pszObjId, oid_sha1),
804 "unexpected digest algorithm oid %s\n",
805 indirect->DigestAlgorithm.pszObjId);
806 ok(indirect->Digest.cbData == 20, "unexpected hash size %d\n",
807 indirect->Digest.cbData);
808 if (indirect->Digest.cbData == 20)
810 const BYTE hash[20] = {
811 0x8a,0xd5,0x45,0x53,0x3d,0x67,0xdf,0x2f,0x78,0xe0,
812 0x55,0x0a,0xe0,0xd9,0x7a,0x28,0x3e,0xbf,0x45,0x2b };
814 ok(!memcmp(indirect->Digest.pbData, hash, 20),
815 "unexpected value\n");
818 HeapFree(GetProcessHeap(), 0, indirect);
820 CloseHandle(file);
821 DeleteFileW(temp_file);
824 static void test_wintrust(void)
826 static GUID generic_action_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
827 WINTRUST_DATA wtd;
828 WINTRUST_FILE_INFO file;
829 LONG r;
830 HRESULT hr;
831 WCHAR pathW[MAX_PATH];
833 memset(&wtd, 0, sizeof(wtd));
834 wtd.cbStruct = sizeof(wtd);
835 wtd.dwUIChoice = WTD_UI_NONE;
836 wtd.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN;
837 wtd.dwUnionChoice = WTD_CHOICE_FILE;
838 U(wtd).pFile = &file;
839 wtd.dwStateAction = WTD_STATEACTION_VERIFY;
840 memset(&file, 0, sizeof(file));
841 file.cbStruct = sizeof(file);
842 file.pcwszFilePath = pathW;
843 /* Test with an empty file */
844 file.hFile = create_temp_file(pathW);
845 r = WinVerifyTrust(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd);
846 ok(r == TRUST_E_SUBJECT_FORM_UNKNOWN,
847 "expected TRUST_E_SUBJECT_FORM_UNKNOWN, got %08x\n", r);
848 CloseHandle(file.hFile);
849 DeleteFileW(pathW);
850 file.hFile = NULL;
851 /* Test with a known file path, which we expect not have a signature */
852 getNotepadPath(pathW, MAX_PATH);
853 r = WinVerifyTrust(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd);
854 ok(r == TRUST_E_NOSIGNATURE || r == CRYPT_E_FILE_ERROR,
855 "expected TRUST_E_NOSIGNATURE or CRYPT_E_FILE_ERROR, got %08x\n", r);
856 wtd.dwStateAction = WTD_STATEACTION_CLOSE;
857 r = WinVerifyTrust(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd);
858 ok(r == S_OK, "WinVerifyTrust failed: %08x\n", r);
859 wtd.dwStateAction = WTD_STATEACTION_VERIFY;
860 hr = WinVerifyTrustEx(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd);
861 ok(hr == TRUST_E_NOSIGNATURE || hr == CRYPT_E_FILE_ERROR,
862 "expected TRUST_E_NOSIGNATURE or CRYPT_E_FILE_ERROR, got %08x\n", hr);
863 wtd.dwStateAction = WTD_STATEACTION_CLOSE;
864 r = WinVerifyTrust(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd);
865 ok(r == S_OK, "WinVerifyTrust failed: %08x\n", r);
868 static void test_get_known_usages(void)
870 BOOL ret;
871 PCCRYPT_OID_INFO *usages;
873 if (!pWTHelperGetKnownUsages)
875 skip("missing WTHelperGetKnownUsages\n");
876 return;
878 SetLastError(0xdeadbeef);
879 ret = pWTHelperGetKnownUsages(0, NULL);
880 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
881 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
882 SetLastError(0xdeadbeef);
883 ret = pWTHelperGetKnownUsages(1, NULL);
884 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
885 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
886 SetLastError(0xdeadbeef);
887 ret = pWTHelperGetKnownUsages(0, &usages);
888 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
889 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
890 /* A value of 1 for the first parameter seems to imply the value is
891 * allocated
893 SetLastError(0xdeadbeef);
894 usages = NULL;
895 ret = pWTHelperGetKnownUsages(1, &usages);
896 ok(ret, "WTHelperGetKnownUsages failed: %d\n", GetLastError());
897 ok(usages != NULL, "expected a pointer\n");
898 if (ret && usages)
900 PCCRYPT_OID_INFO *ptr;
902 /* The returned usages are an array of PCCRYPT_OID_INFOs, terminated with a
903 * NULL pointer.
905 for (ptr = usages; *ptr; ptr++)
907 ok((*ptr)->cbSize == sizeof(CRYPT_OID_INFO) ||
908 (*ptr)->cbSize == (sizeof(CRYPT_OID_INFO) + 2 * sizeof(LPCWSTR)), /* Vista */
909 "unexpected size %d\n", (*ptr)->cbSize);
910 /* Each returned usage is in the CRYPT_ENHKEY_USAGE_OID_GROUP_ID group */
911 ok((*ptr)->dwGroupId == CRYPT_ENHKEY_USAGE_OID_GROUP_ID,
912 "expected group CRYPT_ENHKEY_USAGE_OID_GROUP_ID, got %d\n",
913 (*ptr)->dwGroupId);
916 /* A value of 2 for the second parameter seems to imply the value is freed
918 SetLastError(0xdeadbeef);
919 ret = pWTHelperGetKnownUsages(2, &usages);
920 ok(ret, "WTHelperGetKnownUsages failed: %d\n", GetLastError());
921 ok(usages == NULL, "expected pointer to be cleared\n");
922 SetLastError(0xdeadbeef);
923 usages = NULL;
924 ret = pWTHelperGetKnownUsages(2, &usages);
925 ok(ret, "WTHelperGetKnownUsages failed: %d\n", GetLastError());
926 SetLastError(0xdeadbeef);
927 ret = pWTHelperGetKnownUsages(2, NULL);
928 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
929 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
932 START_TEST(softpub)
934 InitFunctionPtrs();
935 test_provider_funcs();
936 test_sip_create_indirect_data();
937 test_wintrust();
938 test_get_known_usages();