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
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
*,
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
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); \
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); \
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,
124 static void test_utils(SAFE_PROVIDER_FUNCTIONS
*funcs
)
126 CRYPT_PROVIDER_DATA data
= { 0 };
128 CRYPT_PROVIDER_SGNR sgnr
= { 0 };
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
);
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");
145 ok(data
.pahStores
[0] == store
, "Unexpected store\n");
146 CertCloseStore(data
.pahStores
[0], 0);
147 funcs
->pfnFree(data
.pahStores
);
148 data
.pahStores
= NULL
;
150 CertCloseStore(store
, 0);
155 skip("CertOpenStore failed: %08x\n", GetLastError());
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");
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 data aren't copied */
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 ok(data
.pasSigners
[0].cbStruct
== 0, "Unexpected data size %d\n",
185 data
.pasSigners
[0].cbStruct
);
186 ok(data
.pasSigners
[0].sftVerifyAsOf
.dwLowDateTime
== 0,
187 "Unexpected verify time %d\n",
188 data
.pasSigners
[0].sftVerifyAsOf
.dwLowDateTime
);
189 /* But too large a thing isn't added */
190 sgnr
.cbStruct
= sizeof(sgnr
) + sizeof(DWORD
);
191 SetLastError(0xdeadbeef);
192 ret
= funcs
->pfnAddSgnr2Chain(&data
, FALSE
, 0, &sgnr
);
193 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
194 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
197 ret = funcs->pfnAddCert2Chain(NULL, 0, FALSE, 0, NULL);
198 ret = funcs->pfnAddCert2Chain(&data, 0, FALSE, 0, NULL);
200 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, v1CertWithPubKey
,
201 sizeof(v1CertWithPubKey
));
204 /* Notes on behavior that are hard to test:
205 * 1. If pasSigners is invalid, pfnAddCert2Chain crashes
206 * 2. An invalid signer index isn't checked.
208 ret
= funcs
->pfnAddCert2Chain(&data
, 0, FALSE
, 0, cert
);
209 ok(ret
, "pfnAddCert2Chain failed: %08x\n", GetLastError());
210 ok(data
.pasSigners
[0].csCertChain
== 1, "Expected 1 cert, got %d\n",
211 data
.pasSigners
[0].csCertChain
);
212 ok(data
.pasSigners
[0].pasCertChain
!= NULL
,
213 "Expected pasCertChain to be allocated\n");
214 if (data
.pasSigners
[0].pasCertChain
)
216 ok(data
.pasSigners
[0].pasCertChain
[0].pCert
== cert
,
217 "Unexpected cert\n");
218 CertFreeCertificateContext(
219 data
.pasSigners
[0].pasCertChain
[0].pCert
);
221 CertFreeCertificateContext(cert
);
224 skip("CertCreateCertificateContext failed: %08x\n", GetLastError());
225 funcs
->pfnFree(data
.pasSigners
);
229 static void testInitialize(SAFE_PROVIDER_FUNCTIONS
*funcs
, GUID
*actionID
)
232 CRYPT_PROVIDER_DATA data
= { 0 };
233 WINTRUST_DATA wintrust_data
= { 0 };
235 if (!funcs
->pfnInitialize
)
237 skip("missing pfnInitialize\n");
242 ret = funcs->pfnInitialize(NULL);
244 memset(&data
, 0, sizeof(data
));
245 ret
= funcs
->pfnInitialize(&data
);
246 ok(ret
== S_FALSE
, "Expected S_FALSE, got %08x\n", ret
);
247 data
.padwTrustStepErrors
=
248 funcs
->pfnAlloc(TRUSTERROR_MAX_STEPS
* sizeof(DWORD
));
249 /* Without wintrust data set, crashes when padwTrustStepErrors is set */
250 data
.pWintrustData
= &wintrust_data
;
251 if (data
.padwTrustStepErrors
)
253 /* Apparently, cdwTrustStepErrors does not need to be set. */
254 ret
= funcs
->pfnInitialize(&data
);
255 ok(ret
== S_OK
, "Expected S_OK, got %08x\n", ret
);
256 data
.cdwTrustStepErrors
= 1;
257 ret
= funcs
->pfnInitialize(&data
);
258 ok(ret
== S_OK
, "Expected S_OK, got %08x\n", ret
);
259 memset(data
.padwTrustStepErrors
, 0xba,
260 TRUSTERROR_MAX_STEPS
* sizeof(DWORD
));
261 ret
= funcs
->pfnInitialize(&data
);
262 ok(ret
== S_FALSE
, "Expected S_FALSE, got %08x\n", ret
);
263 data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_WVTINIT
] = 0;
264 ret
= funcs
->pfnInitialize(&data
);
265 ok(ret
== S_OK
, "Expected S_OK, got %08x\n", ret
);
266 funcs
->pfnFree(data
.padwTrustStepErrors
);
270 static void getNotepadPath(WCHAR
*notepadPathW
, DWORD size
)
272 static const CHAR notepad
[] = "\\notepad.exe";
273 CHAR notepadPath
[MAX_PATH
];
275 /* Workaround missing W-functions for win9x */
276 GetWindowsDirectoryA(notepadPath
, MAX_PATH
);
277 lstrcatA(notepadPath
, notepad
);
278 MultiByteToWideChar(CP_ACP
, 0, notepadPath
, -1, notepadPathW
, size
);
281 /* Creates a test file and returns a handle to it. The file's path is returned
282 * in temp_file, which must be at least MAX_PATH characters in length.
284 static HANDLE
create_temp_file(WCHAR
*temp_file
)
286 HANDLE file
= INVALID_HANDLE_VALUE
;
287 WCHAR temp_path
[MAX_PATH
];
289 if (GetTempPathW(sizeof(temp_path
) / sizeof(temp_path
[0]), temp_path
))
291 static const WCHAR img
[] = { 'i','m','g',0 };
293 if (GetTempFileNameW(temp_path
, img
, 0, temp_file
))
294 file
= CreateFileW(temp_file
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
295 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
300 static void testObjTrust(SAFE_PROVIDER_FUNCTIONS
*funcs
, GUID
*actionID
)
303 CRYPT_PROVIDER_DATA data
= { 0 };
304 WINTRUST_DATA wintrust_data
= { 0 };
305 WINTRUST_CERT_INFO certInfo
= { sizeof(WINTRUST_CERT_INFO
), 0 };
306 WINTRUST_FILE_INFO fileInfo
= { sizeof(WINTRUST_FILE_INFO
), 0 };
308 if (!funcs
->pfnObjectTrust
)
310 skip("missing pfnObjectTrust\n");
315 ret = funcs->pfnObjectTrust(NULL);
317 data
.pWintrustData
= &wintrust_data
;
318 data
.padwTrustStepErrors
=
319 funcs
->pfnAlloc(TRUSTERROR_MAX_STEPS
* sizeof(DWORD
));
320 if (data
.padwTrustStepErrors
)
322 WCHAR pathW
[MAX_PATH
];
323 PROVDATA_SIP provDataSIP
= { 0 };
324 static const GUID unknown
= { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
325 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
326 static GUID bogusGuid
= { 0xdeadbeef, 0xbaad, 0xf00d, { 0x00,0x00,0x00,
327 0x00,0x00,0x00,0x00,0x00 } };
329 ret
= funcs
->pfnObjectTrust(&data
);
330 ok(ret
== S_FALSE
, "Expected S_FALSE, got %08x\n", ret
);
331 ok(data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] ==
332 ERROR_INVALID_PARAMETER
,
333 "Expected ERROR_INVALID_PARAMETER, got %08x\n",
334 data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
]);
335 U(wintrust_data
).pCert
= &certInfo
;
336 wintrust_data
.dwUnionChoice
= WTD_CHOICE_CERT
;
337 ret
= funcs
->pfnObjectTrust(&data
);
338 ok(ret
== S_OK
, "Expected S_OK, got %08x\n", ret
);
339 certInfo
.psCertContext
= (PCERT_CONTEXT
)CertCreateCertificateContext(
340 X509_ASN_ENCODING
, v1CertWithPubKey
, sizeof(v1CertWithPubKey
));
341 ret
= funcs
->pfnObjectTrust(&data
);
342 ok(ret
== S_OK
, "Expected S_OK, got %08x\n", ret
);
343 CertFreeCertificateContext(certInfo
.psCertContext
);
344 certInfo
.psCertContext
= NULL
;
345 wintrust_data
.dwUnionChoice
= WTD_CHOICE_FILE
;
346 U(wintrust_data
).pFile
= NULL
;
347 ret
= funcs
->pfnObjectTrust(&data
);
348 ok(ret
== S_FALSE
, "Expected S_FALSE, got %08x\n", ret
);
349 ok(data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] ==
350 ERROR_INVALID_PARAMETER
,
351 "Expected ERROR_INVALID_PARAMETER, got %08x\n",
352 data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
]);
353 U(wintrust_data
).pFile
= &fileInfo
;
355 ret = funcs->pfnObjectTrust(&data);
357 /* Create and test with an empty file */
358 fileInfo
.hFile
= create_temp_file(pathW
);
359 /* pfnObjectTrust now crashes unless both pPDSip and psPfns are set */
360 U(data
).pPDSip
= &provDataSIP
;
361 data
.psPfns
= (CRYPT_PROVIDER_FUNCTIONS
*)funcs
;
362 ret
= funcs
->pfnObjectTrust(&data
);
363 ok(ret
== S_FALSE
, "Expected S_FALSE, got %08x\n", ret
);
364 ok(data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] ==
365 TRUST_E_SUBJECT_FORM_UNKNOWN
,
366 "expected TRUST_E_SUBJECT_FORM_UNKNOWN, got %08x\n",
367 data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
]);
368 CloseHandle(fileInfo
.hFile
);
369 fileInfo
.hFile
= NULL
;
370 fileInfo
.pcwszFilePath
= pathW
;
371 ret
= funcs
->pfnObjectTrust(&data
);
372 ok(ret
== S_FALSE
, "Expected S_FALSE, got %08x\n", ret
);
373 ok(data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] ==
374 TRUST_E_SUBJECT_FORM_UNKNOWN
,
375 "expected TRUST_E_SUBJECT_FORM_UNKNOWN, got %08x\n",
376 data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
]);
378 /* Test again with a file we expect to exist, and to contain no
381 getNotepadPath(pathW
, MAX_PATH
);
382 ret
= funcs
->pfnObjectTrust(&data
);
383 ok(ret
== S_FALSE
, "Expected S_FALSE, got %08x\n", ret
);
384 ok(data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] ==
385 TRUST_E_NOSIGNATURE
||
386 data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] ==
387 TRUST_E_SUBJECT_FORM_UNKNOWN
,
388 "Expected TRUST_E_NOSIGNATURE or TRUST_E_SUBJECT_FORM_UNKNOWN, got %08x\n",
389 data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
]);
390 if (data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] ==
393 ok(!memcmp(&provDataSIP
.gSubject
, &unknown
, sizeof(unknown
)),
394 "Unexpected subject GUID\n");
395 ok(provDataSIP
.pSip
!= NULL
, "Expected a SIP\n");
396 ok(provDataSIP
.psSipSubjectInfo
!= NULL
,
397 "Expected a subject info\n");
399 /* Specifying the GUID results in that GUID being the subject GUID */
400 fileInfo
.pgKnownSubject
= &bogusGuid
;
401 ret
= funcs
->pfnObjectTrust(&data
);
402 ok(ret
== S_FALSE
, "Expected S_FALSE, got %08x\n", ret
);
403 ok(data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] ==
404 TRUST_E_NOSIGNATURE
||
405 data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] ==
406 TRUST_E_SUBJECT_FORM_UNKNOWN
||
407 data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] ==
408 TRUST_E_PROVIDER_UNKNOWN
,
409 "Expected TRUST_E_NOSIGNATURE or TRUST_E_SUBJECT_FORM_UNKNOWN or TRUST_E_PROVIDER_UNKNOWN, got %08x\n",
410 data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
]);
411 if (data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_OBJPROV
] ==
414 ok(!memcmp(&provDataSIP
.gSubject
, &bogusGuid
, sizeof(bogusGuid
)),
415 "unexpected subject GUID\n");
417 /* Specifying a bogus GUID pointer crashes */
420 fileInfo
.pgKnownSubject
= (GUID
*)0xdeadbeef;
421 ret
= funcs
->pfnObjectTrust(&data
);
422 ok(ret
== S_FALSE
, "Expected S_FALSE, got %08x\n", ret
);
424 funcs
->pfnFree(data
.padwTrustStepErrors
);
428 static const BYTE selfSignedCert
[] = {
429 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
430 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
431 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x70, 0x7a, 0x43, 0x43,
432 0x41, 0x6f, 0x2b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4a,
433 0x41, 0x4c, 0x59, 0x51, 0x67, 0x65, 0x66, 0x7a, 0x51, 0x41, 0x61, 0x43,
434 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
435 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x4d, 0x47, 0x6f, 0x78,
436 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41, 0x59,
437 0x54, 0x41, 0x6b, 0x46, 0x56, 0x4d, 0x52, 0x4d, 0x77, 0x45, 0x51, 0x59,
438 0x44, 0x56, 0x51, 0x51, 0x49, 0x44, 0x41, 0x70, 0x54, 0x62, 0x32, 0x31,
439 0x6c, 0x4c, 0x56, 0x4e, 0x30, 0x59, 0x58, 0x52, 0x6c, 0x4d, 0x53, 0x45,
440 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x42, 0x68,
441 0x4a, 0x62, 0x6e, 0x52, 0x6c, 0x63, 0x6d, 0x35, 0x6c, 0x64, 0x43, 0x42,
442 0x58, 0x0a, 0x61, 0x57, 0x52, 0x6e, 0x61, 0x58, 0x52, 0x7a, 0x49, 0x46,
443 0x42, 0x30, 0x65, 0x53, 0x42, 0x4d, 0x64, 0x47, 0x51, 0x78, 0x49, 0x7a,
444 0x41, 0x68, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x4d, 0x47, 0x6e,
445 0x4e, 0x6c, 0x62, 0x47, 0x5a, 0x7a, 0x61, 0x57, 0x64, 0x75, 0x5a, 0x57,
446 0x51, 0x75, 0x64, 0x47, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x33, 0x61, 0x57,
447 0x35, 0x6c, 0x61, 0x48, 0x45, 0x75, 0x0a, 0x62, 0x33, 0x4a, 0x6e, 0x4d,
448 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x7a, 0x4d, 0x44, 0x59, 0x79, 0x4d,
449 0x54, 0x45, 0x78, 0x4d, 0x6a, 0x55, 0x78, 0x4d, 0x46, 0x6f, 0x58, 0x44,
450 0x54, 0x49, 0x7a, 0x4d, 0x44, 0x59, 0x78, 0x4f, 0x54, 0x45, 0x78, 0x4d,
451 0x6a, 0x55, 0x78, 0x4d, 0x46, 0x6f, 0x77, 0x61, 0x6a, 0x45, 0x4c, 0x4d,
452 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x0a,
453 0x51, 0x56, 0x55, 0x78, 0x45, 0x7a, 0x41, 0x52, 0x42, 0x67, 0x4e, 0x56,
454 0x42, 0x41, 0x67, 0x4d, 0x43, 0x6c, 0x4e, 0x76, 0x62, 0x57, 0x55, 0x74,
455 0x55, 0x33, 0x52, 0x68, 0x64, 0x47, 0x55, 0x78, 0x49, 0x54, 0x41, 0x66,
456 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x47, 0x45, 0x6c, 0x75,
457 0x64, 0x47, 0x56, 0x79, 0x62, 0x6d, 0x56, 0x30, 0x49, 0x46, 0x64, 0x70,
458 0x5a, 0x47, 0x64, 0x70, 0x0a, 0x64, 0x48, 0x4d, 0x67, 0x55, 0x48, 0x52,
459 0x35, 0x49, 0x45, 0x78, 0x30, 0x5a, 0x44, 0x45, 0x6a, 0x4d, 0x43, 0x45,
460 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x61, 0x63, 0x32, 0x56,
461 0x73, 0x5a, 0x6e, 0x4e, 0x70, 0x5a, 0x32, 0x35, 0x6c, 0x5a, 0x43, 0x35,
462 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6e, 0x64, 0x70, 0x62, 0x6d, 0x56,
463 0x6f, 0x63, 0x53, 0x35, 0x76, 0x63, 0x6d, 0x63, 0x77, 0x0a, 0x67, 0x67,
464 0x45, 0x69, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49,
465 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34,
466 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f,
467 0x49, 0x42, 0x41, 0x51, 0x44, 0x77, 0x4e, 0x6d, 0x2b, 0x46, 0x7a, 0x78,
468 0x6e, 0x6b, 0x48, 0x57, 0x2f, 0x4e, 0x70, 0x37, 0x59, 0x48, 0x34, 0x4d,
469 0x79, 0x45, 0x0a, 0x77, 0x4d, 0x6c, 0x49, 0x67, 0x71, 0x30, 0x66, 0x45,
470 0x77, 0x70, 0x47, 0x6f, 0x41, 0x75, 0x78, 0x44, 0x64, 0x61, 0x46, 0x55,
471 0x32, 0x6f, 0x70, 0x76, 0x41, 0x51, 0x56, 0x61, 0x2b, 0x41, 0x43, 0x46,
472 0x38, 0x63, 0x6f, 0x38, 0x4d, 0x4a, 0x6c, 0x33, 0x78, 0x77, 0x76, 0x46,
473 0x44, 0x2b, 0x67, 0x61, 0x46, 0x45, 0x7a, 0x59, 0x78, 0x53, 0x58, 0x30,
474 0x43, 0x47, 0x72, 0x4a, 0x45, 0x4c, 0x63, 0x0a, 0x74, 0x34, 0x4d, 0x69,
475 0x30, 0x68, 0x4b, 0x50, 0x76, 0x42, 0x70, 0x65, 0x73, 0x59, 0x6c, 0x46,
476 0x4d, 0x51, 0x65, 0x6b, 0x2b, 0x63, 0x70, 0x51, 0x50, 0x33, 0x4b, 0x35,
477 0x75, 0x36, 0x71, 0x58, 0x5a, 0x52, 0x49, 0x67, 0x48, 0x75, 0x59, 0x45,
478 0x4c, 0x2f, 0x73, 0x55, 0x6f, 0x39, 0x32, 0x70, 0x44, 0x30, 0x7a, 0x4a,
479 0x65, 0x4c, 0x47, 0x41, 0x31, 0x49, 0x30, 0x4b, 0x5a, 0x34, 0x73, 0x2f,
480 0x0a, 0x51, 0x7a, 0x77, 0x61, 0x4f, 0x38, 0x62, 0x62, 0x4b, 0x6d, 0x37,
481 0x42, 0x72, 0x6e, 0x56, 0x77, 0x30, 0x6e, 0x5a, 0x2f, 0x4b, 0x41, 0x5a,
482 0x6a, 0x75, 0x78, 0x75, 0x6f, 0x4e, 0x33, 0x52, 0x64, 0x72, 0x69, 0x30,
483 0x4a, 0x48, 0x77, 0x7a, 0x6a, 0x41, 0x55, 0x34, 0x2b, 0x71, 0x57, 0x65,
484 0x55, 0x63, 0x2f, 0x64, 0x33, 0x45, 0x70, 0x4f, 0x47, 0x78, 0x69, 0x42,
485 0x77, 0x5a, 0x4e, 0x61, 0x7a, 0x0a, 0x39, 0x6f, 0x4a, 0x41, 0x37, 0x54,
486 0x2f, 0x51, 0x6f, 0x62, 0x75, 0x61, 0x4e, 0x53, 0x6b, 0x65, 0x55, 0x48,
487 0x43, 0x61, 0x50, 0x53, 0x6a, 0x44, 0x37, 0x71, 0x7a, 0x6c, 0x43, 0x4f,
488 0x52, 0x48, 0x47, 0x68, 0x75, 0x31, 0x76, 0x79, 0x79, 0x35, 0x31, 0x45,
489 0x36, 0x79, 0x46, 0x43, 0x4e, 0x47, 0x66, 0x65, 0x7a, 0x71, 0x2f, 0x4d,
490 0x59, 0x34, 0x4e, 0x4b, 0x68, 0x77, 0x72, 0x61, 0x59, 0x64, 0x0a, 0x62,
491 0x79, 0x49, 0x2f, 0x6c, 0x42, 0x46, 0x62, 0x36, 0x35, 0x6b, 0x5a, 0x45,
492 0x66, 0x49, 0x4b, 0x4b, 0x54, 0x7a, 0x79, 0x36, 0x76, 0x30, 0x44, 0x65,
493 0x79, 0x50, 0x37, 0x52, 0x6b, 0x34, 0x75, 0x48, 0x44, 0x38, 0x77, 0x62,
494 0x49, 0x79, 0x50, 0x32, 0x47, 0x6c, 0x42, 0x30, 0x67, 0x37, 0x2f, 0x69,
495 0x79, 0x33, 0x4c, 0x61, 0x74, 0x49, 0x74, 0x49, 0x70, 0x2b, 0x49, 0x35,
496 0x53, 0x50, 0x56, 0x0a, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a,
497 0x55, 0x44, 0x42, 0x4f, 0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64,
498 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x36, 0x49, 0x4c, 0x5a, 0x2f,
499 0x71, 0x38, 0x66, 0x2f, 0x4b, 0x45, 0x68, 0x4b, 0x76, 0x68, 0x69, 0x2b,
500 0x73, 0x6b, 0x59, 0x45, 0x31, 0x79, 0x48, 0x71, 0x39, 0x7a, 0x41, 0x66,
501 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, 0x0a, 0x47, 0x44, 0x41,
502 0x57, 0x67, 0x42, 0x53, 0x36, 0x49, 0x4c, 0x5a, 0x2f, 0x71, 0x38, 0x66,
503 0x2f, 0x4b, 0x45, 0x68, 0x4b, 0x76, 0x68, 0x69, 0x2b, 0x73, 0x6b, 0x59,
504 0x45, 0x31, 0x79, 0x48, 0x71, 0x39, 0x7a, 0x41, 0x4d, 0x42, 0x67, 0x4e,
505 0x56, 0x48, 0x52, 0x4d, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48,
506 0x2f, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62,
507 0x33, 0x0a, 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41, 0x34,
508 0x49, 0x42, 0x41, 0x51, 0x41, 0x79, 0x5a, 0x59, 0x77, 0x47, 0x4b, 0x46,
509 0x34, 0x34, 0x43, 0x68, 0x47, 0x51, 0x72, 0x6e, 0x74, 0x57, 0x6c, 0x38,
510 0x48, 0x53, 0x4a, 0x30, 0x63, 0x69, 0x55, 0x58, 0x4d, 0x44, 0x4b, 0x32,
511 0x46, 0x6c, 0x6f, 0x74, 0x47, 0x49, 0x6a, 0x30, 0x32, 0x6c, 0x4d, 0x39,
512 0x38, 0x71, 0x45, 0x49, 0x65, 0x68, 0x0a, 0x56, 0x67, 0x66, 0x41, 0x34,
513 0x7a, 0x69, 0x37, 0x4d, 0x45, 0x6c, 0x51, 0x61, 0x76, 0x6b, 0x52, 0x76,
514 0x32, 0x54, 0x43, 0x50, 0x50, 0x55, 0x51, 0x62, 0x35, 0x51, 0x64, 0x61,
515 0x6f, 0x37, 0x57, 0x78, 0x37, 0x6c, 0x66, 0x61, 0x54, 0x6f, 0x5a, 0x68,
516 0x4f, 0x54, 0x2b, 0x4e, 0x52, 0x68, 0x32, 0x6b, 0x35, 0x78, 0x2b, 0x6b,
517 0x6a, 0x5a, 0x46, 0x77, 0x38, 0x70, 0x45, 0x48, 0x74, 0x35, 0x51, 0x0a,
518 0x69, 0x68, 0x62, 0x46, 0x4c, 0x35, 0x58, 0x2b, 0x57, 0x7a, 0x6f, 0x2b,
519 0x42, 0x36, 0x36, 0x59, 0x79, 0x49, 0x76, 0x68, 0x77, 0x54, 0x63, 0x48,
520 0x30, 0x46, 0x2b, 0x6e, 0x66, 0x55, 0x71, 0x66, 0x74, 0x38, 0x59, 0x74,
521 0x72, 0x2f, 0x38, 0x37, 0x47, 0x45, 0x62, 0x73, 0x41, 0x48, 0x6a, 0x48,
522 0x43, 0x36, 0x4c, 0x2b, 0x77, 0x6b, 0x31, 0x76, 0x4e, 0x6e, 0x64, 0x49,
523 0x59, 0x47, 0x30, 0x51, 0x0a, 0x79, 0x62, 0x73, 0x7a, 0x78, 0x49, 0x72,
524 0x32, 0x6d, 0x46, 0x45, 0x49, 0x4a, 0x6f, 0x69, 0x51, 0x44, 0x44, 0x67,
525 0x66, 0x6c, 0x71, 0x67, 0x64, 0x76, 0x4c, 0x54, 0x32, 0x79, 0x64, 0x46,
526 0x6d, 0x79, 0x33, 0x73, 0x32, 0x68, 0x49, 0x74, 0x51, 0x6c, 0x49, 0x71,
527 0x4b, 0x4c, 0x42, 0x36, 0x49, 0x4a, 0x51, 0x49, 0x75, 0x69, 0x37, 0x72,
528 0x37, 0x34, 0x76, 0x64, 0x72, 0x63, 0x58, 0x71, 0x58, 0x0a, 0x44, 0x7a,
529 0x68, 0x6d, 0x4c, 0x66, 0x67, 0x6a, 0x67, 0x4c, 0x77, 0x33, 0x2b, 0x55,
530 0x79, 0x69, 0x59, 0x74, 0x44, 0x54, 0x76, 0x63, 0x78, 0x65, 0x7a, 0x62,
531 0x4c, 0x73, 0x76, 0x51, 0x6f, 0x52, 0x6b, 0x74, 0x77, 0x4b, 0x5a, 0x4c,
532 0x44, 0x54, 0x42, 0x42, 0x35, 0x76, 0x59, 0x32, 0x78, 0x4b, 0x36, 0x6b,
533 0x4f, 0x4f, 0x44, 0x70, 0x7a, 0x50, 0x48, 0x73, 0x4b, 0x67, 0x30, 0x42,
534 0x59, 0x77, 0x0a, 0x4d, 0x6b, 0x48, 0x56, 0x56, 0x54, 0x34, 0x79, 0x2f,
535 0x4d, 0x59, 0x36, 0x63, 0x63, 0x4b, 0x51, 0x2f, 0x4c, 0x56, 0x74, 0x32,
536 0x66, 0x4a, 0x49, 0x74, 0x69, 0x41, 0x71, 0x49, 0x47, 0x32, 0x38, 0x64,
537 0x37, 0x31, 0x53, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44,
538 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
539 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a
542 static void testCertTrust(SAFE_PROVIDER_FUNCTIONS
*funcs
, GUID
*actionID
)
544 CRYPT_PROVIDER_DATA data
= { 0 };
545 CRYPT_PROVIDER_SGNR sgnr
= { sizeof(sgnr
), { 0 } };
549 if (!CertFreeCertificateChain_p
)
551 win_skip("CertFreeCertificateChain not found\n");
555 data
.padwTrustStepErrors
=
556 funcs
->pfnAlloc(TRUSTERROR_MAX_STEPS
* sizeof(DWORD
));
557 if (!data
.padwTrustStepErrors
)
559 skip("pfnAlloc failed\n");
562 ret
= funcs
->pfnCertificateTrust(&data
);
563 ok(ret
== S_FALSE
, "Expected S_FALSE, got %08x\n", ret
);
564 ok(data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_CERTPROV
] ==
565 TRUST_E_NOSIGNATURE
, "Expected TRUST_E_NOSIGNATURE, got %08x\n",
566 data
.padwTrustStepErrors
[TRUSTERROR_STEP_FINAL_CERTPROV
]);
567 b
= funcs
->pfnAddSgnr2Chain(&data
, FALSE
, 0, &sgnr
);
572 /* An empty signer "succeeds," even though there's no cert */
573 ret
= funcs
->pfnCertificateTrust(&data
);
574 ok(ret
== S_OK
, "Expected S_OK, got %08x\n", ret
);
575 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, selfSignedCert
,
576 sizeof(selfSignedCert
));
579 WINTRUST_DATA wintrust_data
= { 0 };
581 b
= funcs
->pfnAddCert2Chain(&data
, 0, FALSE
, 0, cert
);
582 ok(b
== TRUE
, "Expected TRUE, got %d\n", b
);
584 /* If pWintrustData isn't set, crashes attempting to access
585 * pWintrustData->fdwRevocationChecks
587 data
.pWintrustData
= &wintrust_data
;
588 /* If psPfns isn't set, crashes attempting to access
589 * psPfns->pfnCertCheckPolicy
591 data
.psPfns
= (CRYPT_PROVIDER_FUNCTIONS
*)funcs
;
592 ret
= funcs
->pfnCertificateTrust(&data
);
593 ok(ret
== S_OK
, "Expected S_OK, got %08x\n", ret
);
594 ok(data
.csSigners
== 1, "Unexpected number of signers %d\n",
596 ok(data
.pasSigners
[0].pChainContext
!= NULL
,
597 "Expected a certificate chain\n");
598 ok(data
.pasSigners
[0].csCertChain
== 1,
599 "Unexpected number of chain elements %d\n",
600 data
.pasSigners
[0].csCertChain
);
601 /* pasSigners and pasSigners[0].pasCertChain are guaranteed to be
602 * initialized, see tests for pfnAddSgnr2Chain and pfnAddCert2Chain
604 ok(!data
.pasSigners
[0].pasCertChain
[0].fTrustedRoot
,
605 "Didn't expect cert to be trusted\n");
606 ok(data
.pasSigners
[0].pasCertChain
[0].fSelfSigned
,
607 "Expected cert to be self-signed\n");
608 ok(data
.pasSigners
[0].pasCertChain
[0].dwConfidence
==
609 (CERT_CONFIDENCE_SIG
| CERT_CONFIDENCE_TIMENEST
),
610 "Expected CERT_CONFIDENCE_SIG | CERT_CONFIDENCE_TIMENEST, got %08x\n",
611 data
.pasSigners
[0].pasCertChain
[0].dwConfidence
);
612 CertFreeCertificateContext(
613 data
.pasSigners
[0].pasCertChain
[0].pCert
);
614 CertFreeCertificateChain_p(data
.pasSigners
[0].pChainContext
);
615 CertFreeCertificateContext(cert
);
618 funcs
->pfnFree(data
.padwTrustStepErrors
);
621 static void test_provider_funcs(void)
623 static GUID generic_verify_v2
= WINTRUST_ACTION_GENERIC_VERIFY_V2
;
624 SAFE_PROVIDER_FUNCTIONS funcs
= { sizeof(SAFE_PROVIDER_FUNCTIONS
), 0 };
627 ret
= WintrustLoadFunctionPointers(&generic_verify_v2
,
628 (CRYPT_PROVIDER_FUNCTIONS
*)&funcs
);
630 skip("WintrustLoadFunctionPointers failed\n");
634 testInitialize(&funcs
, &generic_verify_v2
);
635 testObjTrust(&funcs
, &generic_verify_v2
);
636 testCertTrust(&funcs
, &generic_verify_v2
);
640 /* minimal PE file image */
641 #define VA_START 0x400000
642 #define FILE_PE_START 0x50
643 #define NUM_SECTIONS 3
644 #define FILE_TEXT 0x200
645 #define RVA_TEXT 0x1000
646 #define RVA_BSS 0x2000
647 #define FILE_IDATA 0x400
648 #define RVA_IDATA 0x3000
649 #define FILE_TOTAL 0x600
650 #define RVA_TOTAL 0x4000
651 #include <pshpack1.h>
653 IMAGE_IMPORT_DESCRIPTOR descriptors
[2];
654 IMAGE_THUNK_DATA32 original_thunks
[2];
655 IMAGE_THUNK_DATA32 thunks
[2];
656 struct __IMPORT_BY_NAME
{
662 #define EXIT_PROCESS (VA_START+RVA_IDATA+FIELD_OFFSET(struct Imports, thunks))
664 static struct _PeImage
{
665 IMAGE_DOS_HEADER dos_header
;
666 char __alignment1
[FILE_PE_START
- sizeof(IMAGE_DOS_HEADER
)];
667 IMAGE_NT_HEADERS32 nt_headers
;
668 IMAGE_SECTION_HEADER sections
[NUM_SECTIONS
];
669 char __alignment2
[FILE_TEXT
- FILE_PE_START
- sizeof(IMAGE_NT_HEADERS32
) -
670 NUM_SECTIONS
* sizeof(IMAGE_SECTION_HEADER
)];
671 unsigned char text_section
[FILE_IDATA
-FILE_TEXT
];
672 struct Imports idata_section
;
673 char __alignment3
[FILE_TOTAL
-FILE_IDATA
-sizeof(struct Imports
)];
676 {IMAGE_DOS_SIGNATURE
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, 0, {0}, FILE_PE_START
},
677 /* alignment before PE header */
681 /* basic headers - 3 sections, no symbols, EXE file */
682 {IMAGE_FILE_MACHINE_I386
, NUM_SECTIONS
, 0, 0, 0, sizeof(IMAGE_OPTIONAL_HEADER32
),
683 IMAGE_FILE_32BIT_MACHINE
| IMAGE_FILE_EXECUTABLE_IMAGE
},
684 /* optional header */
685 {IMAGE_NT_OPTIONAL_HDR32_MAGIC
, 4, 0, FILE_IDATA
-FILE_TEXT
,
686 FILE_TOTAL
-FILE_IDATA
+ FILE_IDATA
-FILE_TEXT
, 0x400,
687 RVA_TEXT
, RVA_TEXT
, RVA_BSS
, VA_START
, 0x1000, 0x200, 4, 0, 1, 0, 4, 0, 0,
688 RVA_TOTAL
, FILE_TEXT
, 0, IMAGE_SUBSYSTEM_WINDOWS_GUI
, 0,
689 0x200000, 0x1000, 0x100000, 0x1000, 0, 0x10,
691 {RVA_IDATA
, sizeof(struct Imports
)}
697 {".text", {0x100}, RVA_TEXT
, FILE_IDATA
-FILE_TEXT
, FILE_TEXT
,
698 0, 0, 0, 0, IMAGE_SCN_CNT_CODE
| IMAGE_SCN_MEM_EXECUTE
| IMAGE_SCN_MEM_READ
},
699 {".bss", {0x400}, RVA_BSS
, 0, 0, 0, 0, 0, 0,
700 IMAGE_SCN_CNT_UNINITIALIZED_DATA
| IMAGE_SCN_MEM_READ
| IMAGE_SCN_MEM_WRITE
},
701 {".idata", {sizeof(struct Imports
)}, RVA_IDATA
, FILE_TOTAL
-FILE_IDATA
, FILE_IDATA
, 0,
702 0, 0, 0, IMAGE_SCN_CNT_INITIALIZED_DATA
| IMAGE_SCN_MEM_READ
| IMAGE_SCN_MEM_WRITE
}
704 /* alignment before first section */
708 0x31, 0xC0, /* xor eax, eax */
709 0xFF, 0x25, EXIT_PROCESS
&0xFF, (EXIT_PROCESS
>>8)&0xFF, (EXIT_PROCESS
>>16)&0xFF,
710 (EXIT_PROCESS
>>24)&0xFF, /* jmp ExitProcess */
716 {{RVA_IDATA
+ FIELD_OFFSET(struct Imports
, original_thunks
)}, 0, 0,
717 RVA_IDATA
+ FIELD_OFFSET(struct Imports
, dllname
),
718 RVA_IDATA
+ FIELD_OFFSET(struct Imports
, thunks
)
722 {{{RVA_IDATA
+FIELD_OFFSET(struct Imports
, ibn
)}}, {{0}}},
723 {{{RVA_IDATA
+FIELD_OFFSET(struct Imports
, ibn
)}}, {{0}}},
727 /* final alignment */
732 static void test_sip_create_indirect_data(void)
734 static GUID unknown
= { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
735 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
736 static char oid_sha1
[] = szOID_OIWSEC_sha1
;
738 SIP_SUBJECTINFO subjinfo
= { 0 };
739 WCHAR temp_file
[MAX_PATH
];
743 if (!CryptSIPCreateIndirectData_p
)
745 skip("Missing CryptSIPCreateIndirectData\n");
748 SetLastError(0xdeadbeef);
749 ret
= CryptSIPCreateIndirectData_p(NULL
, NULL
, NULL
);
750 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
751 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
752 SetLastError(0xdeadbeef);
753 ret
= CryptSIPCreateIndirectData_p(&subjinfo
, NULL
, NULL
);
754 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
755 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
756 subjinfo
.cbSize
= sizeof(subjinfo
);
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 file
= create_temp_file(temp_file
);
762 if (file
== INVALID_HANDLE_VALUE
)
764 skip("couldn't create temp file\n");
767 WriteFile(file
, &bin
, sizeof(bin
), &count
, NULL
);
768 FlushFileBuffers(file
);
770 subjinfo
.hFile
= file
;
771 SetLastError(0xdeadbeef);
772 ret
= CryptSIPCreateIndirectData_p(&subjinfo
, NULL
, NULL
);
773 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
774 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
775 subjinfo
.pgSubjectType
= &unknown
;
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());
781 SetLastError(0xdeadbeef);
782 ret
= CryptSIPCreateIndirectData_p(&subjinfo
, &count
, NULL
);
784 ok(!ret
&& (GetLastError() == NTE_BAD_ALGID
||
785 GetLastError() == ERROR_INVALID_PARAMETER
/* Win7 */),
786 "expected NTE_BAD_ALGID or ERROR_INVALID_PARAMETER, got %08x\n",
788 ok(count
== 0xdeadbeef, "expected count to be unmodified, got %d\n", count
);
789 subjinfo
.DigestAlgorithm
.pszObjId
= oid_sha1
;
791 ret
= CryptSIPCreateIndirectData_p(&subjinfo
, &count
, NULL
);
793 ok(ret
, "CryptSIPCreateIndirectData failed: %d\n", GetLastError());
794 ok(count
, "expected a positive count\n");
797 SIP_INDIRECT_DATA
*indirect
= HeapAlloc(GetProcessHeap(), 0, count
);
800 ret
= CryptSIPCreateIndirectData_p(&subjinfo
, &count
, indirect
);
801 ok(ret
, "CryptSIPCreateIndirectData failed: %d\n", GetLastError());
802 /* If the count is larger than needed, it's unmodified */
803 ok(count
== 256, "unexpected count %d\n", count
);
804 ok(!strcmp(indirect
->Data
.pszObjId
, SPC_PE_IMAGE_DATA_OBJID
),
805 "unexpected data oid %s\n",
806 indirect
->Data
.pszObjId
);
807 ok(!strcmp(indirect
->DigestAlgorithm
.pszObjId
, oid_sha1
),
808 "unexpected digest algorithm oid %s\n",
809 indirect
->DigestAlgorithm
.pszObjId
);
810 ok(indirect
->Digest
.cbData
== 20, "unexpected hash size %d\n",
811 indirect
->Digest
.cbData
);
812 if (indirect
->Digest
.cbData
== 20)
814 const BYTE hash
[20] = {
815 0x8a,0xd5,0x45,0x53,0x3d,0x67,0xdf,0x2f,0x78,0xe0,
816 0x55,0x0a,0xe0,0xd9,0x7a,0x28,0x3e,0xbf,0x45,0x2b };
818 ok(!memcmp(indirect
->Digest
.pbData
, hash
, 20),
819 "unexpected value\n");
822 HeapFree(GetProcessHeap(), 0, indirect
);
825 DeleteFileW(temp_file
);
828 static void test_wintrust(void)
830 static GUID generic_action_v2
= WINTRUST_ACTION_GENERIC_VERIFY_V2
;
832 WINTRUST_FILE_INFO file
;
835 WCHAR pathW
[MAX_PATH
];
837 memset(&wtd
, 0, sizeof(wtd
));
838 wtd
.cbStruct
= sizeof(wtd
);
839 wtd
.dwUIChoice
= WTD_UI_NONE
;
840 wtd
.fdwRevocationChecks
= WTD_REVOKE_WHOLECHAIN
;
841 wtd
.dwUnionChoice
= WTD_CHOICE_FILE
;
842 U(wtd
).pFile
= &file
;
843 wtd
.dwStateAction
= WTD_STATEACTION_VERIFY
;
844 memset(&file
, 0, sizeof(file
));
845 file
.cbStruct
= sizeof(file
);
846 file
.pcwszFilePath
= pathW
;
847 /* Test with an empty file */
848 file
.hFile
= create_temp_file(pathW
);
849 r
= WinVerifyTrust(INVALID_HANDLE_VALUE
, &generic_action_v2
, &wtd
);
850 ok(r
== TRUST_E_SUBJECT_FORM_UNKNOWN
,
851 "expected TRUST_E_SUBJECT_FORM_UNKNOWN, got %08x\n", r
);
852 CloseHandle(file
.hFile
);
855 /* Test with a known file path, which we expect not have a signature */
856 getNotepadPath(pathW
, MAX_PATH
);
857 r
= WinVerifyTrust(INVALID_HANDLE_VALUE
, &generic_action_v2
, &wtd
);
858 ok(r
== TRUST_E_NOSIGNATURE
|| r
== CRYPT_E_FILE_ERROR
,
859 "expected TRUST_E_NOSIGNATURE or CRYPT_E_FILE_ERROR, got %08x\n", r
);
860 wtd
.dwStateAction
= WTD_STATEACTION_CLOSE
;
861 r
= WinVerifyTrust(INVALID_HANDLE_VALUE
, &generic_action_v2
, &wtd
);
862 ok(r
== S_OK
, "WinVerifyTrust failed: %08x\n", r
);
863 wtd
.dwStateAction
= WTD_STATEACTION_VERIFY
;
864 hr
= WinVerifyTrustEx(INVALID_HANDLE_VALUE
, &generic_action_v2
, &wtd
);
865 ok(hr
== TRUST_E_NOSIGNATURE
|| hr
== CRYPT_E_FILE_ERROR
,
866 "expected TRUST_E_NOSIGNATURE or CRYPT_E_FILE_ERROR, got %08x\n", hr
);
867 wtd
.dwStateAction
= WTD_STATEACTION_CLOSE
;
868 r
= WinVerifyTrust(INVALID_HANDLE_VALUE
, &generic_action_v2
, &wtd
);
869 ok(r
== S_OK
, "WinVerifyTrust failed: %08x\n", r
);
872 static void test_get_known_usages(void)
875 PCCRYPT_OID_INFO
*usages
;
877 if (!pWTHelperGetKnownUsages
)
879 skip("missing WTHelperGetKnownUsages\n");
882 SetLastError(0xdeadbeef);
883 ret
= pWTHelperGetKnownUsages(0, NULL
);
884 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
885 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
886 SetLastError(0xdeadbeef);
887 ret
= pWTHelperGetKnownUsages(1, NULL
);
888 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
889 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
890 SetLastError(0xdeadbeef);
891 ret
= pWTHelperGetKnownUsages(0, &usages
);
892 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
893 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
894 /* A value of 1 for the first parameter seems to imply the value is
897 SetLastError(0xdeadbeef);
899 ret
= pWTHelperGetKnownUsages(1, &usages
);
900 ok(ret
, "WTHelperGetKnownUsages failed: %d\n", GetLastError());
901 ok(usages
!= NULL
, "expected a pointer\n");
904 PCCRYPT_OID_INFO
*ptr
;
906 /* The returned usages are an array of PCCRYPT_OID_INFOs, terminated with a
909 for (ptr
= usages
; *ptr
; ptr
++)
911 ok((*ptr
)->cbSize
== sizeof(CRYPT_OID_INFO
) ||
912 (*ptr
)->cbSize
== (sizeof(CRYPT_OID_INFO
) + 2 * sizeof(LPCWSTR
)), /* Vista */
913 "unexpected size %d\n", (*ptr
)->cbSize
);
914 /* Each returned usage is in the CRYPT_ENHKEY_USAGE_OID_GROUP_ID group */
915 ok((*ptr
)->dwGroupId
== CRYPT_ENHKEY_USAGE_OID_GROUP_ID
,
916 "expected group CRYPT_ENHKEY_USAGE_OID_GROUP_ID, got %d\n",
920 /* A value of 2 for the second parameter seems to imply the value is freed
922 SetLastError(0xdeadbeef);
923 ret
= pWTHelperGetKnownUsages(2, &usages
);
924 ok(ret
, "WTHelperGetKnownUsages failed: %d\n", GetLastError());
925 ok(usages
== NULL
, "expected pointer to be cleared\n");
926 SetLastError(0xdeadbeef);
928 ret
= pWTHelperGetKnownUsages(2, &usages
);
929 ok(ret
, "WTHelperGetKnownUsages failed: %d\n", GetLastError());
930 SetLastError(0xdeadbeef);
931 ret
= pWTHelperGetKnownUsages(2, NULL
);
932 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
933 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
939 test_provider_funcs();
940 test_sip_create_indirect_data();
942 test_get_known_usages();