push 585d938e6dafa7e4b71343fb5b928a9214e5518c
[wine/hacks.git] / dlls / crypt32 / tests / crl.c
blob561953b32f2e186b5d5009d659273d6a85dbf4ad
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 testAddCRL(void)
123 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
124 CERT_STORE_CREATE_NEW_FLAG, NULL);
125 PCCRL_CONTEXT context;
126 BOOL ret;
127 DWORD GLE;
129 if (!store) return;
131 /* Bad CRL encoding type */
132 ret = CertAddEncodedCRLToStore(0, 0, NULL, 0, 0, NULL);
133 ok(!ret && GetLastError() == E_INVALIDARG,
134 "Expected E_INVALIDARG, got %08x\n", GetLastError());
135 ret = CertAddEncodedCRLToStore(store, 0, NULL, 0, 0, NULL);
136 ok(!ret && GetLastError() == E_INVALIDARG,
137 "Expected E_INVALIDARG, got %08x\n", GetLastError());
138 ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL), 0, NULL);
139 ok(!ret && GetLastError() == E_INVALIDARG,
140 "Expected E_INVALIDARG, got %08x\n", GetLastError());
141 ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL), 0,
142 NULL);
143 ok(!ret && GetLastError() == E_INVALIDARG,
144 "Expected E_INVALIDARG, got %08x\n", GetLastError());
145 ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL),
146 CERT_STORE_ADD_ALWAYS, NULL);
147 ok(!ret && GetLastError() == E_INVALIDARG,
148 "Expected E_INVALIDARG, got %08x\n", GetLastError());
149 ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL),
150 CERT_STORE_ADD_ALWAYS, NULL);
151 ok(!ret && GetLastError() == E_INVALIDARG,
152 "Expected E_INVALIDARG, got %08x\n", GetLastError());
154 /* No CRL */
155 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, NULL, 0, 0, NULL);
156 GLE = GetLastError();
157 ok(!ret && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
158 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
159 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, NULL, 0, 0, NULL);
160 GLE = GetLastError();
161 ok(!ret && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
162 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
164 /* Weird--bad add disposition leads to an access violation in Windows. */
165 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
166 sizeof(signedCRL), 0, NULL);
167 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
168 GetLastError() == E_INVALIDARG /* Vista */),
169 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n", GetLastError());
170 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
171 sizeof(signedCRL), 0, NULL);
172 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
173 GetLastError() == E_INVALIDARG /* Vista */),
174 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
176 /* Weird--can add a CRL to the NULL store (does this have special meaning?)
178 context = NULL;
179 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
180 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &context);
181 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
182 if (context)
183 CertFreeCRLContext(context);
185 /* Normal cases: a "signed" CRL is okay.. */
186 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
187 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
188 /* and an unsigned one is too. */
189 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, CRL, sizeof(CRL),
190 CERT_STORE_ADD_ALWAYS, NULL);
191 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
193 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
194 sizeof(newerCRL), CERT_STORE_ADD_NEW, NULL);
195 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
196 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
198 /* This should replace (one of) the existing CRL(s). */
199 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
200 sizeof(newerCRL), CERT_STORE_ADD_NEWER, NULL);
201 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
203 CertCloseStore(store, 0);
206 static void testFindCRL(void)
208 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
209 CERT_STORE_CREATE_NEW_FLAG, NULL);
210 PCCRL_CONTEXT context;
211 PCCERT_CONTEXT cert;
212 BOOL ret;
214 if (!store) return;
215 if (!pCertFindCRLInStore)
217 skip("CertFindCRLInStore() is not available\n");
218 return;
221 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
222 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
223 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
225 /* Crashes
226 context = pCertFindCRLInStore(NULL, 0, 0, 0, NULL, NULL);
229 /* Find any context */
230 context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ANY, NULL, NULL);
231 ok(context != NULL, "Expected a context\n");
232 if (context)
233 CertFreeCRLContext(context);
234 /* Bogus flags are ignored */
235 context = pCertFindCRLInStore(store, 0, 1234, CRL_FIND_ANY, NULL, NULL);
236 ok(context != NULL, "Expected a context\n");
237 if (context)
238 CertFreeCRLContext(context);
239 /* CRL encoding type is ignored too */
240 context = pCertFindCRLInStore(store, 1234, 0, CRL_FIND_ANY, NULL, NULL);
241 ok(context != NULL, "Expected a context\n");
242 if (context)
243 CertFreeCRLContext(context);
245 /* This appears to match any cert */
246 context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, NULL, NULL);
247 ok(context != NULL, "Expected a context\n");
248 if (context)
249 CertFreeCRLContext(context);
251 /* Try to match an issuer that isn't in the store */
252 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
253 sizeof(bigCert2));
254 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
255 GetLastError());
256 context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
257 ok(context == NULL, "Expected no matching context\n");
258 CertFreeCertificateContext(cert);
260 /* Match an issuer that is in the store */
261 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
262 sizeof(bigCert));
263 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
264 GetLastError());
265 context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
266 ok(context != NULL, "Expected a context\n");
267 if (context)
268 CertFreeCRLContext(context);
269 CertFreeCertificateContext(cert);
271 CertCloseStore(store, 0);
274 static void testGetCRLFromStore(void)
276 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
277 CERT_STORE_CREATE_NEW_FLAG, NULL);
278 PCCRL_CONTEXT context;
279 PCCERT_CONTEXT cert;
280 DWORD flags;
281 BOOL ret;
283 if (!store) return;
285 /* Crash
286 context = CertGetCRLFromStore(NULL, NULL, NULL, NULL);
287 context = CertGetCRLFromStore(store, NULL, NULL, NULL);
290 /* Bogus flags */
291 flags = 0xffffffff;
292 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
293 ok(!context && GetLastError() == E_INVALIDARG,
294 "Expected E_INVALIDARG, got %08x\n", GetLastError());
296 /* Test an empty store */
297 flags = 0;
298 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
299 ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
300 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
302 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
303 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
304 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
306 /* NULL matches any CRL */
307 flags = 0;
308 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
309 ok(context != NULL, "Expected a context\n");
310 CertFreeCRLContext(context);
312 /* This cert's issuer isn't in */
313 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
314 sizeof(bigCert2));
315 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
316 GetLastError());
317 context = CertGetCRLFromStore(store, cert, NULL, &flags);
318 ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
319 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
320 CertFreeCertificateContext(cert);
322 /* But this one is */
323 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
324 sizeof(bigCert));
325 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
326 GetLastError());
327 context = CertGetCRLFromStore(store, cert, NULL, &flags);
328 ok(context != NULL, "Expected a context\n");
329 CertFreeCRLContext(context);
330 CertFreeCertificateContext(cert);
332 CertCloseStore(store, 0);
335 static void checkCRLHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
336 PCCRL_CONTEXT context, DWORD propID)
338 BYTE hash[20] = { 0 }, hashProperty[20];
339 BOOL ret;
340 DWORD size;
342 memset(hash, 0, sizeof(hash));
343 memset(hashProperty, 0, sizeof(hashProperty));
344 size = sizeof(hash);
345 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
346 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
347 ret = CertGetCRLContextProperty(context, propID, hashProperty, &size);
348 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
349 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
350 propID);
353 static void testCRLProperties(void)
355 PCCRL_CONTEXT context = CertCreateCRLContext(X509_ASN_ENCODING,
356 CRL, sizeof(CRL));
358 ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
359 if (context)
361 DWORD propID, numProps, access, size;
362 BOOL ret;
363 BYTE hash[20] = { 0 }, hashProperty[20];
364 CRYPT_DATA_BLOB blob;
366 /* This crashes
367 propID = CertEnumCRLContextProperties(NULL, 0);
370 propID = 0;
371 numProps = 0;
372 do {
373 propID = CertEnumCRLContextProperties(context, propID);
374 if (propID)
375 numProps++;
376 } while (propID != 0);
377 ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
379 /* Tests with a NULL cert context. Prop ID 0 fails.. */
380 ret = CertSetCRLContextProperty(NULL, 0, 0, NULL);
381 ok(!ret && GetLastError() == E_INVALIDARG,
382 "Expected E_INVALIDARG, got %08x\n", GetLastError());
383 /* while this just crashes.
384 ret = CertSetCRLContextProperty(NULL, CERT_KEY_PROV_HANDLE_PROP_ID, 0,
385 NULL);
388 ret = CertSetCRLContextProperty(context, 0, 0, NULL);
389 ok(!ret && GetLastError() == E_INVALIDARG,
390 "Expected E_INVALIDARG, got %08x\n", GetLastError());
391 /* Can't set the cert property directly, this crashes.
392 ret = CertSetCRLContextProperty(context, CERT_CRL_PROP_ID, 0, CRL);
395 /* These all crash.
396 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
397 NULL);
398 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID, NULL, NULL);
399 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
400 hashProperty, NULL);
402 /* A missing prop */
403 size = 0;
404 ret = CertGetCRLContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID,
405 NULL, &size);
406 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
407 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
408 /* And, an implicit property */
409 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
410 NULL, &size);
411 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
412 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
413 &access, &size);
414 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
415 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
416 "Didn't expect a persisted crl\n");
417 /* Trying to set this "read only" property crashes.
418 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
419 ret = CertSetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
420 &access);
423 /* Can I set the hash to an invalid hash? */
424 blob.pbData = hash;
425 blob.cbData = sizeof(hash);
426 ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, &blob);
427 ok(ret, "CertSetCRLContextProperty failed: %08x\n",
428 GetLastError());
429 size = sizeof(hashProperty);
430 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
431 hashProperty, &size);
432 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
433 /* Delete the (bogus) hash, and get the real one */
434 ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, NULL);
435 ok(ret, "CertSetCRLContextProperty failed: %08x\n", GetLastError());
436 checkCRLHash(CRL, sizeof(CRL), CALG_SHA1, context, CERT_HASH_PROP_ID);
438 /* Now that the hash property is set, we should get one property when
439 * enumerating.
441 propID = 0;
442 numProps = 0;
443 do {
444 propID = CertEnumCRLContextProperties(context, propID);
445 if (propID)
446 numProps++;
447 } while (propID != 0);
448 ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
450 /* Check a few other implicit properties */
451 checkCRLHash(CRL, sizeof(CRL), CALG_MD5, context,
452 CERT_MD5_HASH_PROP_ID);
454 CertFreeCRLContext(context);
458 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
459 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
460 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
461 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
462 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
463 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
464 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
465 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
466 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
467 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
468 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
469 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
470 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
471 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
472 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
473 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
474 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
475 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
476 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
477 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
478 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
479 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
480 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
481 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
482 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
483 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
484 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
485 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
486 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
487 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
488 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
489 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
490 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
491 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
492 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
493 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
494 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
495 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
496 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
497 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
498 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
499 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
500 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
501 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
502 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
503 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
504 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
505 0xcd };
507 static void testIsValidCRLForCert(void)
509 BOOL ret;
510 PCCERT_CONTEXT cert1, cert2;
511 PCCRL_CONTEXT crl;
512 HCERTSTORE store;
514 if(!pCertIsValidCRLForCertificate) return;
516 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
517 sizeof(v1CRLWithIssuerAndEntry));
518 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
519 cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
520 sizeof(bigCert));
521 ok(cert1 != NULL, "CertCreateCertificateContext failed: %08x\n",
522 GetLastError());
524 /* Crash
525 ret = CertIsValidCRLForCertificate(NULL, NULL, 0, NULL);
526 ret = CertIsValidCRLForCertificate(cert1, NULL, 0, NULL);
529 /* Curiously, any CRL is valid for the NULL certificate */
530 ret = pCertIsValidCRLForCertificate(NULL, crl, 0, NULL);
531 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
533 /* Same issuer for both cert and CRL, this CRL is valid for that cert */
534 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
535 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
537 cert2 = CertCreateCertificateContext(X509_ASN_ENCODING,
538 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer));
539 ok(cert2 != NULL, "CertCreateCertificateContext failed: %08x\n",
540 GetLastError());
542 /* Yet more curious: different issuers for these, yet the CRL is valid for
543 * that cert. According to MSDN, the relevant bit to check is whether the
544 * CRL has a CRL_ISSUING_DIST_POINT extension.
546 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
547 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
549 CertFreeCRLContext(crl);
551 /* Yet with a CRL_ISSUING_DIST_POINT in the CRL, I still can't get this
552 * to say the CRL is not valid for either cert.
554 crl = CertCreateCRLContext(X509_ASN_ENCODING, v2CRLWithIssuingDistPoint,
555 sizeof(v2CRLWithIssuingDistPoint));
556 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
558 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
559 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
560 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
561 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
563 CertFreeCRLContext(crl);
565 /* And again, with a real CRL, the CRL is valid for both certs. */
566 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
567 sizeof(verisignCRL));
568 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
570 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
571 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
572 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
573 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
575 CertFreeCRLContext(crl);
577 /* One last test: a CRL in a different store than the cert is also valid
578 * for the cert, so CertIsValidCRLForCertificate must always return TRUE?
580 store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
581 CERT_STORE_CREATE_NEW_FLAG, NULL);
582 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
584 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, verisignCRL,
585 sizeof(verisignCRL), CERT_STORE_ADD_ALWAYS, &crl);
586 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
588 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
589 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
590 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
591 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
593 CertFreeCRLContext(crl);
595 CertCloseStore(store, 0);
597 CertFreeCertificateContext(cert2);
598 CertFreeCertificateContext(cert1);
601 static const BYTE crlWithDifferentIssuer[] = {
602 0x30,0x47,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
603 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x41,0x6c,0x65,0x78,0x20,0x4c,0x61,0x6e,
604 0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
605 0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
606 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a };
608 static void testFindCertInCRL(void)
610 BOOL ret;
611 PCCERT_CONTEXT cert;
612 PCCRL_CONTEXT crl;
613 PCRL_ENTRY entry;
615 if (!pCertFindCertificateInCRL)
617 skip("CertFindCertificateInCRL() is not available\n");
618 return;
621 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
622 sizeof(bigCert));
623 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
624 GetLastError());
626 /* Crash
627 ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, NULL);
628 ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, NULL);
629 ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, NULL);
630 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, NULL);
631 ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, &entry);
632 ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, &entry);
633 ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, &entry);
636 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
637 sizeof(verisignCRL));
638 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
639 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
640 ok(entry == NULL, "Expected not to find an entry in CRL\n");
641 CertFreeCRLContext(crl);
643 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
644 sizeof(v1CRLWithIssuerAndEntry));
645 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
646 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
647 ok(entry != NULL, "Expected to find an entry in CRL\n");
648 CertFreeCRLContext(crl);
650 /* Entry found even though CRL issuer doesn't match cert issuer */
651 crl = CertCreateCRLContext(X509_ASN_ENCODING, crlWithDifferentIssuer,
652 sizeof(crlWithDifferentIssuer));
653 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
654 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
655 ok(entry != NULL, "Expected to find an entry in CRL\n");
656 CertFreeCRLContext(crl);
658 CertFreeCertificateContext(cert);
661 static void testVerifyCRLRevocation(void)
663 BOOL ret;
664 PCCERT_CONTEXT cert;
665 PCCRL_CONTEXT crl;
667 ret = CertVerifyCRLRevocation(0, NULL, 0, NULL);
668 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
669 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, NULL, 0, NULL);
670 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
672 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
673 sizeof(bigCert));
675 /* Check against no CRL */
676 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 0, NULL);
677 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
678 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 0, NULL);
679 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
681 /* Check against CRL with entry for the cert */
682 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
683 sizeof(v1CRLWithIssuerAndEntry));
684 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
685 (PCRL_INFO *)&crl->pCrlInfo);
686 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
687 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
688 (PCRL_INFO *)&crl->pCrlInfo);
689 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
690 CertFreeCRLContext(crl);
692 /* Check against CRL with different issuer and entry for the cert */
693 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
694 sizeof(v1CRLWithIssuerAndEntry));
695 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
696 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
697 (PCRL_INFO *)&crl->pCrlInfo);
698 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
699 CertFreeCRLContext(crl);
701 /* Check against CRL without entry for the cert */
702 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
703 sizeof(verisignCRL));
704 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
705 (PCRL_INFO *)&crl->pCrlInfo);
706 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
707 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
708 (PCRL_INFO *)&crl->pCrlInfo);
709 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
710 CertFreeCRLContext(crl);
712 CertFreeCertificateContext(cert);
715 START_TEST(crl)
717 init_function_pointers();
719 testCreateCRL();
720 testAddCRL();
721 testFindCRL();
722 testGetCRLFromStore();
724 testCRLProperties();
726 testIsValidCRLForCert();
727 testFindCertInCRL();
728 testVerifyCRLRevocation();