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