crypt32: Implement CertGetCRLFromStore.
[wine/wine-kai.git] / dlls / crypt32 / tests / crl.c
blob5d0ddc6178a7cd9a7b121d9670bdf40462f1e052
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"
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,
62 0x02, 0x01, 0x01 };
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,
67 0x5a };
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 void testCreateCRL(void)
81 PCCRL_CONTEXT context;
83 context = CertCreateCRLContext(0, NULL, 0);
84 ok(!context && GetLastError() == E_INVALIDARG,
85 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
86 context = CertCreateCRLContext(X509_ASN_ENCODING, NULL, 0);
87 ok(!context && GetLastError() == CRYPT_E_ASN1_EOD,
88 "Expected CRYPT_E_ASN1_EOD, got %08lx\n", GetLastError());
89 context = CertCreateCRLContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
90 ok(!context && GetLastError() == CRYPT_E_ASN1_CORRUPT,
91 "Expected CRYPT_E_ASN1_CORRUPT, got %08lx\n", GetLastError());
92 context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
93 sizeof(signedCRL) - 1);
94 ok(!context && (GetLastError() == CRYPT_E_ASN1_EOD ||
95 GetLastError() == CRYPT_E_ASN1_CORRUPT),
96 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08lx\n",
97 GetLastError());
98 context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
99 sizeof(signedCRL));
100 ok(context != NULL, "CertCreateCRLContext failed: %08lx\n", GetLastError());
101 if (context)
102 CertFreeCRLContext(context);
103 context = CertCreateCRLContext(X509_ASN_ENCODING, CRL, sizeof(CRL));
104 ok(context != NULL, "CertCreateCRLContext failed: %08lx\n", GetLastError());
105 if (context)
106 CertFreeCRLContext(context);
109 static void testAddCRL(void)
111 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
112 CERT_STORE_CREATE_NEW_FLAG, NULL);
113 PCCRL_CONTEXT context;
114 BOOL ret;
116 if (!store) return;
118 /* Bad CRL encoding type */
119 ret = CertAddEncodedCRLToStore(0, 0, NULL, 0, 0, NULL);
120 ok(!ret && GetLastError() == E_INVALIDARG,
121 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
122 ret = CertAddEncodedCRLToStore(store, 0, NULL, 0, 0, NULL);
123 ok(!ret && GetLastError() == E_INVALIDARG,
124 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
125 ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL), 0, NULL);
126 ok(!ret && GetLastError() == E_INVALIDARG,
127 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
128 ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL), 0,
129 NULL);
130 ok(!ret && GetLastError() == E_INVALIDARG,
131 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
132 ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL),
133 CERT_STORE_ADD_ALWAYS, NULL);
134 ok(!ret && GetLastError() == E_INVALIDARG,
135 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
136 ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL),
137 CERT_STORE_ADD_ALWAYS, NULL);
138 ok(!ret && GetLastError() == E_INVALIDARG,
139 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
141 /* No CRL */
142 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, NULL, 0, 0, NULL);
143 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
144 "Expected CRYPT_E_ASN1_EOD, got %08lx\n", GetLastError());
145 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, NULL, 0, 0, NULL);
146 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
147 "Expected CRYPT_E_ASN1_EOD, got %08lx\n", GetLastError());
149 /* Weird--bad add disposition leads to an access violation in Windows. */
150 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
151 sizeof(signedCRL), 0, NULL);
152 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
153 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
154 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
155 sizeof(signedCRL), 0, NULL);
156 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
157 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
159 /* Weird--can add a CRL to the NULL store (does this have special meaning?)
161 context = NULL;
162 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
163 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &context);
164 ok(ret, "CertAddEncodedCRLToStore failed: %08lx\n", GetLastError());
165 if (context)
166 CertFreeCRLContext(context);
168 /* Normal cases: a "signed" CRL is okay.. */
169 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
170 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
171 /* and an unsigned one is too. */
172 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, CRL, sizeof(CRL),
173 CERT_STORE_ADD_ALWAYS, NULL);
174 ok(ret, "CertAddEncodedCRLToStore failed: %08lx\n", GetLastError());
176 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
177 sizeof(newerCRL), CERT_STORE_ADD_NEW, NULL);
178 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
179 "Expected CRYPT_E_EXISTS, got %08lx\n", GetLastError());
181 /* This should replace (one of) the existing CRL(s). */
182 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
183 sizeof(newerCRL), CERT_STORE_ADD_NEWER, NULL);
184 ok(ret, "CertAddEncodedCRLToStore failed: %08lx\n", GetLastError());
186 CertCloseStore(store, 0);
189 static void testFindCRL(void)
191 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
192 CERT_STORE_CREATE_NEW_FLAG, NULL);
193 PCCRL_CONTEXT context;
194 PCCERT_CONTEXT cert;
195 BOOL ret;
197 if (!store) return;
199 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
200 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
201 ok(ret, "CertAddEncodedCRLToStore failed: %08lx\n", GetLastError());
203 /* Crashes
204 context = CertFindCRLInStore(NULL, 0, 0, 0, NULL, NULL);
207 /* Find any context */
208 context = CertFindCRLInStore(store, 0, 0, CRL_FIND_ANY, NULL, NULL);
209 ok(context != NULL, "Expected a context\n");
210 if (context)
211 CertFreeCRLContext(context);
212 /* Bogus flags are ignored */
213 context = CertFindCRLInStore(store, 0, 1234, CRL_FIND_ANY, NULL, NULL);
214 ok(context != NULL, "Expected a context\n");
215 if (context)
216 CertFreeCRLContext(context);
217 /* CRL encoding type is ignored too */
218 context = CertFindCRLInStore(store, 1234, 0, CRL_FIND_ANY, NULL, NULL);
219 ok(context != NULL, "Expected a context\n");
220 if (context)
221 CertFreeCRLContext(context);
223 /* This appears to match any cert */
224 context = CertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, NULL, NULL);
225 ok(context != NULL, "Expected a context\n");
226 if (context)
227 CertFreeCRLContext(context);
229 /* Try to match an issuer that isn't in the store */
230 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
231 sizeof(bigCert2));
232 ok(cert != NULL, "CertCreateCertificateContext failed: %08lx\n",
233 GetLastError());
234 context = CertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
235 ok(context == NULL, "Expected no matching context\n");
236 CertFreeCertificateContext(cert);
238 /* Match an issuer that is in the store */
239 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
240 sizeof(bigCert));
241 ok(cert != NULL, "CertCreateCertificateContext failed: %08lx\n",
242 GetLastError());
243 context = CertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
244 ok(context != NULL, "Expected a context\n");
245 if (context)
246 CertFreeCRLContext(context);
247 CertFreeCertificateContext(cert);
249 CertCloseStore(store, 0);
252 static void testGetCRLFromStore(void)
254 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
255 CERT_STORE_CREATE_NEW_FLAG, NULL);
256 PCCRL_CONTEXT context;
257 PCCERT_CONTEXT cert;
258 DWORD flags;
259 BOOL ret;
261 if (!store) return;
263 /* Crash
264 context = CertGetCRLFromStore(NULL, NULL, NULL, NULL);
265 context = CertGetCRLFromStore(store, NULL, NULL, NULL);
268 /* Bogus flags */
269 flags = 0xffffffff;
270 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
271 ok(!context && GetLastError() == E_INVALIDARG,
272 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
274 /* Test an empty store */
275 flags = 0;
276 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
277 ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
278 "Expected CRYPT_E_NOT_FOUND, got %08lx\n", GetLastError());
280 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
281 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
282 ok(ret, "CertAddEncodedCRLToStore failed: %08lx\n", GetLastError());
284 /* NULL matches any CRL */
285 flags = 0;
286 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
287 ok(context != NULL, "Expected a context\n");
288 CertFreeCRLContext(context);
290 /* This cert's issuer isn't in */
291 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
292 sizeof(bigCert2));
293 ok(cert != NULL, "CertCreateCertificateContext failed: %08lx\n",
294 GetLastError());
295 context = CertGetCRLFromStore(store, cert, NULL, &flags);
296 ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
297 "Expected CRYPT_E_NOT_FOUND, got %08lx\n", GetLastError());
298 CertFreeCertificateContext(cert);
300 /* But this one is */
301 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
302 sizeof(bigCert));
303 ok(cert != NULL, "CertCreateCertificateContext failed: %08lx\n",
304 GetLastError());
305 context = CertGetCRLFromStore(store, cert, NULL, &flags);
306 ok(context != NULL, "Expected a context\n");
307 CertFreeCRLContext(context);
308 CertFreeCertificateContext(cert);
310 CertCloseStore(store, 0);
313 static void checkCRLHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
314 PCCRL_CONTEXT context, DWORD propID)
316 BYTE hash[20] = { 0 }, hashProperty[20];
317 BOOL ret;
318 DWORD size;
320 memset(hash, 0, sizeof(hash));
321 memset(hashProperty, 0, sizeof(hashProperty));
322 size = sizeof(hash);
323 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
324 ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError());
325 ret = CertGetCRLContextProperty(context, propID, hashProperty, &size);
326 ok(ret, "CertGetCRLContextProperty failed: %08lx\n", GetLastError());
327 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %ld\n",
328 propID);
331 static void testCRLProperties(void)
333 PCCRL_CONTEXT context = CertCreateCRLContext(X509_ASN_ENCODING,
334 CRL, sizeof(CRL));
336 ok(context != NULL, "CertCreateCRLContext failed: %08lx\n", GetLastError());
337 if (context)
339 DWORD propID, numProps, access, size;
340 BOOL ret;
341 BYTE hash[20] = { 0 }, hashProperty[20];
342 CRYPT_DATA_BLOB blob;
344 /* This crashes
345 propID = CertEnumCRLContextProperties(NULL, 0);
348 propID = 0;
349 numProps = 0;
350 do {
351 propID = CertEnumCRLContextProperties(context, propID);
352 if (propID)
353 numProps++;
354 } while (propID != 0);
355 ok(numProps == 0, "Expected 0 properties, got %ld\n", numProps);
357 /* Tests with a NULL cert context. Prop ID 0 fails.. */
358 ret = CertSetCRLContextProperty(NULL, 0, 0, NULL);
359 ok(!ret && GetLastError() == E_INVALIDARG,
360 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
361 /* while this just crashes.
362 ret = CertSetCRLContextProperty(NULL, CERT_KEY_PROV_HANDLE_PROP_ID, 0,
363 NULL);
366 ret = CertSetCRLContextProperty(context, 0, 0, NULL);
367 ok(!ret && GetLastError() == E_INVALIDARG,
368 "Expected E_INVALIDARG, got %08lx\n", GetLastError());
369 /* Can't set the cert property directly, this crashes.
370 ret = CertSetCRLContextProperty(context, CERT_CRL_PROP_ID, 0, CRL);
373 /* These all crash.
374 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
375 NULL);
376 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID, NULL, NULL);
377 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
378 hashProperty, NULL);
380 /* A missing prop */
381 size = 0;
382 ret = CertGetCRLContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID,
383 NULL, &size);
384 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
385 "Expected CRYPT_E_NOT_FOUND, got %08lx\n", GetLastError());
386 /* And, an implicit property */
387 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
388 NULL, &size);
389 ok(ret, "CertGetCRLContextProperty failed: %08lx\n", GetLastError());
390 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
391 &access, &size);
392 ok(ret, "CertGetCRLContextProperty failed: %08lx\n", GetLastError());
393 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
394 "Didn't expect a persisted crl\n");
395 /* Trying to set this "read only" property crashes.
396 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
397 ret = CertSetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
398 &access);
401 /* Can I set the hash to an invalid hash? */
402 blob.pbData = hash;
403 blob.cbData = sizeof(hash);
404 ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, &blob);
405 ok(ret, "CertSetCRLContextProperty failed: %08lx\n",
406 GetLastError());
407 size = sizeof(hashProperty);
408 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
409 hashProperty, &size);
410 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
411 /* Delete the (bogus) hash, and get the real one */
412 ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, NULL);
413 ok(ret, "CertSetCRLContextProperty failed: %08lx\n", GetLastError());
414 checkCRLHash(CRL, sizeof(CRL), CALG_SHA1, context, CERT_HASH_PROP_ID);
416 /* Now that the hash property is set, we should get one property when
417 * enumerating.
419 propID = 0;
420 numProps = 0;
421 do {
422 propID = CertEnumCRLContextProperties(context, propID);
423 if (propID)
424 numProps++;
425 } while (propID != 0);
426 ok(numProps == 1, "Expected 1 properties, got %ld\n", numProps);
428 /* Check a few other implicit properties */
429 checkCRLHash(CRL, sizeof(CRL), CALG_MD5, context,
430 CERT_MD5_HASH_PROP_ID);
432 CertFreeCRLContext(context);
436 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
437 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
438 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
439 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
440 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
441 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
442 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
443 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
444 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
445 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
446 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
447 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
448 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
449 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
450 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
451 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
452 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
453 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
454 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
455 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
456 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
457 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
458 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
459 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
460 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
461 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
462 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
463 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
464 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
465 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
466 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
467 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
468 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
469 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
470 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
471 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
472 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
473 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
474 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
475 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
476 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
477 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
478 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
479 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
480 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
481 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
482 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
483 0xcd };
485 static void testIsValidCRLForCert(void)
487 BOOL ret;
488 PCCERT_CONTEXT cert1, cert2;
489 PCCRL_CONTEXT crl;
490 HCERTSTORE store;
492 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
493 sizeof(v1CRLWithIssuerAndEntry));
494 ok(crl != NULL, "CertCreateCRLContext failed: %08lx\n", GetLastError());
495 cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
496 sizeof(bigCert));
497 ok(cert1 != NULL, "CertCreateCertificateContext failed: %08lx\n",
498 GetLastError());
500 /* Crash
501 ret = CertIsValidCRLForCertificate(NULL, NULL, 0, NULL);
502 ret = CertIsValidCRLForCertificate(cert1, NULL, 0, NULL);
505 /* Curiously, any CRL is valid for the NULL certificate */
506 ret = CertIsValidCRLForCertificate(NULL, crl, 0, NULL);
507 ok(ret, "CertIsValidCRLForCertificate failed: %08lx\n", GetLastError());
509 /* Same issuer for both cert and CRL, this CRL is valid for that cert */
510 ret = CertIsValidCRLForCertificate(cert1, crl, 0, NULL);
511 ok(ret, "CertIsValidCRLForCertificate failed: %08lx\n", GetLastError());
513 cert2 = CertCreateCertificateContext(X509_ASN_ENCODING,
514 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer));
515 ok(cert2 != NULL, "CertCreateCertificateContext failed: %08lx\n",
516 GetLastError());
518 /* Yet more curious: different issuers for these, yet the CRL is valid for
519 * that cert. According to MSDN, the relevant bit to check is whether the
520 * CRL has a CRL_ISSUING_DIST_POINT extension.
522 ret = CertIsValidCRLForCertificate(cert2, crl, 0, NULL);
523 ok(ret, "CertIsValidCRLForCertificate failed: %08lx\n", GetLastError());
525 CertFreeCRLContext(crl);
527 /* Yet with a CRL_ISSUING_DIST_POINT in the CRL, I still can't get this
528 * to say the CRL is not valid for either cert.
530 crl = CertCreateCRLContext(X509_ASN_ENCODING, v2CRLWithIssuingDistPoint,
531 sizeof(v2CRLWithIssuingDistPoint));
532 ok(crl != NULL, "CertCreateCRLContext failed: %08lx\n", GetLastError());
534 ret = CertIsValidCRLForCertificate(cert1, crl, 0, NULL);
535 ok(ret, "CertIsValidCRLForCertificate failed: %08lx\n", GetLastError());
536 ret = CertIsValidCRLForCertificate(cert2, crl, 0, NULL);
537 ok(ret, "CertIsValidCRLForCertificate failed: %08lx\n", GetLastError());
539 CertFreeCRLContext(crl);
541 /* And again, with a real CRL, the CRL is valid for both certs. */
542 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
543 sizeof(verisignCRL));
544 ok(crl != NULL, "CertCreateCRLContext failed: %08lx\n", GetLastError());
546 ret = CertIsValidCRLForCertificate(cert1, crl, 0, NULL);
547 ok(ret, "CertIsValidCRLForCertificate failed: %08lx\n", GetLastError());
548 ret = CertIsValidCRLForCertificate(cert2, crl, 0, NULL);
549 ok(ret, "CertIsValidCRLForCertificate failed: %08lx\n", GetLastError());
551 CertFreeCRLContext(crl);
553 /* One last test: a CRL in a different store than the cert is also valid
554 * for the cert, so CertIsValidCRLForCertificate must always return TRUE?
556 store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
557 CERT_STORE_CREATE_NEW_FLAG, NULL);
558 ok(store != NULL, "CertOpenStore failed: %08lx\n", GetLastError());
560 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, verisignCRL,
561 sizeof(verisignCRL), CERT_STORE_ADD_ALWAYS, &crl);
562 ok(ret, "CertAddEncodedCRLToStore failed: %08lx\n", GetLastError());
564 ret = CertIsValidCRLForCertificate(cert1, crl, 0, NULL);
565 ok(ret, "CertIsValidCRLForCertificate failed: %08lx\n", GetLastError());
566 ret = CertIsValidCRLForCertificate(cert2, crl, 0, NULL);
567 ok(ret, "CertIsValidCRLForCertificate failed: %08lx\n", GetLastError());
569 CertFreeCRLContext(crl);
571 CertCloseStore(store, 0);
573 CertFreeCertificateContext(cert2);
574 CertFreeCertificateContext(cert1);
577 static const BYTE crlWithDifferentIssuer[] = {
578 0x30,0x47,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
579 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x41,0x6c,0x65,0x78,0x20,0x4c,0x61,0x6e,
580 0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
581 0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
582 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a };
584 static void testFindCertInCRL(void)
586 BOOL ret;
587 PCCERT_CONTEXT cert;
588 PCCRL_CONTEXT crl;
589 PCRL_ENTRY entry;
591 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
592 sizeof(bigCert));
593 ok(cert != NULL, "CertCreateCertificateContext failed: %08lx\n",
594 GetLastError());
596 /* Crash
597 ret = CertFindCertificateInCRL(NULL, NULL, 0, NULL, NULL);
598 ret = CertFindCertificateInCRL(NULL, crl, 0, NULL, NULL);
599 ret = CertFindCertificateInCRL(cert, NULL, 0, NULL, NULL);
600 ret = CertFindCertificateInCRL(cert, crl, 0, NULL, NULL);
601 ret = CertFindCertificateInCRL(NULL, NULL, 0, NULL, &entry);
602 ret = CertFindCertificateInCRL(NULL, crl, 0, NULL, &entry);
603 ret = CertFindCertificateInCRL(cert, NULL, 0, NULL, &entry);
606 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
607 sizeof(verisignCRL));
608 ret = CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
609 ok(ret, "CertFindCertificateInCRL failed: %08lx\n", GetLastError());
610 ok(entry == NULL, "Expected not to find an entry in CRL\n");
611 CertFreeCRLContext(crl);
613 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
614 sizeof(v1CRLWithIssuerAndEntry));
615 ret = CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
616 ok(ret, "CertFindCertificateInCRL failed: %08lx\n", GetLastError());
617 ok(entry != NULL, "Expected to find an entry in CRL\n");
618 CertFreeCRLContext(crl);
620 /* Entry found even though CRL issuer doesn't match cert issuer */
621 crl = CertCreateCRLContext(X509_ASN_ENCODING, crlWithDifferentIssuer,
622 sizeof(crlWithDifferentIssuer));
623 ret = CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
624 ok(ret, "CertFindCertificateInCRL failed: %08lx\n", GetLastError());
625 ok(entry != NULL, "Expected to find an entry in CRL\n");
626 CertFreeCRLContext(crl);
628 CertFreeCertificateContext(cert);
631 static void testVerifyCRLRevocation(void)
633 BOOL ret;
634 PCCERT_CONTEXT cert;
635 PCCRL_CONTEXT crl;
637 ret = CertVerifyCRLRevocation(0, NULL, 0, NULL);
638 ok(ret, "CertVerifyCRLRevocation failed: %08lx\n", GetLastError());
639 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, NULL, 0, NULL);
640 ok(ret, "CertVerifyCRLRevocation failed: %08lx\n", GetLastError());
642 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
643 sizeof(bigCert));
645 /* Check against no CRL */
646 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 0, NULL);
647 ok(ret, "CertVerifyCRLRevocation failed: %08lx\n", GetLastError());
648 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 0, NULL);
649 ok(ret, "CertVerifyCRLRevocation failed: %08lx\n", GetLastError());
651 /* Check against CRL with entry for the cert */
652 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
653 sizeof(v1CRLWithIssuerAndEntry));
654 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
655 (PCRL_INFO *)&crl->pCrlInfo);
656 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
657 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
658 (PCRL_INFO *)&crl->pCrlInfo);
659 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
660 CertFreeCRLContext(crl);
662 /* Check against CRL with different issuer and entry for the cert */
663 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
664 sizeof(v1CRLWithIssuerAndEntry));
665 ok(crl != NULL, "CertCreateCRLContext failed: %08lx\n", GetLastError());
666 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
667 (PCRL_INFO *)&crl->pCrlInfo);
668 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
669 CertFreeCRLContext(crl);
671 /* Check against CRL without entry for the cert */
672 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
673 sizeof(verisignCRL));
674 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
675 (PCRL_INFO *)&crl->pCrlInfo);
676 ok(ret, "CertVerifyCRLRevocation failed: %08lx\n", GetLastError());
677 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
678 (PCRL_INFO *)&crl->pCrlInfo);
679 ok(ret, "CertVerifyCRLRevocation failed: %08lx\n", GetLastError());
680 CertFreeCRLContext(crl);
682 CertFreeCertificateContext(cert);
685 START_TEST(crl)
687 testCreateCRL();
688 testAddCRL();
689 testFindCRL();
690 testGetCRLFromStore();
692 testCRLProperties();
694 testIsValidCRLForCert();
695 testFindCertInCRL();
696 testVerifyCRLRevocation();