push cea036dc4aae50c232dc1391dcc459ff0b060bcf
[wine/hacks.git] / dlls / wintrust / tests / softpub.c
blob5c5d892d45d9c0acd1c0d7f4c13a1b7d0772bd4a
1 /*
2 * wintrust softpub functions tests
4 * Copyright 2007 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <assert.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winerror.h>
26 #include <wintrust.h>
27 #include <softpub.h>
28 #include <mssip.h>
29 #include <winuser.h>
30 #include "winnls.h"
32 #include "wine/test.h"
34 /* Just in case we're being built with borked headers, redefine function
35 * pointers to have the correct calling convention.
37 typedef void *(WINAPI *SAFE_MEM_ALLOC)(DWORD);
38 typedef void (WINAPI *SAFE_MEM_FREE)(void *);
39 typedef BOOL (WINAPI *SAFE_ADD_STORE)(CRYPT_PROVIDER_DATA *,
40 HCERTSTORE);
41 typedef BOOL (WINAPI *SAFE_ADD_SGNR)(CRYPT_PROVIDER_DATA *,
42 BOOL, DWORD, struct _CRYPT_PROVIDER_SGNR *);
43 typedef BOOL (WINAPI *SAFE_ADD_CERT)(CRYPT_PROVIDER_DATA *,
44 DWORD, BOOL, DWORD, PCCERT_CONTEXT);
45 typedef BOOL (WINAPI *SAFE_ADD_PRIVDATA)(CRYPT_PROVIDER_DATA *,
46 CRYPT_PROVIDER_PRIVDATA *);
47 typedef HRESULT (WINAPI *SAFE_PROVIDER_INIT_CALL)(CRYPT_PROVIDER_DATA *);
48 typedef HRESULT (WINAPI *SAFE_PROVIDER_OBJTRUST_CALL)(CRYPT_PROVIDER_DATA *);
49 typedef HRESULT (WINAPI *SAFE_PROVIDER_SIGTRUST_CALL)(CRYPT_PROVIDER_DATA *);
50 typedef HRESULT (WINAPI *SAFE_PROVIDER_CERTTRUST_CALL)(CRYPT_PROVIDER_DATA *);
51 typedef HRESULT (WINAPI *SAFE_PROVIDER_FINALPOLICY_CALL)(CRYPT_PROVIDER_DATA *);
52 typedef HRESULT (WINAPI *SAFE_PROVIDER_TESTFINALPOLICY_CALL)(
53 CRYPT_PROVIDER_DATA *);
54 typedef HRESULT (WINAPI *SAFE_PROVIDER_CLEANUP_CALL)(CRYPT_PROVIDER_DATA *);
55 typedef BOOL (WINAPI *SAFE_PROVIDER_CERTCHKPOLICY_CALL)(
56 CRYPT_PROVIDER_DATA *, DWORD, BOOL, DWORD);
58 typedef struct _SAFE_PROVIDER_FUNCTIONS
60 DWORD cbStruct;
61 SAFE_MEM_ALLOC pfnAlloc;
62 SAFE_MEM_FREE pfnFree;
63 SAFE_ADD_STORE pfnAddStore2Chain;
64 SAFE_ADD_SGNR pfnAddSgnr2Chain;
65 SAFE_ADD_CERT pfnAddCert2Chain;
66 SAFE_ADD_PRIVDATA pfnAddPrivData2Chain;
67 SAFE_PROVIDER_INIT_CALL pfnInitialize;
68 SAFE_PROVIDER_OBJTRUST_CALL pfnObjectTrust;
69 SAFE_PROVIDER_SIGTRUST_CALL pfnSignatureTrust;
70 SAFE_PROVIDER_CERTTRUST_CALL pfnCertificateTrust;
71 SAFE_PROVIDER_FINALPOLICY_CALL pfnFinalPolicy;
72 SAFE_PROVIDER_CERTCHKPOLICY_CALL pfnCertCheckPolicy;
73 SAFE_PROVIDER_TESTFINALPOLICY_CALL pfnTestFinalPolicy;
74 struct _CRYPT_PROVUI_FUNCS *psUIpfns;
75 SAFE_PROVIDER_CLEANUP_CALL pfnCleanupPolicy;
76 } SAFE_PROVIDER_FUNCTIONS;
78 static const BYTE v1CertWithPubKey[] = {
79 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
80 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
81 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
82 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
83 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
84 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
85 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
86 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
87 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
88 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
89 0x01,0x01 };
91 static void test_utils(SAFE_PROVIDER_FUNCTIONS *funcs)
93 CRYPT_PROVIDER_DATA data = { 0 };
94 HCERTSTORE store;
95 CRYPT_PROVIDER_SGNR sgnr = { 0 };
96 BOOL ret;
98 /* Crash
99 ret = funcs->pfnAddStore2Chain(NULL, NULL);
100 ret = funcs->pfnAddStore2Chain(&data, NULL);
102 store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
103 CERT_STORE_CREATE_NEW_FLAG, NULL);
104 if (store)
106 ret = funcs->pfnAddStore2Chain(&data, store);
107 ok(ret, "pfnAddStore2Chain failed: %08x\n", GetLastError());
108 ok(data.chStores == 1, "Expected 1 store, got %d\n", data.chStores);
109 ok(data.pahStores != NULL, "Expected pahStores to be allocated\n");
110 if (data.pahStores)
112 ok(data.pahStores[0] == store, "Unexpected store\n");
113 CertCloseStore(data.pahStores[0], 0);
114 funcs->pfnFree(data.pahStores);
115 data.pahStores = NULL;
116 data.chStores = 0;
117 CertCloseStore(store, 0);
118 store = NULL;
121 else
122 skip("CertOpenStore failed: %08x\n", GetLastError());
124 /* Crash
125 ret = funcs->pfnAddSgnr2Chain(NULL, FALSE, 0, NULL);
126 ret = funcs->pfnAddSgnr2Chain(&data, FALSE, 0, NULL);
128 ret = funcs->pfnAddSgnr2Chain(&data, FALSE, 0, &sgnr);
129 ok(ret, "pfnAddSgnr2Chain failed: %08x\n", GetLastError());
130 ok(data.csSigners == 1, "Expected 1 signer, got %d\n", data.csSigners);
131 ok(data.pasSigners != NULL, "Expected pasSigners to be allocated\n");
132 if (data.pasSigners)
134 PCCERT_CONTEXT cert;
136 ok(!memcmp(&data.pasSigners[0], &sgnr, sizeof(sgnr)),
137 "Unexpected data in signer\n");
138 /* Adds into the location specified by the index */
139 sgnr.cbStruct = sizeof(CRYPT_PROVIDER_SGNR);
140 sgnr.sftVerifyAsOf.dwLowDateTime = 0xdeadbeef;
141 ret = funcs->pfnAddSgnr2Chain(&data, FALSE, 1, &sgnr);
142 ok(ret, "pfnAddSgnr2Chain failed: %08x\n", GetLastError());
143 ok(data.csSigners == 2, "Expected 2 signers, got %d\n", data.csSigners);
144 ok(!memcmp(&data.pasSigners[1], &sgnr, sizeof(sgnr)),
145 "Unexpected data in signer\n");
146 /* This also adds, but the data aren't copied */
147 sgnr.cbStruct = sizeof(DWORD);
148 ret = funcs->pfnAddSgnr2Chain(&data, FALSE, 0, &sgnr);
149 ok(ret, "pfnAddSgnr2Chain failed: %08x\n", GetLastError());
150 ok(data.csSigners == 3, "Expected 3 signers, got %d\n", data.csSigners);
151 ok(data.pasSigners[0].cbStruct == 0, "Unexpected data size %d\n",
152 data.pasSigners[0].cbStruct);
153 ok(data.pasSigners[0].sftVerifyAsOf.dwLowDateTime == 0,
154 "Unexpected verify time %d\n",
155 data.pasSigners[0].sftVerifyAsOf.dwLowDateTime);
156 /* But too large a thing isn't added */
157 sgnr.cbStruct = sizeof(sgnr) + sizeof(DWORD);
158 SetLastError(0xdeadbeef);
159 ret = funcs->pfnAddSgnr2Chain(&data, FALSE, 0, &sgnr);
160 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
161 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
163 /* Crash
164 ret = funcs->pfnAddCert2Chain(NULL, 0, FALSE, 0, NULL);
165 ret = funcs->pfnAddCert2Chain(&data, 0, FALSE, 0, NULL);
167 cert = CertCreateCertificateContext(X509_ASN_ENCODING, v1CertWithPubKey,
168 sizeof(v1CertWithPubKey));
169 if (cert)
171 /* Notes on behavior that are hard to test:
172 * 1. If pasSigners is invalid, pfnAddCert2Chain crashes
173 * 2. An invalid signer index isn't checked.
175 ret = funcs->pfnAddCert2Chain(&data, 0, FALSE, 0, cert);
176 ok(ret, "pfnAddCert2Chain failed: %08x\n", GetLastError());
177 ok(data.pasSigners[0].csCertChain == 1, "Expected 1 cert, got %d\n",
178 data.pasSigners[0].csCertChain);
179 ok(data.pasSigners[0].pasCertChain != NULL,
180 "Expected pasCertChain to be allocated\n");
181 if (data.pasSigners[0].pasCertChain)
182 ok(data.pasSigners[0].pasCertChain[0].pCert == cert,
183 "Unexpected cert\n");
184 CertFreeCertificateContext(cert);
186 else
187 skip("CertCreateCertificateContext failed: %08x\n", GetLastError());
191 static void testInitialize(SAFE_PROVIDER_FUNCTIONS *funcs, GUID *actionID)
193 HRESULT ret;
194 CRYPT_PROVIDER_DATA data = { 0 };
195 WINTRUST_DATA wintrust_data = { 0 };
197 if (!funcs->pfnInitialize)
199 skip("missing pfnInitialize\n");
200 return;
203 /* Crashes
204 ret = funcs->pfnInitialize(NULL);
206 memset(&data, 0, sizeof(data));
207 ret = funcs->pfnInitialize(&data);
208 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
209 data.padwTrustStepErrors =
210 funcs->pfnAlloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
211 /* Without wintrust data set, crashes when padwTrustStepErrors is set */
212 data.pWintrustData = &wintrust_data;
213 if (data.padwTrustStepErrors)
215 /* Apparently, cdwTrustStepErrors does not need to be set. */
216 ret = funcs->pfnInitialize(&data);
217 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
218 data.cdwTrustStepErrors = 1;
219 ret = funcs->pfnInitialize(&data);
220 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
221 memset(data.padwTrustStepErrors, 0xba,
222 TRUSTERROR_MAX_STEPS * sizeof(DWORD));
223 ret = funcs->pfnInitialize(&data);
224 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
225 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT] = 0;
226 ret = funcs->pfnInitialize(&data);
227 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
228 funcs->pfnFree(data.padwTrustStepErrors);
232 static void getNotepadPath(WCHAR *notepadPathW, DWORD size)
234 static const CHAR notepad[] = "\\notepad.exe";
235 CHAR notepadPath[MAX_PATH];
237 /* Workaround missing W-functions for win9x */
238 GetWindowsDirectoryA(notepadPath, MAX_PATH);
239 lstrcatA(notepadPath, notepad);
240 MultiByteToWideChar(0, 0, notepadPath, -1, notepadPathW, size);
243 static void testObjTrust(SAFE_PROVIDER_FUNCTIONS *funcs, GUID *actionID)
245 HRESULT ret;
246 CRYPT_PROVIDER_DATA data = { 0 };
247 WINTRUST_DATA wintrust_data = { 0 };
248 WINTRUST_CERT_INFO certInfo = { sizeof(WINTRUST_CERT_INFO), 0 };
249 WINTRUST_FILE_INFO fileInfo = { sizeof(WINTRUST_FILE_INFO), 0 };
251 if (!funcs->pfnObjectTrust)
253 skip("missing pfnObjectTrust\n");
254 return;
257 /* Crashes
258 ret = funcs->pfnObjectTrust(NULL);
260 data.pWintrustData = &wintrust_data;
261 data.padwTrustStepErrors =
262 funcs->pfnAlloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
263 if (data.padwTrustStepErrors)
265 WCHAR notepadPathW[MAX_PATH];
266 PROVDATA_SIP provDataSIP = { 0 };
267 static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,
268 0x00,0xC0,0x4F,0xC2,0x95,0xEE } };
270 ret = funcs->pfnObjectTrust(&data);
271 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
272 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
273 ERROR_INVALID_PARAMETER,
274 "Expected ERROR_INVALID_PARAMETER, got %08x\n",
275 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
276 U(wintrust_data).pCert = &certInfo;
277 wintrust_data.dwUnionChoice = WTD_CHOICE_CERT;
278 ret = funcs->pfnObjectTrust(&data);
279 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
280 certInfo.psCertContext = (PCERT_CONTEXT)CertCreateCertificateContext(
281 X509_ASN_ENCODING, v1CertWithPubKey, sizeof(v1CertWithPubKey));
282 ret = funcs->pfnObjectTrust(&data);
283 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
284 CertFreeCertificateContext(certInfo.psCertContext);
285 certInfo.psCertContext = NULL;
286 wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
287 U(wintrust_data).pFile = NULL;
288 ret = funcs->pfnObjectTrust(&data);
289 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
290 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
291 ERROR_INVALID_PARAMETER,
292 "Expected ERROR_INVALID_PARAMETER, got %08x\n",
293 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
294 U(wintrust_data).pFile = &fileInfo;
295 /* Crashes
296 ret = funcs->pfnObjectTrust(&data);
298 getNotepadPath(notepadPathW, MAX_PATH);
299 fileInfo.pcwszFilePath = notepadPathW;
300 /* pfnObjectTrust now crashes unless both pPDSip and psPfns are set */
301 U(data).pPDSip = &provDataSIP;
302 data.psPfns = (CRYPT_PROVIDER_FUNCTIONS *)funcs;
303 ret = funcs->pfnObjectTrust(&data);
304 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
305 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
306 TRUST_E_NOSIGNATURE, "Expected TRUST_E_NOSIGNATURE, got %08x\n",
307 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
308 ok(!memcmp(&provDataSIP.gSubject, &unknown, sizeof(unknown)),
309 "Unexpected subject GUID\n");
310 ok(provDataSIP.pSip != NULL, "Expected a SIP\n");
311 ok(provDataSIP.psSipSubjectInfo != NULL, "Expected a subject info\n");
312 funcs->pfnFree(data.padwTrustStepErrors);
316 static const BYTE selfSignedCert[] = {
317 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
318 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
319 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
320 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
321 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
322 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
323 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
324 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
325 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
326 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
327 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
328 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
329 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
330 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
331 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
332 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
333 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
334 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
335 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
336 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
337 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
338 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
339 0xa8, 0x76, 0x57, 0x92, 0x36 };
341 static void testCertTrust(SAFE_PROVIDER_FUNCTIONS *funcs, GUID *actionID)
343 CRYPT_PROVIDER_DATA data = { 0 };
344 CRYPT_PROVIDER_SGNR sgnr = { sizeof(sgnr), { 0 } };
345 HRESULT ret;
347 data.padwTrustStepErrors =
348 funcs->pfnAlloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
349 if (!data.padwTrustStepErrors)
351 skip("pfnAlloc failed\n");
352 return;
354 ret = funcs->pfnCertificateTrust(&data);
355 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
356 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] ==
357 TRUST_E_NOSIGNATURE, "Expected TRUST_E_NOSIGNATURE, got %08x\n",
358 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV]);
359 ret = funcs->pfnAddSgnr2Chain(&data, FALSE, 0, &sgnr);
360 if (ret)
362 PCCERT_CONTEXT cert;
364 /* An empty signer "succeeds," even though there's no cert */
365 ret = funcs->pfnCertificateTrust(&data);
366 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
367 cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
368 sizeof(selfSignedCert));
369 if (cert)
371 WINTRUST_DATA wintrust_data = { 0 };
373 ret = funcs->pfnAddCert2Chain(&data, 0, FALSE, 0, cert);
374 /* If pWintrustData isn't set, crashes attempting to access
375 * pWintrustData->fdwRevocationChecks
377 data.pWintrustData = &wintrust_data;
378 /* If psPfns isn't set, crashes attempting to access
379 * psPfns->pfnCertCheckPolicy
381 data.psPfns = (CRYPT_PROVIDER_FUNCTIONS *)funcs;
382 ret = funcs->pfnCertificateTrust(&data);
383 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
384 ok(data.csSigners == 1, "Unexpected number of signers %d\n",
385 data.csSigners);
386 ok(data.pasSigners[0].pChainContext != NULL,
387 "Expected a certificate chain\n");
388 ok(data.pasSigners[0].csCertChain == 1,
389 "Unexpected number of chain elements %d\n",
390 data.pasSigners[0].csCertChain);
391 /* pasSigners and pasSigners[0].pasCertChain are guaranteed to be
392 * initialized, see tests for pfnAddSgnr2Chain and pfnAddCert2Chain
394 ok(!data.pasSigners[0].pasCertChain[0].fTrustedRoot,
395 "Didn't expect cert to be trusted\n");
396 ok(data.pasSigners[0].pasCertChain[0].fSelfSigned,
397 "Expected cert to be self-signed\n");
398 ok(data.pasSigners[0].pasCertChain[0].dwConfidence ==
399 (CERT_CONFIDENCE_SIG | CERT_CONFIDENCE_TIMENEST),
400 "Expected CERT_CONFIDENCE_SIG | CERT_CONFIDENCE_TIMENEST, got %08x\n",
401 data.pasSigners[0].pasCertChain[0].dwConfidence);
402 CertFreeCertificateContext(cert);
407 static void test_provider_funcs(void)
409 static GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
410 SAFE_PROVIDER_FUNCTIONS funcs = { sizeof(SAFE_PROVIDER_FUNCTIONS), 0 };
411 BOOL ret;
413 ret = WintrustLoadFunctionPointers(&generic_verify_v2,
414 (CRYPT_PROVIDER_FUNCTIONS *)&funcs);
415 if (!ret)
416 skip("WintrustLoadFunctionPointers failed\n");
417 else
419 test_utils(&funcs);
420 testInitialize(&funcs, &generic_verify_v2);
421 testObjTrust(&funcs, &generic_verify_v2);
422 testCertTrust(&funcs, &generic_verify_v2);
426 static void test_wintrust(void)
428 static GUID generic_action_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
429 WINTRUST_DATA wtd;
430 WINTRUST_FILE_INFO file;
431 LONG r;
432 HRESULT hr;
433 WCHAR notepadPathW[MAX_PATH];
435 memset(&wtd, 0, sizeof(wtd));
436 wtd.cbStruct = sizeof(wtd);
437 wtd.dwUIChoice = WTD_UI_NONE;
438 wtd.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN;
439 wtd.dwUnionChoice = WTD_CHOICE_FILE;
440 U(wtd).pFile = &file;
441 wtd.dwStateAction = WTD_STATEACTION_VERIFY;
442 memset(&file, 0, sizeof(file));
443 file.cbStruct = sizeof(file);
444 getNotepadPath(notepadPathW, MAX_PATH);
445 file.pcwszFilePath = notepadPathW;
446 r = WinVerifyTrust(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd);
447 ok(r == TRUST_E_NOSIGNATURE, "expected TRUST_E_NOSIGNATURE, got %08x\n", r);
448 hr = WinVerifyTrustEx(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd);
449 ok(hr == TRUST_E_NOSIGNATURE, "expected TRUST_E_NOSIGNATURE, got %08x\n",
450 hr);
453 static BOOL (WINAPI * pWTHelperGetKnownUsages)(DWORD action, PCCRYPT_OID_INFO **usages);
455 static void InitFunctionPtrs(void)
457 HMODULE hWintrust = GetModuleHandleA("wintrust.dll");
459 #define WINTRUST_GET_PROC(func) \
460 p ## func = (void*)GetProcAddress(hWintrust, #func); \
461 if(!p ## func) { \
462 trace("GetProcAddress(%s) failed\n", #func); \
465 WINTRUST_GET_PROC(WTHelperGetKnownUsages)
467 #undef WINTRUST_GET_PROC
470 static void test_get_known_usages(void)
472 BOOL ret;
473 PCCRYPT_OID_INFO *usages;
475 if (!pWTHelperGetKnownUsages)
477 skip("missing WTHelperGetKnownUsages\n");
478 return;
480 SetLastError(0xdeadbeef);
481 ret = pWTHelperGetKnownUsages(0, NULL);
482 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
483 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
484 SetLastError(0xdeadbeef);
485 ret = pWTHelperGetKnownUsages(1, NULL);
486 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
487 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
488 SetLastError(0xdeadbeef);
489 ret = pWTHelperGetKnownUsages(0, &usages);
490 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
491 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
492 /* A value of 1 for the first parameter seems to imply the value is
493 * allocated
495 SetLastError(0xdeadbeef);
496 usages = NULL;
497 ret = pWTHelperGetKnownUsages(1, &usages);
498 ok(ret, "WTHelperGetKnownUsages failed: %d\n", GetLastError());
499 ok(usages != NULL, "expected a pointer\n");
500 if (ret && usages)
502 PCCRYPT_OID_INFO *ptr;
504 /* The returned usages are an array of PCCRYPT_OID_INFOs, terminated with a
505 * NULL pointer.
507 for (ptr = usages; *ptr; ptr++)
509 ok((*ptr)->cbSize == sizeof(CRYPT_OID_INFO) ||
510 (*ptr)->cbSize == (sizeof(CRYPT_OID_INFO) + 2 * sizeof(LPCWSTR)), /* Vista */
511 "unexpected size %d\n", (*ptr)->cbSize);
512 /* Each returned usage is in the CRYPT_ENHKEY_USAGE_OID_GROUP_ID group */
513 ok((*ptr)->dwGroupId == CRYPT_ENHKEY_USAGE_OID_GROUP_ID,
514 "expected group CRYPT_ENHKEY_USAGE_OID_GROUP_ID, got %d\n",
515 (*ptr)->dwGroupId);
518 /* A value of 2 for the second parameter seems to imply the value is freed
520 SetLastError(0xdeadbeef);
521 ret = pWTHelperGetKnownUsages(2, &usages);
522 ok(ret, "WTHelperGetKnownUsages failed: %d\n", GetLastError());
523 ok(usages == NULL, "expected pointer to be cleared\n");
524 SetLastError(0xdeadbeef);
525 usages = NULL;
526 ret = pWTHelperGetKnownUsages(2, &usages);
527 ok(ret, "WTHelperGetKnownUsages failed: %d\n", GetLastError());
528 SetLastError(0xdeadbeef);
529 ret = pWTHelperGetKnownUsages(2, NULL);
530 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
531 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
534 START_TEST(softpub)
536 InitFunctionPtrs();
537 test_provider_funcs();
538 test_wintrust();
539 test_get_known_usages();