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