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;
92 context = CertCreateCRLContext(0, NULL, 0);
93 ok(!context && GetLastError() == E_INVALIDARG,
94 "Expected E_INVALIDARG, got %08x\n", GetLastError());
95 context = CertCreateCRLContext(X509_ASN_ENCODING, NULL, 0);
97 ok(!context && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
98 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
99 context = CertCreateCRLContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
100 GLE = GetLastError();
101 ok(!context && (GLE == CRYPT_E_ASN1_CORRUPT || GLE == OSS_DATA_ERROR),
102 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n", GLE);
103 context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
104 sizeof(signedCRL) - 1);
105 ok(!context && (GLE == CRYPT_E_ASN1_EOD || GLE == CRYPT_E_ASN1_CORRUPT ||
106 GLE == OSS_DATA_ERROR),
107 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
109 context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
111 ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
113 CertFreeCRLContext(context);
114 context = CertCreateCRLContext(X509_ASN_ENCODING, CRL, sizeof(CRL));
115 ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
117 CertFreeCRLContext(context);
120 static void testAddCRL(void)
122 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
123 CERT_STORE_CREATE_NEW_FLAG, NULL);
124 PCCRL_CONTEXT context;
130 /* Bad CRL encoding type */
131 ret = CertAddEncodedCRLToStore(0, 0, NULL, 0, 0, NULL);
132 ok(!ret && GetLastError() == E_INVALIDARG,
133 "Expected E_INVALIDARG, got %08x\n", GetLastError());
134 ret = CertAddEncodedCRLToStore(store, 0, NULL, 0, 0, NULL);
135 ok(!ret && GetLastError() == E_INVALIDARG,
136 "Expected E_INVALIDARG, got %08x\n", GetLastError());
137 ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL), 0, NULL);
138 ok(!ret && GetLastError() == E_INVALIDARG,
139 "Expected E_INVALIDARG, got %08x\n", GetLastError());
140 ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL), 0,
142 ok(!ret && GetLastError() == E_INVALIDARG,
143 "Expected E_INVALIDARG, got %08x\n", GetLastError());
144 ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL),
145 CERT_STORE_ADD_ALWAYS, NULL);
146 ok(!ret && GetLastError() == E_INVALIDARG,
147 "Expected E_INVALIDARG, got %08x\n", GetLastError());
148 ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL),
149 CERT_STORE_ADD_ALWAYS, NULL);
150 ok(!ret && GetLastError() == E_INVALIDARG,
151 "Expected E_INVALIDARG, got %08x\n", GetLastError());
154 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, NULL, 0, 0, NULL);
155 GLE = GetLastError();
156 ok(!ret && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
157 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
158 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, NULL, 0, 0, NULL);
159 GLE = GetLastError();
160 ok(!ret && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
161 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
163 /* Weird--bad add disposition leads to an access violation in Windows. */
164 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
165 sizeof(signedCRL), 0, NULL);
166 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
167 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
168 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
169 sizeof(signedCRL), 0, NULL);
170 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
171 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
173 /* Weird--can add a CRL to the NULL store (does this have special meaning?)
176 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
177 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &context);
178 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
180 CertFreeCRLContext(context);
182 /* Normal cases: a "signed" CRL is okay.. */
183 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
184 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
185 /* and an unsigned one is too. */
186 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, CRL, sizeof(CRL),
187 CERT_STORE_ADD_ALWAYS, NULL);
188 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
190 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
191 sizeof(newerCRL), CERT_STORE_ADD_NEW, NULL);
192 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
193 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
195 /* This should replace (one of) the existing CRL(s). */
196 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
197 sizeof(newerCRL), CERT_STORE_ADD_NEWER, NULL);
198 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
200 CertCloseStore(store, 0);
203 static void testFindCRL(void)
205 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
206 CERT_STORE_CREATE_NEW_FLAG, NULL);
207 PCCRL_CONTEXT context;
213 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
214 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
215 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
218 context = CertFindCRLInStore(NULL, 0, 0, 0, NULL, NULL);
221 /* Find any context */
222 context = CertFindCRLInStore(store, 0, 0, CRL_FIND_ANY, NULL, NULL);
223 ok(context != NULL, "Expected a context\n");
225 CertFreeCRLContext(context);
226 /* Bogus flags are ignored */
227 context = CertFindCRLInStore(store, 0, 1234, CRL_FIND_ANY, NULL, NULL);
228 ok(context != NULL, "Expected a context\n");
230 CertFreeCRLContext(context);
231 /* CRL encoding type is ignored too */
232 context = CertFindCRLInStore(store, 1234, 0, CRL_FIND_ANY, NULL, NULL);
233 ok(context != NULL, "Expected a context\n");
235 CertFreeCRLContext(context);
237 /* This appears to match any cert */
238 context = CertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, NULL, NULL);
239 ok(context != NULL, "Expected a context\n");
241 CertFreeCRLContext(context);
243 /* Try to match an issuer that isn't in the store */
244 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
246 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
248 context = CertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
249 ok(context == NULL, "Expected no matching context\n");
250 CertFreeCertificateContext(cert);
252 /* Match an issuer that is in the store */
253 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
255 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
257 context = CertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
258 ok(context != NULL, "Expected a context\n");
260 CertFreeCRLContext(context);
261 CertFreeCertificateContext(cert);
263 CertCloseStore(store, 0);
266 static void testGetCRLFromStore(void)
268 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
269 CERT_STORE_CREATE_NEW_FLAG, NULL);
270 PCCRL_CONTEXT context;
278 context = CertGetCRLFromStore(NULL, NULL, NULL, NULL);
279 context = CertGetCRLFromStore(store, NULL, NULL, NULL);
284 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
285 ok(!context && GetLastError() == E_INVALIDARG,
286 "Expected E_INVALIDARG, got %08x\n", GetLastError());
288 /* Test an empty store */
290 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
291 ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
292 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
294 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
295 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
296 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
298 /* NULL matches any CRL */
300 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
301 ok(context != NULL, "Expected a context\n");
302 CertFreeCRLContext(context);
304 /* This cert's issuer isn't in */
305 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
307 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
309 context = CertGetCRLFromStore(store, cert, NULL, &flags);
310 ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
311 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
312 CertFreeCertificateContext(cert);
314 /* But this one is */
315 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
317 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
319 context = CertGetCRLFromStore(store, cert, NULL, &flags);
320 ok(context != NULL, "Expected a context\n");
321 CertFreeCRLContext(context);
322 CertFreeCertificateContext(cert);
324 CertCloseStore(store, 0);
327 static void checkCRLHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
328 PCCRL_CONTEXT context, DWORD propID)
330 BYTE hash[20] = { 0 }, hashProperty[20];
334 memset(hash, 0, sizeof(hash));
335 memset(hashProperty, 0, sizeof(hashProperty));
337 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
338 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
339 ret = CertGetCRLContextProperty(context, propID, hashProperty, &size);
340 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
341 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
345 static void testCRLProperties(void)
347 PCCRL_CONTEXT context = CertCreateCRLContext(X509_ASN_ENCODING,
350 ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
353 DWORD propID, numProps, access, size;
355 BYTE hash[20] = { 0 }, hashProperty[20];
356 CRYPT_DATA_BLOB blob;
359 propID = CertEnumCRLContextProperties(NULL, 0);
365 propID = CertEnumCRLContextProperties(context, propID);
368 } while (propID != 0);
369 ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
371 /* Tests with a NULL cert context. Prop ID 0 fails.. */
372 ret = CertSetCRLContextProperty(NULL, 0, 0, NULL);
373 ok(!ret && GetLastError() == E_INVALIDARG,
374 "Expected E_INVALIDARG, got %08x\n", GetLastError());
375 /* while this just crashes.
376 ret = CertSetCRLContextProperty(NULL, CERT_KEY_PROV_HANDLE_PROP_ID, 0,
380 ret = CertSetCRLContextProperty(context, 0, 0, NULL);
381 ok(!ret && GetLastError() == E_INVALIDARG,
382 "Expected E_INVALIDARG, got %08x\n", GetLastError());
383 /* Can't set the cert property directly, this crashes.
384 ret = CertSetCRLContextProperty(context, CERT_CRL_PROP_ID, 0, CRL);
388 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
390 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID, NULL, NULL);
391 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
396 ret = CertGetCRLContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID,
398 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
399 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
400 /* And, an implicit property */
401 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
403 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
404 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
406 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
407 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
408 "Didn't expect a persisted crl\n");
409 /* Trying to set this "read only" property crashes.
410 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
411 ret = CertSetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
415 /* Can I set the hash to an invalid hash? */
417 blob.cbData = sizeof(hash);
418 ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, &blob);
419 ok(ret, "CertSetCRLContextProperty failed: %08x\n",
421 size = sizeof(hashProperty);
422 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
423 hashProperty, &size);
424 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
425 /* Delete the (bogus) hash, and get the real one */
426 ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, NULL);
427 ok(ret, "CertSetCRLContextProperty failed: %08x\n", GetLastError());
428 checkCRLHash(CRL, sizeof(CRL), CALG_SHA1, context, CERT_HASH_PROP_ID);
430 /* Now that the hash property is set, we should get one property when
436 propID = CertEnumCRLContextProperties(context, propID);
439 } while (propID != 0);
440 ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
442 /* Check a few other implicit properties */
443 checkCRLHash(CRL, sizeof(CRL), CALG_MD5, context,
444 CERT_MD5_HASH_PROP_ID);
446 CertFreeCRLContext(context);
450 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
451 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
452 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
453 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
454 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
455 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
456 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
457 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
458 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
459 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
460 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
461 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
462 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
463 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
464 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
465 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
466 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
467 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
468 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
469 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
470 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
471 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
472 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
473 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
474 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
475 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
476 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
477 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
478 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
479 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
480 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
481 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
482 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
483 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
484 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
485 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
486 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
487 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
488 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
489 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
490 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
491 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
492 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
493 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
494 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
495 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
496 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
499 static void testIsValidCRLForCert(void)
502 PCCERT_CONTEXT cert1, cert2;
506 if(!pCertIsValidCRLForCertificate) return;
508 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
509 sizeof(v1CRLWithIssuerAndEntry));
510 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
511 cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
513 ok(cert1 != NULL, "CertCreateCertificateContext failed: %08x\n",
517 ret = CertIsValidCRLForCertificate(NULL, NULL, 0, NULL);
518 ret = CertIsValidCRLForCertificate(cert1, NULL, 0, NULL);
521 /* Curiously, any CRL is valid for the NULL certificate */
522 ret = pCertIsValidCRLForCertificate(NULL, crl, 0, NULL);
523 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
525 /* Same issuer for both cert and CRL, this CRL is valid for that cert */
526 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
527 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
529 cert2 = CertCreateCertificateContext(X509_ASN_ENCODING,
530 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer));
531 ok(cert2 != NULL, "CertCreateCertificateContext failed: %08x\n",
534 /* Yet more curious: different issuers for these, yet the CRL is valid for
535 * that cert. According to MSDN, the relevant bit to check is whether the
536 * CRL has a CRL_ISSUING_DIST_POINT extension.
538 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
539 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
541 CertFreeCRLContext(crl);
543 /* Yet with a CRL_ISSUING_DIST_POINT in the CRL, I still can't get this
544 * to say the CRL is not valid for either cert.
546 crl = CertCreateCRLContext(X509_ASN_ENCODING, v2CRLWithIssuingDistPoint,
547 sizeof(v2CRLWithIssuingDistPoint));
548 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
550 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
551 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
552 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
553 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
555 CertFreeCRLContext(crl);
557 /* And again, with a real CRL, the CRL is valid for both certs. */
558 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
559 sizeof(verisignCRL));
560 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
562 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
563 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
564 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
565 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
567 CertFreeCRLContext(crl);
569 /* One last test: a CRL in a different store than the cert is also valid
570 * for the cert, so CertIsValidCRLForCertificate must always return TRUE?
572 store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
573 CERT_STORE_CREATE_NEW_FLAG, NULL);
574 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
576 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, verisignCRL,
577 sizeof(verisignCRL), CERT_STORE_ADD_ALWAYS, &crl);
578 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
580 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
581 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
582 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
583 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
585 CertFreeCRLContext(crl);
587 CertCloseStore(store, 0);
589 CertFreeCertificateContext(cert2);
590 CertFreeCertificateContext(cert1);
593 static const BYTE crlWithDifferentIssuer[] = {
594 0x30,0x47,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
595 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x41,0x6c,0x65,0x78,0x20,0x4c,0x61,0x6e,
596 0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
597 0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
598 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a };
600 static void testFindCertInCRL(void)
607 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
609 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
613 ret = CertFindCertificateInCRL(NULL, NULL, 0, NULL, NULL);
614 ret = CertFindCertificateInCRL(NULL, crl, 0, NULL, NULL);
615 ret = CertFindCertificateInCRL(cert, NULL, 0, NULL, NULL);
616 ret = CertFindCertificateInCRL(cert, crl, 0, NULL, NULL);
617 ret = CertFindCertificateInCRL(NULL, NULL, 0, NULL, &entry);
618 ret = CertFindCertificateInCRL(NULL, crl, 0, NULL, &entry);
619 ret = CertFindCertificateInCRL(cert, NULL, 0, NULL, &entry);
622 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
623 sizeof(verisignCRL));
624 ret = CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
625 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
626 ok(entry == NULL, "Expected not to find an entry in CRL\n");
627 CertFreeCRLContext(crl);
629 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
630 sizeof(v1CRLWithIssuerAndEntry));
631 ret = CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
632 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
633 ok(entry != NULL, "Expected to find an entry in CRL\n");
634 CertFreeCRLContext(crl);
636 /* Entry found even though CRL issuer doesn't match cert issuer */
637 crl = CertCreateCRLContext(X509_ASN_ENCODING, crlWithDifferentIssuer,
638 sizeof(crlWithDifferentIssuer));
639 ret = CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
640 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
641 ok(entry != NULL, "Expected to find an entry in CRL\n");
642 CertFreeCRLContext(crl);
644 CertFreeCertificateContext(cert);
647 static void testVerifyCRLRevocation(void)
653 ret = CertVerifyCRLRevocation(0, NULL, 0, NULL);
654 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
655 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, NULL, 0, NULL);
656 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
658 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
661 /* Check against no CRL */
662 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 0, NULL);
663 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
664 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 0, NULL);
665 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
667 /* Check against CRL with entry for the cert */
668 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
669 sizeof(v1CRLWithIssuerAndEntry));
670 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
671 (PCRL_INFO *)&crl->pCrlInfo);
672 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
673 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
674 (PCRL_INFO *)&crl->pCrlInfo);
675 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
676 CertFreeCRLContext(crl);
678 /* Check against CRL with different issuer and entry for the cert */
679 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
680 sizeof(v1CRLWithIssuerAndEntry));
681 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
682 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
683 (PCRL_INFO *)&crl->pCrlInfo);
684 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
685 CertFreeCRLContext(crl);
687 /* Check against CRL without entry for the cert */
688 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
689 sizeof(verisignCRL));
690 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
691 (PCRL_INFO *)&crl->pCrlInfo);
692 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
693 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
694 (PCRL_INFO *)&crl->pCrlInfo);
695 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
696 CertFreeCRLContext(crl);
698 CertFreeCertificateContext(cert);
703 init_function_pointers();
708 testGetCRLFromStore();
712 testIsValidCRLForCert();
714 testVerifyCRLRevocation();