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