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