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
30 #include "wine/test.h"
32 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
33 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
34 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
35 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
36 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
37 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
38 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
39 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
40 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
41 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
42 static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
43 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
44 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
45 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
46 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
47 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
48 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20,
49 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
50 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
51 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
52 static const BYTE bigCertWithDifferentIssuer[] = { 0x30, 0x7a, 0x02, 0x01,
53 0x01, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
54 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
55 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
56 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
57 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
58 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
59 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
60 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
61 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
63 static const BYTE CRL[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
64 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
65 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
66 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
68 static const BYTE newerCRL[] = { 0x30, 0x2a, 0x30, 0x02, 0x06, 0x00, 0x30,
69 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
70 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x17, 0x0d, 0x30, 0x36,
71 0x30, 0x35, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
72 static const BYTE signedCRL[] = { 0x30, 0x45, 0x30, 0x2c, 0x30, 0x02, 0x06,
73 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
74 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
75 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
76 0x30, 0x5a, 0x30, 0x02, 0x06, 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c,
77 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
79 static BOOL (WINAPI *pCertIsValidCRLForCertificate)(PCCERT_CONTEXT, PCCRL_CONTEXT, DWORD, void*);
81 static void init_function_pointers(void)
83 HMODULE hdll = GetModuleHandleA("crypt32.dll");
84 pCertIsValidCRLForCertificate = (void*)GetProcAddress(hdll, "CertIsValidCRLForCertificate");
87 static void testCreateCRL(void)
89 PCCRL_CONTEXT context;
91 context = CertCreateCRLContext(0, NULL, 0);
92 ok(!context && GetLastError() == E_INVALIDARG,
93 "Expected E_INVALIDARG, got %08x\n", GetLastError());
94 context = CertCreateCRLContext(X509_ASN_ENCODING, NULL, 0);
95 ok(!context && GetLastError() == CRYPT_E_ASN1_EOD,
96 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
97 context = CertCreateCRLContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
98 ok(!context && GetLastError() == CRYPT_E_ASN1_CORRUPT,
99 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
100 context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
101 sizeof(signedCRL) - 1);
102 ok(!context && (GetLastError() == CRYPT_E_ASN1_EOD ||
103 GetLastError() == CRYPT_E_ASN1_CORRUPT),
104 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
106 context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
108 ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
110 CertFreeCRLContext(context);
111 context = CertCreateCRLContext(X509_ASN_ENCODING, CRL, sizeof(CRL));
112 ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
114 CertFreeCRLContext(context);
117 static void testAddCRL(void)
119 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
120 CERT_STORE_CREATE_NEW_FLAG, NULL);
121 PCCRL_CONTEXT context;
126 /* Bad CRL encoding type */
127 ret = CertAddEncodedCRLToStore(0, 0, NULL, 0, 0, NULL);
128 ok(!ret && GetLastError() == E_INVALIDARG,
129 "Expected E_INVALIDARG, got %08x\n", GetLastError());
130 ret = CertAddEncodedCRLToStore(store, 0, NULL, 0, 0, NULL);
131 ok(!ret && GetLastError() == E_INVALIDARG,
132 "Expected E_INVALIDARG, got %08x\n", GetLastError());
133 ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL), 0, NULL);
134 ok(!ret && GetLastError() == E_INVALIDARG,
135 "Expected E_INVALIDARG, got %08x\n", GetLastError());
136 ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL), 0,
138 ok(!ret && GetLastError() == E_INVALIDARG,
139 "Expected E_INVALIDARG, got %08x\n", GetLastError());
140 ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL),
141 CERT_STORE_ADD_ALWAYS, NULL);
142 ok(!ret && GetLastError() == E_INVALIDARG,
143 "Expected E_INVALIDARG, got %08x\n", GetLastError());
144 ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL),
145 CERT_STORE_ADD_ALWAYS, NULL);
146 ok(!ret && GetLastError() == E_INVALIDARG,
147 "Expected E_INVALIDARG, got %08x\n", GetLastError());
150 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, NULL, 0, 0, NULL);
151 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
152 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
153 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, NULL, 0, 0, NULL);
154 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
155 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
157 /* Weird--bad add disposition leads to an access violation in Windows. */
158 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
159 sizeof(signedCRL), 0, NULL);
160 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
161 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
162 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
163 sizeof(signedCRL), 0, NULL);
164 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
165 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
167 /* Weird--can add a CRL to the NULL store (does this have special meaning?)
170 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
171 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &context);
172 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
174 CertFreeCRLContext(context);
176 /* Normal cases: a "signed" CRL is okay.. */
177 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
178 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
179 /* and an unsigned one is too. */
180 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, CRL, sizeof(CRL),
181 CERT_STORE_ADD_ALWAYS, NULL);
182 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
184 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
185 sizeof(newerCRL), CERT_STORE_ADD_NEW, NULL);
186 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
187 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
189 /* This should replace (one of) the existing CRL(s). */
190 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
191 sizeof(newerCRL), CERT_STORE_ADD_NEWER, NULL);
192 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
194 CertCloseStore(store, 0);
197 static void testFindCRL(void)
199 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
200 CERT_STORE_CREATE_NEW_FLAG, NULL);
201 PCCRL_CONTEXT context;
207 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
208 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
209 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
212 context = CertFindCRLInStore(NULL, 0, 0, 0, NULL, NULL);
215 /* Find any context */
216 context = CertFindCRLInStore(store, 0, 0, CRL_FIND_ANY, NULL, NULL);
217 ok(context != NULL, "Expected a context\n");
219 CertFreeCRLContext(context);
220 /* Bogus flags are ignored */
221 context = CertFindCRLInStore(store, 0, 1234, CRL_FIND_ANY, NULL, NULL);
222 ok(context != NULL, "Expected a context\n");
224 CertFreeCRLContext(context);
225 /* CRL encoding type is ignored too */
226 context = CertFindCRLInStore(store, 1234, 0, CRL_FIND_ANY, NULL, NULL);
227 ok(context != NULL, "Expected a context\n");
229 CertFreeCRLContext(context);
231 /* This appears to match any cert */
232 context = CertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, NULL, NULL);
233 ok(context != NULL, "Expected a context\n");
235 CertFreeCRLContext(context);
237 /* Try to match an issuer that isn't in the store */
238 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
240 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
242 context = CertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
243 ok(context == NULL, "Expected no matching context\n");
244 CertFreeCertificateContext(cert);
246 /* Match an issuer that is in the store */
247 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
249 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
251 context = CertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
252 ok(context != NULL, "Expected a context\n");
254 CertFreeCRLContext(context);
255 CertFreeCertificateContext(cert);
257 CertCloseStore(store, 0);
260 static void testGetCRLFromStore(void)
262 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
263 CERT_STORE_CREATE_NEW_FLAG, NULL);
264 PCCRL_CONTEXT context;
272 context = CertGetCRLFromStore(NULL, NULL, NULL, NULL);
273 context = CertGetCRLFromStore(store, NULL, NULL, NULL);
278 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
279 ok(!context && GetLastError() == E_INVALIDARG,
280 "Expected E_INVALIDARG, got %08x\n", GetLastError());
282 /* Test an empty store */
284 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
285 ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
286 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
288 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
289 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
290 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
292 /* NULL matches any CRL */
294 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
295 ok(context != NULL, "Expected a context\n");
296 CertFreeCRLContext(context);
298 /* This cert's issuer isn't in */
299 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
301 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
303 context = CertGetCRLFromStore(store, cert, NULL, &flags);
304 ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
305 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
306 CertFreeCertificateContext(cert);
308 /* But this one is */
309 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
311 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
313 context = CertGetCRLFromStore(store, cert, NULL, &flags);
314 ok(context != NULL, "Expected a context\n");
315 CertFreeCRLContext(context);
316 CertFreeCertificateContext(cert);
318 CertCloseStore(store, 0);
321 static void checkCRLHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
322 PCCRL_CONTEXT context, DWORD propID)
324 BYTE hash[20] = { 0 }, hashProperty[20];
328 memset(hash, 0, sizeof(hash));
329 memset(hashProperty, 0, sizeof(hashProperty));
331 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
332 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
333 ret = CertGetCRLContextProperty(context, propID, hashProperty, &size);
334 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
335 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
339 static void testCRLProperties(void)
341 PCCRL_CONTEXT context = CertCreateCRLContext(X509_ASN_ENCODING,
344 ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
347 DWORD propID, numProps, access, size;
349 BYTE hash[20] = { 0 }, hashProperty[20];
350 CRYPT_DATA_BLOB blob;
353 propID = CertEnumCRLContextProperties(NULL, 0);
359 propID = CertEnumCRLContextProperties(context, propID);
362 } while (propID != 0);
363 ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
365 /* Tests with a NULL cert context. Prop ID 0 fails.. */
366 ret = CertSetCRLContextProperty(NULL, 0, 0, NULL);
367 ok(!ret && GetLastError() == E_INVALIDARG,
368 "Expected E_INVALIDARG, got %08x\n", GetLastError());
369 /* while this just crashes.
370 ret = CertSetCRLContextProperty(NULL, CERT_KEY_PROV_HANDLE_PROP_ID, 0,
374 ret = CertSetCRLContextProperty(context, 0, 0, NULL);
375 ok(!ret && GetLastError() == E_INVALIDARG,
376 "Expected E_INVALIDARG, got %08x\n", GetLastError());
377 /* Can't set the cert property directly, this crashes.
378 ret = CertSetCRLContextProperty(context, CERT_CRL_PROP_ID, 0, CRL);
382 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
384 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID, NULL, NULL);
385 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
390 ret = CertGetCRLContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID,
392 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
393 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
394 /* And, an implicit property */
395 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
397 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
398 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
400 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
401 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
402 "Didn't expect a persisted crl\n");
403 /* Trying to set this "read only" property crashes.
404 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
405 ret = CertSetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
409 /* Can I set the hash to an invalid hash? */
411 blob.cbData = sizeof(hash);
412 ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, &blob);
413 ok(ret, "CertSetCRLContextProperty failed: %08x\n",
415 size = sizeof(hashProperty);
416 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
417 hashProperty, &size);
418 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
419 /* Delete the (bogus) hash, and get the real one */
420 ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, NULL);
421 ok(ret, "CertSetCRLContextProperty failed: %08x\n", GetLastError());
422 checkCRLHash(CRL, sizeof(CRL), CALG_SHA1, context, CERT_HASH_PROP_ID);
424 /* Now that the hash property is set, we should get one property when
430 propID = CertEnumCRLContextProperties(context, propID);
433 } while (propID != 0);
434 ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
436 /* Check a few other implicit properties */
437 checkCRLHash(CRL, sizeof(CRL), CALG_MD5, context,
438 CERT_MD5_HASH_PROP_ID);
440 CertFreeCRLContext(context);
444 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
445 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
446 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
447 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
448 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
449 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
450 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
451 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
452 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
453 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
454 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
455 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
456 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
457 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
458 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
459 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
460 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
461 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
462 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
463 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
464 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
465 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
466 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
467 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
468 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
469 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
470 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
471 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
472 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
473 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
474 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
475 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
476 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
477 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
478 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
479 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
480 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
481 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
482 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
483 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
484 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
485 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
486 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
487 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
488 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
489 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
490 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
493 static void testIsValidCRLForCert(void)
496 PCCERT_CONTEXT cert1, cert2;
500 if(!pCertIsValidCRLForCertificate) return;
502 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
503 sizeof(v1CRLWithIssuerAndEntry));
504 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
505 cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
507 ok(cert1 != NULL, "CertCreateCertificateContext failed: %08x\n",
511 ret = CertIsValidCRLForCertificate(NULL, NULL, 0, NULL);
512 ret = CertIsValidCRLForCertificate(cert1, NULL, 0, NULL);
515 /* Curiously, any CRL is valid for the NULL certificate */
516 ret = pCertIsValidCRLForCertificate(NULL, crl, 0, NULL);
517 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
519 /* Same issuer for both cert and CRL, this CRL is valid for that cert */
520 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
521 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
523 cert2 = CertCreateCertificateContext(X509_ASN_ENCODING,
524 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer));
525 ok(cert2 != NULL, "CertCreateCertificateContext failed: %08x\n",
528 /* Yet more curious: different issuers for these, yet the CRL is valid for
529 * that cert. According to MSDN, the relevant bit to check is whether the
530 * CRL has a CRL_ISSUING_DIST_POINT extension.
532 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
533 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
535 CertFreeCRLContext(crl);
537 /* Yet with a CRL_ISSUING_DIST_POINT in the CRL, I still can't get this
538 * to say the CRL is not valid for either cert.
540 crl = CertCreateCRLContext(X509_ASN_ENCODING, v2CRLWithIssuingDistPoint,
541 sizeof(v2CRLWithIssuingDistPoint));
542 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
544 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
545 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
546 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
547 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
549 CertFreeCRLContext(crl);
551 /* And again, with a real CRL, the CRL is valid for both certs. */
552 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
553 sizeof(verisignCRL));
554 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
556 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
557 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
558 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
559 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
561 CertFreeCRLContext(crl);
563 /* One last test: a CRL in a different store than the cert is also valid
564 * for the cert, so CertIsValidCRLForCertificate must always return TRUE?
566 store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
567 CERT_STORE_CREATE_NEW_FLAG, NULL);
568 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
570 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, verisignCRL,
571 sizeof(verisignCRL), CERT_STORE_ADD_ALWAYS, &crl);
572 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
574 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
575 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
576 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
577 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
579 CertFreeCRLContext(crl);
581 CertCloseStore(store, 0);
583 CertFreeCertificateContext(cert2);
584 CertFreeCertificateContext(cert1);
587 static const BYTE crlWithDifferentIssuer[] = {
588 0x30,0x47,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
589 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x41,0x6c,0x65,0x78,0x20,0x4c,0x61,0x6e,
590 0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
591 0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
592 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a };
594 static void testFindCertInCRL(void)
601 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
603 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
607 ret = CertFindCertificateInCRL(NULL, NULL, 0, NULL, NULL);
608 ret = CertFindCertificateInCRL(NULL, crl, 0, NULL, NULL);
609 ret = CertFindCertificateInCRL(cert, NULL, 0, NULL, NULL);
610 ret = CertFindCertificateInCRL(cert, crl, 0, NULL, NULL);
611 ret = CertFindCertificateInCRL(NULL, NULL, 0, NULL, &entry);
612 ret = CertFindCertificateInCRL(NULL, crl, 0, NULL, &entry);
613 ret = CertFindCertificateInCRL(cert, NULL, 0, NULL, &entry);
616 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
617 sizeof(verisignCRL));
618 ret = CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
619 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
620 ok(entry == NULL, "Expected not to find an entry in CRL\n");
621 CertFreeCRLContext(crl);
623 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
624 sizeof(v1CRLWithIssuerAndEntry));
625 ret = CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
626 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
627 ok(entry != NULL, "Expected to find an entry in CRL\n");
628 CertFreeCRLContext(crl);
630 /* Entry found even though CRL issuer doesn't match cert issuer */
631 crl = CertCreateCRLContext(X509_ASN_ENCODING, crlWithDifferentIssuer,
632 sizeof(crlWithDifferentIssuer));
633 ret = CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
634 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
635 ok(entry != NULL, "Expected to find an entry in CRL\n");
636 CertFreeCRLContext(crl);
638 CertFreeCertificateContext(cert);
641 static void testVerifyCRLRevocation(void)
647 ret = CertVerifyCRLRevocation(0, NULL, 0, NULL);
648 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
649 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, NULL, 0, NULL);
650 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
652 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
655 /* Check against no CRL */
656 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 0, NULL);
657 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
658 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 0, NULL);
659 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
661 /* Check against CRL with entry for the cert */
662 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
663 sizeof(v1CRLWithIssuerAndEntry));
664 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
665 (PCRL_INFO *)&crl->pCrlInfo);
666 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
667 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
668 (PCRL_INFO *)&crl->pCrlInfo);
669 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
670 CertFreeCRLContext(crl);
672 /* Check against CRL with different issuer and entry for the cert */
673 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
674 sizeof(v1CRLWithIssuerAndEntry));
675 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
676 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
677 (PCRL_INFO *)&crl->pCrlInfo);
678 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
679 CertFreeCRLContext(crl);
681 /* Check against CRL without entry for the cert */
682 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
683 sizeof(verisignCRL));
684 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
685 (PCRL_INFO *)&crl->pCrlInfo);
686 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
687 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
688 (PCRL_INFO *)&crl->pCrlInfo);
689 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
690 CertFreeCRLContext(crl);
692 CertFreeCertificateContext(cert);
697 init_function_pointers();
702 testGetCRLFromStore();
706 testIsValidCRLForCert();
708 testVerifyCRLRevocation();