push 5bc4839baba05cc4333240c25295b8dd6e351557
[wine/hacks.git] / dlls / wintrust / tests / softpub.c
blobc60ccb3aa95eb981d696098f9a278e362c26d6a4
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 } };
269 static GUID bogusGuid = { 0xdeadbeef, 0xbaad, 0xf00d, { 0x00,0x00,0x00,
270 0x00,0x00,0x00,0x00,0x00 } };
272 ret = funcs->pfnObjectTrust(&data);
273 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
274 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
275 ERROR_INVALID_PARAMETER,
276 "Expected ERROR_INVALID_PARAMETER, got %08x\n",
277 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
278 U(wintrust_data).pCert = &certInfo;
279 wintrust_data.dwUnionChoice = WTD_CHOICE_CERT;
280 ret = funcs->pfnObjectTrust(&data);
281 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
282 certInfo.psCertContext = (PCERT_CONTEXT)CertCreateCertificateContext(
283 X509_ASN_ENCODING, v1CertWithPubKey, sizeof(v1CertWithPubKey));
284 ret = funcs->pfnObjectTrust(&data);
285 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
286 CertFreeCertificateContext(certInfo.psCertContext);
287 certInfo.psCertContext = NULL;
288 wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
289 U(wintrust_data).pFile = NULL;
290 ret = funcs->pfnObjectTrust(&data);
291 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
292 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
293 ERROR_INVALID_PARAMETER,
294 "Expected ERROR_INVALID_PARAMETER, got %08x\n",
295 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
296 U(wintrust_data).pFile = &fileInfo;
297 /* Crashes
298 ret = funcs->pfnObjectTrust(&data);
300 getNotepadPath(notepadPathW, MAX_PATH);
301 fileInfo.pcwszFilePath = notepadPathW;
302 /* pfnObjectTrust now crashes unless both pPDSip and psPfns are set */
303 U(data).pPDSip = &provDataSIP;
304 data.psPfns = (CRYPT_PROVIDER_FUNCTIONS *)funcs;
305 ret = funcs->pfnObjectTrust(&data);
306 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
307 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
308 TRUST_E_NOSIGNATURE ||
309 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
310 TRUST_E_SUBJECT_FORM_UNKNOWN,
311 "Expected TRUST_E_NOSIGNATURE or TRUST_E_SUBJECT_FORM_UNKNOWN, got %08x\n",
312 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
313 if (data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
314 TRUST_E_NOSIGNATURE)
316 ok(!memcmp(&provDataSIP.gSubject, &unknown, sizeof(unknown)),
317 "Unexpected subject GUID\n");
318 ok(provDataSIP.pSip != NULL, "Expected a SIP\n");
319 ok(provDataSIP.psSipSubjectInfo != NULL,
320 "Expected a subject info\n");
322 /* Specifying the GUID results in that GUID being the subject GUID */
323 fileInfo.pgKnownSubject = &bogusGuid;
324 ret = funcs->pfnObjectTrust(&data);
325 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
326 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
327 TRUST_E_NOSIGNATURE ||
328 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
329 TRUST_E_SUBJECT_FORM_UNKNOWN ||
330 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
331 TRUST_E_PROVIDER_UNKNOWN,
332 "Expected TRUST_E_NOSIGNATURE or TRUST_E_SUBJECT_FORM_UNKNOWN or TRUST_E_PROVIDER_UNKNOWN, got %08x\n",
333 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV]);
334 if (data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_OBJPROV] ==
335 TRUST_E_NOSIGNATURE)
337 ok(!memcmp(&provDataSIP.gSubject, &bogusGuid, sizeof(bogusGuid)),
338 "unexpected subject GUID\n");
340 /* Specifying a bogus GUID pointer crashes */
341 if (0)
343 fileInfo.pgKnownSubject = (GUID *)0xdeadbeef;
344 ret = funcs->pfnObjectTrust(&data);
346 funcs->pfnFree(data.padwTrustStepErrors);
350 static const BYTE selfSignedCert[] = {
351 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
352 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
353 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
354 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
355 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
356 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
357 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
358 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
359 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
360 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
361 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
362 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
363 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
364 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
365 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
366 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
367 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
368 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
369 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
370 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
371 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
372 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
373 0xa8, 0x76, 0x57, 0x92, 0x36 };
375 static void testCertTrust(SAFE_PROVIDER_FUNCTIONS *funcs, GUID *actionID)
377 CRYPT_PROVIDER_DATA data = { 0 };
378 CRYPT_PROVIDER_SGNR sgnr = { sizeof(sgnr), { 0 } };
379 HRESULT ret;
381 data.padwTrustStepErrors =
382 funcs->pfnAlloc(TRUSTERROR_MAX_STEPS * sizeof(DWORD));
383 if (!data.padwTrustStepErrors)
385 skip("pfnAlloc failed\n");
386 return;
388 ret = funcs->pfnCertificateTrust(&data);
389 ok(ret == S_FALSE, "Expected S_FALSE, got %08x\n", ret);
390 ok(data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV] ==
391 TRUST_E_NOSIGNATURE, "Expected TRUST_E_NOSIGNATURE, got %08x\n",
392 data.padwTrustStepErrors[TRUSTERROR_STEP_FINAL_CERTPROV]);
393 ret = funcs->pfnAddSgnr2Chain(&data, FALSE, 0, &sgnr);
394 if (ret)
396 PCCERT_CONTEXT cert;
398 /* An empty signer "succeeds," even though there's no cert */
399 ret = funcs->pfnCertificateTrust(&data);
400 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
401 cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
402 sizeof(selfSignedCert));
403 if (cert)
405 WINTRUST_DATA wintrust_data = { 0 };
407 ret = funcs->pfnAddCert2Chain(&data, 0, FALSE, 0, cert);
408 /* If pWintrustData isn't set, crashes attempting to access
409 * pWintrustData->fdwRevocationChecks
411 data.pWintrustData = &wintrust_data;
412 /* If psPfns isn't set, crashes attempting to access
413 * psPfns->pfnCertCheckPolicy
415 data.psPfns = (CRYPT_PROVIDER_FUNCTIONS *)funcs;
416 ret = funcs->pfnCertificateTrust(&data);
417 ok(ret == S_OK, "Expected S_OK, got %08x\n", ret);
418 ok(data.csSigners == 1, "Unexpected number of signers %d\n",
419 data.csSigners);
420 ok(data.pasSigners[0].pChainContext != NULL,
421 "Expected a certificate chain\n");
422 ok(data.pasSigners[0].csCertChain == 1,
423 "Unexpected number of chain elements %d\n",
424 data.pasSigners[0].csCertChain);
425 /* pasSigners and pasSigners[0].pasCertChain are guaranteed to be
426 * initialized, see tests for pfnAddSgnr2Chain and pfnAddCert2Chain
428 ok(!data.pasSigners[0].pasCertChain[0].fTrustedRoot,
429 "Didn't expect cert to be trusted\n");
430 ok(data.pasSigners[0].pasCertChain[0].fSelfSigned,
431 "Expected cert to be self-signed\n");
432 ok(data.pasSigners[0].pasCertChain[0].dwConfidence ==
433 (CERT_CONFIDENCE_SIG | CERT_CONFIDENCE_TIMENEST),
434 "Expected CERT_CONFIDENCE_SIG | CERT_CONFIDENCE_TIMENEST, got %08x\n",
435 data.pasSigners[0].pasCertChain[0].dwConfidence);
436 CertFreeCertificateContext(cert);
441 static void test_provider_funcs(void)
443 static GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
444 SAFE_PROVIDER_FUNCTIONS funcs = { sizeof(SAFE_PROVIDER_FUNCTIONS), 0 };
445 BOOL ret;
447 ret = WintrustLoadFunctionPointers(&generic_verify_v2,
448 (CRYPT_PROVIDER_FUNCTIONS *)&funcs);
449 if (!ret)
450 skip("WintrustLoadFunctionPointers failed\n");
451 else
453 test_utils(&funcs);
454 testInitialize(&funcs, &generic_verify_v2);
455 testObjTrust(&funcs, &generic_verify_v2);
456 testCertTrust(&funcs, &generic_verify_v2);
460 static void test_wintrust(void)
462 static GUID generic_action_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2;
463 WINTRUST_DATA wtd;
464 WINTRUST_FILE_INFO file;
465 LONG r;
466 HRESULT hr;
467 WCHAR notepadPathW[MAX_PATH];
469 memset(&wtd, 0, sizeof(wtd));
470 wtd.cbStruct = sizeof(wtd);
471 wtd.dwUIChoice = WTD_UI_NONE;
472 wtd.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN;
473 wtd.dwUnionChoice = WTD_CHOICE_FILE;
474 U(wtd).pFile = &file;
475 wtd.dwStateAction = WTD_STATEACTION_VERIFY;
476 memset(&file, 0, sizeof(file));
477 file.cbStruct = sizeof(file);
478 getNotepadPath(notepadPathW, MAX_PATH);
479 file.pcwszFilePath = notepadPathW;
480 r = WinVerifyTrust(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd);
481 ok(r == TRUST_E_NOSIGNATURE || r == CRYPT_E_FILE_ERROR,
482 "expected TRUST_E_NOSIGNATURE or CRYPT_E_FILE_ERROR, got %08x\n", r);
483 hr = WinVerifyTrustEx(INVALID_HANDLE_VALUE, &generic_action_v2, &wtd);
484 ok(hr == TRUST_E_NOSIGNATURE || r == CRYPT_E_FILE_ERROR,
485 "expected TRUST_E_NOSIGNATURE or CRYPT_E_FILE_ERROR, got %08x\n", hr);
488 static BOOL (WINAPI * pWTHelperGetKnownUsages)(DWORD action, PCCRYPT_OID_INFO **usages);
490 static void InitFunctionPtrs(void)
492 HMODULE hWintrust = GetModuleHandleA("wintrust.dll");
494 #define WINTRUST_GET_PROC(func) \
495 p ## func = (void*)GetProcAddress(hWintrust, #func); \
496 if(!p ## func) { \
497 trace("GetProcAddress(%s) failed\n", #func); \
500 WINTRUST_GET_PROC(WTHelperGetKnownUsages)
502 #undef WINTRUST_GET_PROC
505 static void test_get_known_usages(void)
507 BOOL ret;
508 PCCRYPT_OID_INFO *usages;
510 if (!pWTHelperGetKnownUsages)
512 skip("missing WTHelperGetKnownUsages\n");
513 return;
515 SetLastError(0xdeadbeef);
516 ret = pWTHelperGetKnownUsages(0, NULL);
517 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
518 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
519 SetLastError(0xdeadbeef);
520 ret = pWTHelperGetKnownUsages(1, NULL);
521 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
522 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
523 SetLastError(0xdeadbeef);
524 ret = pWTHelperGetKnownUsages(0, &usages);
525 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
526 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
527 /* A value of 1 for the first parameter seems to imply the value is
528 * allocated
530 SetLastError(0xdeadbeef);
531 usages = NULL;
532 ret = pWTHelperGetKnownUsages(1, &usages);
533 ok(ret, "WTHelperGetKnownUsages failed: %d\n", GetLastError());
534 ok(usages != NULL, "expected a pointer\n");
535 if (ret && usages)
537 PCCRYPT_OID_INFO *ptr;
539 /* The returned usages are an array of PCCRYPT_OID_INFOs, terminated with a
540 * NULL pointer.
542 for (ptr = usages; *ptr; ptr++)
544 ok((*ptr)->cbSize == sizeof(CRYPT_OID_INFO) ||
545 (*ptr)->cbSize == (sizeof(CRYPT_OID_INFO) + 2 * sizeof(LPCWSTR)), /* Vista */
546 "unexpected size %d\n", (*ptr)->cbSize);
547 /* Each returned usage is in the CRYPT_ENHKEY_USAGE_OID_GROUP_ID group */
548 ok((*ptr)->dwGroupId == CRYPT_ENHKEY_USAGE_OID_GROUP_ID,
549 "expected group CRYPT_ENHKEY_USAGE_OID_GROUP_ID, got %d\n",
550 (*ptr)->dwGroupId);
553 /* A value of 2 for the second parameter seems to imply the value is freed
555 SetLastError(0xdeadbeef);
556 ret = pWTHelperGetKnownUsages(2, &usages);
557 ok(ret, "WTHelperGetKnownUsages failed: %d\n", GetLastError());
558 ok(usages == NULL, "expected pointer to be cleared\n");
559 SetLastError(0xdeadbeef);
560 usages = NULL;
561 ret = pWTHelperGetKnownUsages(2, &usages);
562 ok(ret, "WTHelperGetKnownUsages failed: %d\n", GetLastError());
563 SetLastError(0xdeadbeef);
564 ret = pWTHelperGetKnownUsages(2, NULL);
565 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
566 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
569 START_TEST(softpub)
571 InitFunctionPtrs();
572 test_provider_funcs();
573 test_wintrust();
574 test_get_known_usages();