push e8d2f3f1a5d20911a70f6477421a6c3dacf00760
[wine/hacks.git] / dlls / crypt32 / tests / crl.c
blob0bd0e5c13b078fed1c26ae1547642bcb9f105d65
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 * Both tests crash on some win9x boxes.
167 if (0)
169 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
170 sizeof(signedCRL), 0, NULL);
171 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
172 GetLastError() == E_INVALIDARG /* Vista */),
173 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n", GetLastError());
174 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
175 sizeof(signedCRL), 0, NULL);
176 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
177 GetLastError() == E_INVALIDARG /* Vista */),
178 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n", GetLastError());
181 /* Weird--can add a CRL to the NULL store (does this have special meaning?)
183 context = NULL;
184 ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
185 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &context);
186 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
187 if (context)
188 CertFreeCRLContext(context);
190 /* Normal cases: a "signed" CRL is okay.. */
191 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
192 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
193 /* and an unsigned one is too. */
194 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, CRL, sizeof(CRL),
195 CERT_STORE_ADD_ALWAYS, NULL);
196 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
198 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
199 sizeof(newerCRL), CERT_STORE_ADD_NEW, NULL);
200 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
201 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
203 /* This should replace (one of) the existing CRL(s). */
204 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
205 sizeof(newerCRL), CERT_STORE_ADD_NEWER, NULL);
206 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
208 CertCloseStore(store, 0);
211 static void testFindCRL(void)
213 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
214 CERT_STORE_CREATE_NEW_FLAG, NULL);
215 PCCRL_CONTEXT context;
216 PCCERT_CONTEXT cert;
217 BOOL ret;
219 if (!store) return;
220 if (!pCertFindCRLInStore)
222 skip("CertFindCRLInStore() is not available\n");
223 return;
226 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
227 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
228 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
230 /* Crashes
231 context = pCertFindCRLInStore(NULL, 0, 0, 0, NULL, NULL);
234 /* Find any context */
235 context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ANY, NULL, NULL);
236 ok(context != NULL, "Expected a context\n");
237 if (context)
238 CertFreeCRLContext(context);
239 /* Bogus flags are ignored */
240 context = pCertFindCRLInStore(store, 0, 1234, CRL_FIND_ANY, NULL, NULL);
241 ok(context != NULL, "Expected a context\n");
242 if (context)
243 CertFreeCRLContext(context);
244 /* CRL encoding type is ignored too */
245 context = pCertFindCRLInStore(store, 1234, 0, CRL_FIND_ANY, NULL, NULL);
246 ok(context != NULL, "Expected a context\n");
247 if (context)
248 CertFreeCRLContext(context);
250 /* This appears to match any cert */
251 context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, NULL, NULL);
252 ok(context != NULL, "Expected a context\n");
253 if (context)
254 CertFreeCRLContext(context);
256 /* Try to match an issuer that isn't in the store */
257 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
258 sizeof(bigCert2));
259 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
260 GetLastError());
261 context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
262 ok(context == NULL, "Expected no matching context\n");
263 CertFreeCertificateContext(cert);
265 /* Match an issuer that is in the store */
266 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
267 sizeof(bigCert));
268 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
269 GetLastError());
270 context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
271 ok(context != NULL, "Expected a context\n");
272 if (context)
273 CertFreeCRLContext(context);
274 CertFreeCertificateContext(cert);
276 CertCloseStore(store, 0);
279 static void testGetCRLFromStore(void)
281 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
282 CERT_STORE_CREATE_NEW_FLAG, NULL);
283 PCCRL_CONTEXT context;
284 PCCERT_CONTEXT cert;
285 DWORD flags;
286 BOOL ret;
288 if (!store) return;
290 /* Crash
291 context = CertGetCRLFromStore(NULL, NULL, NULL, NULL);
292 context = CertGetCRLFromStore(store, NULL, NULL, NULL);
295 /* Bogus flags */
296 flags = 0xffffffff;
297 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
298 ok(!context && GetLastError() == E_INVALIDARG,
299 "Expected E_INVALIDARG, got %08x\n", GetLastError());
301 /* Test an empty store */
302 flags = 0;
303 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
304 ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
305 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
307 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
308 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
309 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
311 /* NULL matches any CRL */
312 flags = 0;
313 context = CertGetCRLFromStore(store, NULL, NULL, &flags);
314 ok(context != NULL, "Expected a context\n");
315 CertFreeCRLContext(context);
317 /* This cert's issuer isn't in */
318 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
319 sizeof(bigCert2));
320 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
321 GetLastError());
322 context = CertGetCRLFromStore(store, cert, NULL, &flags);
323 ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
324 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
325 CertFreeCertificateContext(cert);
327 /* But this one is */
328 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
329 sizeof(bigCert));
330 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
331 GetLastError());
332 context = CertGetCRLFromStore(store, cert, NULL, &flags);
333 ok(context != NULL, "Expected a context\n");
334 CertFreeCRLContext(context);
335 CertFreeCertificateContext(cert);
337 CertCloseStore(store, 0);
340 static void checkCRLHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
341 PCCRL_CONTEXT context, DWORD propID)
343 BYTE hash[20] = { 0 }, hashProperty[20];
344 BOOL ret;
345 DWORD size;
347 memset(hash, 0, sizeof(hash));
348 memset(hashProperty, 0, sizeof(hashProperty));
349 size = sizeof(hash);
350 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
351 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
352 ret = CertGetCRLContextProperty(context, propID, hashProperty, &size);
353 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
354 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
355 propID);
358 static void testCRLProperties(void)
360 PCCRL_CONTEXT context = CertCreateCRLContext(X509_ASN_ENCODING,
361 CRL, sizeof(CRL));
363 ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
364 if (context)
366 DWORD propID, numProps, access, size;
367 BOOL ret;
368 BYTE hash[20] = { 0 }, hashProperty[20];
369 CRYPT_DATA_BLOB blob;
371 /* This crashes
372 propID = CertEnumCRLContextProperties(NULL, 0);
375 propID = 0;
376 numProps = 0;
377 do {
378 propID = CertEnumCRLContextProperties(context, propID);
379 if (propID)
380 numProps++;
381 } while (propID != 0);
382 ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
384 /* Tests with a NULL cert context. Prop ID 0 fails.. */
385 ret = CertSetCRLContextProperty(NULL, 0, 0, NULL);
386 ok(!ret && GetLastError() == E_INVALIDARG,
387 "Expected E_INVALIDARG, got %08x\n", GetLastError());
388 /* while this just crashes.
389 ret = CertSetCRLContextProperty(NULL, CERT_KEY_PROV_HANDLE_PROP_ID, 0,
390 NULL);
393 ret = CertSetCRLContextProperty(context, 0, 0, NULL);
394 ok(!ret && GetLastError() == E_INVALIDARG,
395 "Expected E_INVALIDARG, got %08x\n", GetLastError());
396 /* Can't set the cert property directly, this crashes.
397 ret = CertSetCRLContextProperty(context, CERT_CRL_PROP_ID, 0, CRL);
400 /* These all crash.
401 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
402 NULL);
403 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID, NULL, NULL);
404 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
405 hashProperty, NULL);
407 /* A missing prop */
408 size = 0;
409 ret = CertGetCRLContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID,
410 NULL, &size);
411 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
412 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
413 /* And, an implicit property */
414 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
415 NULL, &size);
416 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
417 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
418 &access, &size);
419 ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
420 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
421 "Didn't expect a persisted crl\n");
422 /* Trying to set this "read only" property crashes.
423 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
424 ret = CertSetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
425 &access);
428 /* Can I set the hash to an invalid hash? */
429 blob.pbData = hash;
430 blob.cbData = sizeof(hash);
431 ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, &blob);
432 ok(ret, "CertSetCRLContextProperty failed: %08x\n",
433 GetLastError());
434 size = sizeof(hashProperty);
435 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
436 hashProperty, &size);
437 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
438 /* Delete the (bogus) hash, and get the real one */
439 ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, NULL);
440 ok(ret, "CertSetCRLContextProperty failed: %08x\n", GetLastError());
441 checkCRLHash(CRL, sizeof(CRL), CALG_SHA1, context, CERT_HASH_PROP_ID);
443 /* Now that the hash property is set, we should get one property when
444 * enumerating.
446 propID = 0;
447 numProps = 0;
448 do {
449 propID = CertEnumCRLContextProperties(context, propID);
450 if (propID)
451 numProps++;
452 } while (propID != 0);
453 ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
455 /* Check a few other implicit properties */
456 checkCRLHash(CRL, sizeof(CRL), CALG_MD5, context,
457 CERT_MD5_HASH_PROP_ID);
459 CertFreeCRLContext(context);
463 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
464 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
465 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
466 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
467 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
468 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
469 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
470 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
471 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
472 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
473 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
474 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
475 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
476 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
477 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
478 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
479 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
480 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
481 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
482 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
483 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
484 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
485 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
486 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
487 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
488 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
489 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
490 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
491 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
492 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
493 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
494 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
495 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
496 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
497 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
498 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
499 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
500 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
501 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
502 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
503 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
504 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
505 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
506 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
507 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
508 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
509 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
510 0xcd };
512 static void testIsValidCRLForCert(void)
514 BOOL ret;
515 PCCERT_CONTEXT cert1, cert2;
516 PCCRL_CONTEXT crl;
517 HCERTSTORE store;
519 if(!pCertIsValidCRLForCertificate) return;
521 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
522 sizeof(v1CRLWithIssuerAndEntry));
523 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
524 cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
525 sizeof(bigCert));
526 ok(cert1 != NULL, "CertCreateCertificateContext failed: %08x\n",
527 GetLastError());
529 /* Crash
530 ret = CertIsValidCRLForCertificate(NULL, NULL, 0, NULL);
531 ret = CertIsValidCRLForCertificate(cert1, NULL, 0, NULL);
534 /* Curiously, any CRL is valid for the NULL certificate */
535 ret = pCertIsValidCRLForCertificate(NULL, crl, 0, NULL);
536 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
538 /* Same issuer for both cert and CRL, this CRL is valid for that cert */
539 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
540 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
542 cert2 = CertCreateCertificateContext(X509_ASN_ENCODING,
543 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer));
544 ok(cert2 != NULL, "CertCreateCertificateContext failed: %08x\n",
545 GetLastError());
547 /* Yet more curious: different issuers for these, yet the CRL is valid for
548 * that cert. According to MSDN, the relevant bit to check is whether the
549 * CRL has a CRL_ISSUING_DIST_POINT extension.
551 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
552 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
554 CertFreeCRLContext(crl);
556 /* Yet with a CRL_ISSUING_DIST_POINT in the CRL, I still can't get this
557 * to say the CRL is not valid for either cert.
559 crl = CertCreateCRLContext(X509_ASN_ENCODING, v2CRLWithIssuingDistPoint,
560 sizeof(v2CRLWithIssuingDistPoint));
561 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
563 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
564 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
565 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
566 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
568 CertFreeCRLContext(crl);
570 /* And again, with a real CRL, the CRL is valid for both certs. */
571 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
572 sizeof(verisignCRL));
573 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
575 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
576 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
577 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
578 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
580 CertFreeCRLContext(crl);
582 /* One last test: a CRL in a different store than the cert is also valid
583 * for the cert, so CertIsValidCRLForCertificate must always return TRUE?
585 store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
586 CERT_STORE_CREATE_NEW_FLAG, NULL);
587 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
589 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, verisignCRL,
590 sizeof(verisignCRL), CERT_STORE_ADD_ALWAYS, &crl);
591 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
593 ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
594 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
595 ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
596 ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
598 CertFreeCRLContext(crl);
600 CertCloseStore(store, 0);
602 CertFreeCertificateContext(cert2);
603 CertFreeCertificateContext(cert1);
606 static const BYTE crlWithDifferentIssuer[] = {
607 0x30,0x47,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
608 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x41,0x6c,0x65,0x78,0x20,0x4c,0x61,0x6e,
609 0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
610 0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
611 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a };
613 static void testFindCertInCRL(void)
615 BOOL ret;
616 PCCERT_CONTEXT cert;
617 PCCRL_CONTEXT crl;
618 PCRL_ENTRY entry;
620 if (!pCertFindCertificateInCRL)
622 skip("CertFindCertificateInCRL() is not available\n");
623 return;
626 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
627 sizeof(bigCert));
628 ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
629 GetLastError());
631 /* Crash
632 ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, NULL);
633 ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, NULL);
634 ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, NULL);
635 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, NULL);
636 ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, &entry);
637 ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, &entry);
638 ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, &entry);
641 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
642 sizeof(verisignCRL));
643 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
644 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
645 ok(entry == NULL, "Expected not to find an entry in CRL\n");
646 CertFreeCRLContext(crl);
648 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
649 sizeof(v1CRLWithIssuerAndEntry));
650 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
651 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
652 ok(entry != NULL, "Expected to find an entry in CRL\n");
653 CertFreeCRLContext(crl);
655 /* Entry found even though CRL issuer doesn't match cert issuer */
656 crl = CertCreateCRLContext(X509_ASN_ENCODING, crlWithDifferentIssuer,
657 sizeof(crlWithDifferentIssuer));
658 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
659 ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
660 ok(entry != NULL, "Expected to find an entry in CRL\n");
661 CertFreeCRLContext(crl);
663 CertFreeCertificateContext(cert);
666 static void testVerifyCRLRevocation(void)
668 BOOL ret;
669 PCCERT_CONTEXT cert;
670 PCCRL_CONTEXT crl;
672 ret = CertVerifyCRLRevocation(0, NULL, 0, NULL);
673 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
674 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, NULL, 0, NULL);
675 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
677 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
678 sizeof(bigCert));
680 /* Check against no CRL */
681 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 0, NULL);
682 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
683 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 0, NULL);
684 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
686 /* Check against CRL with entry for the cert */
687 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
688 sizeof(v1CRLWithIssuerAndEntry));
689 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
690 (PCRL_INFO *)&crl->pCrlInfo);
691 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
692 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
693 (PCRL_INFO *)&crl->pCrlInfo);
694 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
695 CertFreeCRLContext(crl);
697 /* Check against CRL with different issuer and entry for the cert */
698 crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
699 sizeof(v1CRLWithIssuerAndEntry));
700 ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
701 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
702 (PCRL_INFO *)&crl->pCrlInfo);
703 ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
704 CertFreeCRLContext(crl);
706 /* Check against CRL without entry for the cert */
707 crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
708 sizeof(verisignCRL));
709 ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
710 (PCRL_INFO *)&crl->pCrlInfo);
711 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
712 ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
713 (PCRL_INFO *)&crl->pCrlInfo);
714 ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
715 CertFreeCRLContext(crl);
717 CertFreeCertificateContext(cert);
720 START_TEST(crl)
722 init_function_pointers();
724 testCreateCRL();
725 testAddCRL();
726 testFindCRL();
727 testGetCRLFromStore();
729 testCRLProperties();
731 testIsValidCRLForCert();
732 testFindCertInCRL();
733 testVerifyCRLRevocation();