push 52d6b63ba2f2d4f9b02b6b922d27bff05a60596f
[wine/hacks.git] / dlls / crypt32 / tests / crl.c
blob1b8cb18e4d17dc5223960715827b2b9b30dff3ed
1 /*
2 * crypt32 CRL functions tests
4 * Copyright 2005-2006 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
21 #include <assert.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <windef.h>
25 #include <winbase.h>
26 #include <winreg.h>
27 #include <winerror.h>
28 #include <wincrypt.h>
30 #include "wine/test.h"
33 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
34 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
35 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
36 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
37 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
38 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
39 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
40 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
41 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
42 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
43 static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
44 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
45 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
46 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
47 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
48 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
49 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20,
50 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
51 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
52 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
53 static const BYTE bigCertWithDifferentIssuer[] = { 0x30, 0x7a, 0x02, 0x01,
54 0x01, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
55 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
56 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
57 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
58 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
59 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
60 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
61 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
62 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
63 0x02, 0x01, 0x01 };
64 static const BYTE CRL[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
65 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
66 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
67 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
68 0x5a };
69 static const BYTE newerCRL[] = { 0x30, 0x2a, 0x30, 0x02, 0x06, 0x00, 0x30,
70 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
71 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x17, 0x0d, 0x30, 0x36,
72 0x30, 0x35, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
73 static const BYTE signedCRL[] = { 0x30, 0x45, 0x30, 0x2c, 0x30, 0x02, 0x06,
74 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
75 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
76 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
77 0x30, 0x5a, 0x30, 0x02, 0x06, 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c,
78 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
80 static BOOL (WINAPI *pCertFindCertificateInCRL)(PCCERT_CONTEXT,PCCRL_CONTEXT,DWORD,void*,PCRL_ENTRY*);
81 static PCCRL_CONTEXT (WINAPI *pCertFindCRLInStore)(HCERTSTORE,DWORD,DWORD,DWORD,const void*,PCCRL_CONTEXT);
82 static BOOL (WINAPI *pCertIsValidCRLForCertificate)(PCCERT_CONTEXT, PCCRL_CONTEXT, DWORD, void*);
84 static void init_function_pointers(void)
86 HMODULE hdll = GetModuleHandleA("crypt32.dll");
87 pCertFindCertificateInCRL = (void*)GetProcAddress(hdll, "CertFindCertificateInCRL");
88 pCertFindCRLInStore = (void*)GetProcAddress(hdll, "CertFindCRLInStore");
89 pCertIsValidCRLForCertificate = (void*)GetProcAddress(hdll, "CertIsValidCRLForCertificate");
92 static void testCreateCRL(void)
94 PCCRL_CONTEXT context;
95 DWORD GLE;
97 context = CertCreateCRLContext(0, NULL, 0);
98 ok(!context && GetLastError() == E_INVALIDARG,
99 "Expected E_INVALIDARG, got %08x\n", GetLastError());
100 context = CertCreateCRLContext(X509_ASN_ENCODING, NULL, 0);
101 GLE = GetLastError();
102 ok(!context && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
103 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
104 context = CertCreateCRLContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
105 GLE = GetLastError();
106 ok(!context, "Expected failure\n");
107 context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
108 sizeof(signedCRL) - 1);
109 ok(!context, "Expected failure\n");
110 context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
111 sizeof(signedCRL));
112 ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
113 if (context)
114 CertFreeCRLContext(context);
115 context = CertCreateCRLContext(X509_ASN_ENCODING, CRL, sizeof(CRL));
116 ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
117 if (context)
118 CertFreeCRLContext(context);
121 static void testDupCRL(void)
123 PCCRL_CONTEXT context, dupContext;
125 context = CertDuplicateCRLContext(NULL);
126 ok(context == NULL, "expected NULL\n");
127 context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
128 sizeof(signedCRL));
129 dupContext = CertDuplicateCRLContext(context);
130 ok(dupContext != NULL, "expected a context\n");
131 ok(dupContext == context, "expected identical context addresses\n");
132 CertFreeCRLContext(dupContext);
133 CertFreeCRLContext(context);
136 static void testAddCRL(void)
138 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
139 CERT_STORE_CREATE_NEW_FLAG, NULL);
140 PCCRL_CONTEXT context;
141 BOOL ret;
142 DWORD GLE;
144 if (!store) return;
146 /* Bad CRL encoding type */
147 ret = CertAddEncodedCRLToStore(0, 0, NULL, 0, 0, NULL);
148 ok(!ret && GetLastError() == E_INVALIDARG,
149 "Expected E_INVALIDARG, got %08x\n", GetLastError());
150 ret = CertAddEncodedCRLToStore(store, 0, NULL, 0, 0, NULL);
151 ok(!ret && GetLastError() == E_INVALIDARG,
152 "Expected E_INVALIDARG, got %08x\n", GetLastError());
153 ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL), 0, NULL);
154 ok(!ret && GetLastError() == E_INVALIDARG,
155 "Expected E_INVALIDARG, got %08x\n", GetLastError());
156 ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL), 0,
157 NULL);
158 ok(!ret && GetLastError() == E_INVALIDARG,
159 "Expected E_INVALIDARG, got %08x\n", GetLastError());
160 ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL),
161 CERT_STORE_ADD_ALWAYS, NULL);
162 ok(!ret && GetLastError() == E_INVALIDARG,
163 "Expected E_INVALIDARG, got %08x\n", GetLastError());
164 ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL),
165 CERT_STORE_ADD_ALWAYS, NULL);
166 ok(!ret && GetLastError() == E_INVALIDARG,
167 "Expected E_INVALIDARG, got %08x\n", GetLastError());
169 /* No CRL */
170 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, NULL, 0, 0, NULL);
171 GLE = GetLastError();
172 ok(!ret && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
173 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
174 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, NULL, 0, 0, NULL);
175 GLE = GetLastError();
176 ok(!ret && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
177 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
179 /* Weird--bad add disposition leads to an access violation in Windows.
180 * Both tests crash on some win9x boxes.
182 if (0)
184 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
185 sizeof(signedCRL), 0, NULL);
186 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
187 GetLastError() == E_INVALIDARG /* Vista */),
188 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n", GetLastError());
189 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
190 sizeof(signedCRL), 0, NULL);
191 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
192 GetLastError() == E_INVALIDARG /* Vista */),
193 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n", GetLastError());
196 /* Weird--can add a CRL to the NULL store (does this have special meaning?)
198 context = NULL;
199 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
200 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &context);
201 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
202 if (context)
203 CertFreeCRLContext(context);
205 /* Normal cases: a "signed" CRL is okay.. */
206 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
207 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
208 /* and an unsigned one is too. */
209 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, CRL, sizeof(CRL),
210 CERT_STORE_ADD_ALWAYS, NULL);
211 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
213 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
214 sizeof(newerCRL), CERT_STORE_ADD_NEW, NULL);
215 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
216 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
218 /* This should replace (one of) the existing CRL(s). */
219 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
220 sizeof(newerCRL), CERT_STORE_ADD_NEWER, NULL);
221 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
223 CertCloseStore(store, 0);
226 static void testFindCRL(void)
228 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
229 CERT_STORE_CREATE_NEW_FLAG, NULL);
230 PCCRL_CONTEXT context;
231 PCCERT_CONTEXT cert;
232 BOOL ret;
234 if (!store) return;
235 if (!pCertFindCRLInStore)
237 win_skip("CertFindCRLInStore() is not available\n");
238 return;
241 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
242 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
243 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
245 /* Crashes
246 context = pCertFindCRLInStore(NULL, 0, 0, 0, NULL, NULL);
249 /* Find any context */
250 context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ANY, NULL, NULL);
251 ok(context != NULL, "Expected a context\n");
252 if (context)
253 CertFreeCRLContext(context);
254 /* Bogus flags are ignored */
255 context = pCertFindCRLInStore(store, 0, 1234, CRL_FIND_ANY, NULL, NULL);
256 ok(context != NULL, "Expected a context\n");
257 if (context)
258 CertFreeCRLContext(context);
259 /* CRL encoding type is ignored too */
260 context = pCertFindCRLInStore(store, 1234, 0, CRL_FIND_ANY, NULL, NULL);
261 ok(context != NULL, "Expected a context\n");
262 if (context)
263 CertFreeCRLContext(context);
265 /* This appears to match any cert */
266 context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, NULL, NULL);
267 ok(context != NULL, "Expected a context\n");
268 if (context)
269 CertFreeCRLContext(context);
271 /* Try to match an issuer that isn't in the store */
272 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
273 sizeof(bigCert2));
274 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
275 GetLastError());
276 context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
277 ok(context == NULL, "Expected no matching context\n");
278 CertFreeCertificateContext(cert);
280 /* Match an issuer that is in the store */
281 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
282 sizeof(bigCert));
283 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
284 GetLastError());
285 context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
286 ok(context != NULL, "Expected a context\n");
287 if (context)
288 CertFreeCRLContext(context);
289 CertFreeCertificateContext(cert);
291 CertCloseStore(store, 0);
294 static void testGetCRLFromStore(void)
296 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
297 CERT_STORE_CREATE_NEW_FLAG, NULL);
298 PCCRL_CONTEXT context;
299 PCCERT_CONTEXT cert;
300 DWORD flags;
301 BOOL ret;
303 if (!store) return;
305 /* Crash
306 context = CertGetCRLFromStore(NULL, NULL, NULL, NULL);
307 context = CertGetCRLFromStore(store, NULL, NULL, NULL);
310 /* Bogus flags */
311 flags = 0xffffffff;
312 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
313 ok(!context && GetLastError() == E_INVALIDARG,
314 "Expected E_INVALIDARG, got %08x\n", GetLastError());
316 /* Test an empty store */
317 flags = 0;
318 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
319 ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
320 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
322 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
323 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
324 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
326 /* NULL matches any CRL */
327 flags = 0;
328 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
329 ok(context != NULL, "Expected a context\n");
330 CertFreeCRLContext(context);
332 /* This cert's issuer isn't in */
333 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
334 sizeof(bigCert2));
335 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
336 GetLastError());
337 context = CertGetCRLFromStore(store, cert, NULL, &flags);
338 ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
339 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
340 CertFreeCertificateContext(cert);
342 /* But this one is */
343 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
344 sizeof(bigCert));
345 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
346 GetLastError());
347 context = CertGetCRLFromStore(store, cert, NULL, &flags);
348 ok(context != NULL, "Expected a context\n");
349 CertFreeCRLContext(context);
350 CertFreeCertificateContext(cert);
352 CertCloseStore(store, 0);
355 static void checkCRLHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
356 PCCRL_CONTEXT context, DWORD propID)
358 BYTE hash[20] = { 0 }, hashProperty[20];
359 BOOL ret;
360 DWORD size;
362 memset(hash, 0, sizeof(hash));
363 memset(hashProperty, 0, sizeof(hashProperty));
364 size = sizeof(hash);
365 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
366 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
367 ret = CertGetCRLContextProperty(context, propID, hashProperty, &size);
368 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
369 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
370 propID);
373 static void testCRLProperties(void)
375 PCCRL_CONTEXT context = CertCreateCRLContext(X509_ASN_ENCODING,
376 CRL, sizeof(CRL));
378 ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
379 if (context)
381 DWORD propID, numProps, access, size;
382 BOOL ret;
383 BYTE hash[20] = { 0 }, hashProperty[20];
384 CRYPT_DATA_BLOB blob;
386 /* This crashes
387 propID = CertEnumCRLContextProperties(NULL, 0);
390 propID = 0;
391 numProps = 0;
392 do {
393 propID = CertEnumCRLContextProperties(context, propID);
394 if (propID)
395 numProps++;
396 } while (propID != 0);
397 ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
399 /* Tests with a NULL cert context. Prop ID 0 fails.. */
400 ret = CertSetCRLContextProperty(NULL, 0, 0, NULL);
401 ok(!ret && GetLastError() == E_INVALIDARG,
402 "Expected E_INVALIDARG, got %08x\n", GetLastError());
403 /* while this just crashes.
404 ret = CertSetCRLContextProperty(NULL, CERT_KEY_PROV_HANDLE_PROP_ID, 0,
405 NULL);
408 ret = CertSetCRLContextProperty(context, 0, 0, NULL);
409 ok(!ret && GetLastError() == E_INVALIDARG,
410 "Expected E_INVALIDARG, got %08x\n", GetLastError());
411 /* Can't set the cert property directly, this crashes.
412 ret = CertSetCRLContextProperty(context, CERT_CRL_PROP_ID, 0, CRL);
415 /* These all crash.
416 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
417 NULL);
418 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID, NULL, NULL);
419 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
420 hashProperty, NULL);
422 /* A missing prop */
423 size = 0;
424 ret = CertGetCRLContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID,
425 NULL, &size);
426 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
427 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
428 /* And, an implicit property */
429 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
430 NULL, &size);
431 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
432 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
433 &access, &size);
434 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
435 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
436 "Didn't expect a persisted crl\n");
437 /* Trying to set this "read only" property crashes.
438 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
439 ret = CertSetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
440 &access);
443 /* Can I set the hash to an invalid hash? */
444 blob.pbData = hash;
445 blob.cbData = sizeof(hash);
446 ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, &blob);
447 ok(ret, "CertSetCRLContextProperty failed: %08x\n",
448 GetLastError());
449 size = sizeof(hashProperty);
450 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
451 hashProperty, &size);
452 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
453 /* Delete the (bogus) hash, and get the real one */
454 ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, NULL);
455 ok(ret, "CertSetCRLContextProperty failed: %08x\n", GetLastError());
456 checkCRLHash(CRL, sizeof(CRL), CALG_SHA1, context, CERT_HASH_PROP_ID);
458 /* Now that the hash property is set, we should get one property when
459 * enumerating.
461 propID = 0;
462 numProps = 0;
463 do {
464 propID = CertEnumCRLContextProperties(context, propID);
465 if (propID)
466 numProps++;
467 } while (propID != 0);
468 ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
470 /* Check a few other implicit properties */
471 checkCRLHash(CRL, sizeof(CRL), CALG_MD5, context,
472 CERT_MD5_HASH_PROP_ID);
474 CertFreeCRLContext(context);
478 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
479 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
480 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
481 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
482 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
483 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
484 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
485 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
486 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
487 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
488 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
489 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
490 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
491 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
492 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
493 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
494 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
495 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
496 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
497 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
498 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
499 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
500 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
501 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
502 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
503 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
504 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
505 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
506 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
507 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
508 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
509 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
510 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
511 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
512 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
513 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
514 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
515 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
516 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
517 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
518 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
519 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
520 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
521 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
522 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
523 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
524 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
525 0xcd };
527 static void testIsValidCRLForCert(void)
529 BOOL ret;
530 PCCERT_CONTEXT cert1, cert2;
531 PCCRL_CONTEXT crl;
532 HCERTSTORE store;
534 if(!pCertIsValidCRLForCertificate) return;
536 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
537 sizeof(v1CRLWithIssuerAndEntry));
538 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
539 cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
540 sizeof(bigCert));
541 ok(cert1 != NULL, "CertCreateCertificateContext failed: %08x\n",
542 GetLastError());
544 /* Crash
545 ret = CertIsValidCRLForCertificate(NULL, NULL, 0, NULL);
546 ret = CertIsValidCRLForCertificate(cert1, NULL, 0, NULL);
549 /* Curiously, any CRL is valid for the NULL certificate */
550 ret = pCertIsValidCRLForCertificate(NULL, crl, 0, NULL);
551 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
553 /* Same issuer for both cert and CRL, this CRL is valid for that cert */
554 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
555 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
557 cert2 = CertCreateCertificateContext(X509_ASN_ENCODING,
558 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer));
559 ok(cert2 != NULL, "CertCreateCertificateContext failed: %08x\n",
560 GetLastError());
562 /* Yet more curious: different issuers for these, yet the CRL is valid for
563 * that cert. According to MSDN, the relevant bit to check is whether the
564 * CRL has a CRL_ISSUING_DIST_POINT extension.
566 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
567 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
569 CertFreeCRLContext(crl);
571 /* Yet with a CRL_ISSUING_DIST_POINT in the CRL, I still can't get this
572 * to say the CRL is not valid for either cert.
574 crl = CertCreateCRLContext(X509_ASN_ENCODING, v2CRLWithIssuingDistPoint,
575 sizeof(v2CRLWithIssuingDistPoint));
576 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
578 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
579 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
580 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
581 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
583 CertFreeCRLContext(crl);
585 /* And again, with a real CRL, the CRL is valid for both certs. */
586 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
587 sizeof(verisignCRL));
588 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
590 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
591 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
592 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
593 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
595 CertFreeCRLContext(crl);
597 /* One last test: a CRL in a different store than the cert is also valid
598 * for the cert, so CertIsValidCRLForCertificate must always return TRUE?
600 store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
601 CERT_STORE_CREATE_NEW_FLAG, NULL);
602 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
604 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, verisignCRL,
605 sizeof(verisignCRL), CERT_STORE_ADD_ALWAYS, &crl);
606 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
608 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
609 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
610 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
611 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
613 CertFreeCRLContext(crl);
615 CertCloseStore(store, 0);
617 CertFreeCertificateContext(cert2);
618 CertFreeCertificateContext(cert1);
621 static const BYTE crlWithDifferentIssuer[] = {
622 0x30,0x47,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
623 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x41,0x6c,0x65,0x78,0x20,0x4c,0x61,0x6e,
624 0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
625 0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
626 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a };
628 static void testFindCertInCRL(void)
630 BOOL ret;
631 PCCERT_CONTEXT cert;
632 PCCRL_CONTEXT crl;
633 PCRL_ENTRY entry;
635 if (!pCertFindCertificateInCRL)
637 win_skip("CertFindCertificateInCRL() is not available\n");
638 return;
641 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
642 sizeof(bigCert));
643 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
644 GetLastError());
646 /* Crash
647 ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, NULL);
648 ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, NULL);
649 ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, NULL);
650 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, NULL);
651 ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, &entry);
652 ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, &entry);
653 ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, &entry);
656 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
657 sizeof(verisignCRL));
658 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
659 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
660 ok(entry == NULL, "Expected not to find an entry in CRL\n");
661 CertFreeCRLContext(crl);
663 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
664 sizeof(v1CRLWithIssuerAndEntry));
665 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
666 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
667 ok(entry != NULL, "Expected to find an entry in CRL\n");
668 CertFreeCRLContext(crl);
670 /* Entry found even though CRL issuer doesn't match cert issuer */
671 crl = CertCreateCRLContext(X509_ASN_ENCODING, crlWithDifferentIssuer,
672 sizeof(crlWithDifferentIssuer));
673 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
674 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
675 ok(entry != NULL, "Expected to find an entry in CRL\n");
676 CertFreeCRLContext(crl);
678 CertFreeCertificateContext(cert);
681 static void testVerifyCRLRevocation(void)
683 BOOL ret;
684 PCCERT_CONTEXT cert;
685 PCCRL_CONTEXT crl;
687 ret = CertVerifyCRLRevocation(0, NULL, 0, NULL);
688 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
689 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, NULL, 0, NULL);
690 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
692 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
693 sizeof(bigCert));
695 /* Check against no CRL */
696 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 0, NULL);
697 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
698 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 0, NULL);
699 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
701 /* Check against CRL with entry for the cert */
702 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
703 sizeof(v1CRLWithIssuerAndEntry));
704 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
705 (PCRL_INFO *)&crl->pCrlInfo);
706 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
707 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
708 (PCRL_INFO *)&crl->pCrlInfo);
709 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
710 CertFreeCRLContext(crl);
712 /* Check against CRL with different issuer and entry for the cert */
713 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
714 sizeof(v1CRLWithIssuerAndEntry));
715 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
716 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
717 (PCRL_INFO *)&crl->pCrlInfo);
718 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
719 CertFreeCRLContext(crl);
721 /* Check against CRL without entry for the cert */
722 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
723 sizeof(verisignCRL));
724 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
725 (PCRL_INFO *)&crl->pCrlInfo);
726 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
727 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
728 (PCRL_INFO *)&crl->pCrlInfo);
729 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
730 CertFreeCRLContext(crl);
732 CertFreeCertificateContext(cert);
735 START_TEST(crl)
737 init_function_pointers();
739 testCreateCRL();
740 testDupCRL();
741 testAddCRL();
742 testFindCRL();
743 testGetCRLFromStore();
745 testCRLProperties();
747 testIsValidCRLForCert();
748 testFindCertInCRL();
749 testVerifyCRLRevocation();