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 <stdio.h>
22 #include <stdarg.h>
23 
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     ok(!context, "Expected failure\n");
106     context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
107      sizeof(signedCRL) - 1);
108     ok(!context, "Expected failure\n");
109     context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL,
110      sizeof(signedCRL));
111     ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
112     if (context)
113         CertFreeCRLContext(context);
114     context = CertCreateCRLContext(X509_ASN_ENCODING, CRL, sizeof(CRL));
115     ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
116     if (context)
117         CertFreeCRLContext(context);
118 }
119 
120 static void testDupCRL(void)
121 {
122     PCCRL_CONTEXT context, dupContext;
123     BOOL res;
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 
133     res = CertFreeCRLContext(dupContext);
134     ok(res, "CertFreeCRLContext failed\n");
135 
136     res = CertFreeCRLContext(context);
137     ok(res, "CertFreeCRLContext failed\n");
138 
139     res = CertFreeCRLContext(NULL);
140     ok(res, "CertFreeCRLContext failed\n");
141 }
142 
143 static void testAddCRL(void)
144 {
145     HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
146      CERT_STORE_CREATE_NEW_FLAG, NULL);
147     PCCRL_CONTEXT context, context2;
148     BOOL ret;
149     DWORD GLE;
150 
151     ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
152     if (!store) return;
153 
154     /* Bad CRL encoding type */
155     ret = CertAddEncodedCRLToStore(0, 0, NULL, 0, 0, NULL);
156     ok(!ret && GetLastError() == E_INVALIDARG,
157      "Expected E_INVALIDARG, got %08x\n", GetLastError());
158     ret = CertAddEncodedCRLToStore(store, 0, NULL, 0, 0, NULL);
159     ok(!ret && GetLastError() == E_INVALIDARG,
160      "Expected E_INVALIDARG, got %08x\n", GetLastError());
161     ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL), 0, NULL);
162     ok(!ret && GetLastError() == E_INVALIDARG,
163      "Expected E_INVALIDARG, got %08x\n", GetLastError());
164     ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL), 0,
165      NULL);
166     ok(!ret && GetLastError() == E_INVALIDARG,
167      "Expected E_INVALIDARG, got %08x\n", GetLastError());
168     ret = CertAddEncodedCRLToStore(0, 0, signedCRL, sizeof(signedCRL),
169      CERT_STORE_ADD_ALWAYS, NULL);
170     ok(!ret && GetLastError() == E_INVALIDARG,
171      "Expected E_INVALIDARG, got %08x\n", GetLastError());
172     ret = CertAddEncodedCRLToStore(store, 0, signedCRL, sizeof(signedCRL),
173      CERT_STORE_ADD_ALWAYS, NULL);
174     ok(!ret && GetLastError() == E_INVALIDARG,
175      "Expected E_INVALIDARG, got %08x\n", GetLastError());
176 
177     /* No CRL */
178     ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, NULL, 0, 0, NULL);
179     GLE = GetLastError();
180     ok(!ret && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
181      "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
182     ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, NULL, 0, 0, NULL);
183     GLE = GetLastError();
184     ok(!ret && (GLE == CRYPT_E_ASN1_EOD || GLE == OSS_MORE_INPUT),
185      "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE);
186 
187     /* Weird--bad add disposition leads to an access violation in Windows.
188      * Both tests crash on some win9x boxes.
189      */
190     if (0)
191     {
192         ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
193          sizeof(signedCRL), 0, NULL);
194         ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
195                     GetLastError() == E_INVALIDARG /* Vista */),
196          "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n", GetLastError());
197         ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
198          sizeof(signedCRL), 0, NULL);
199         ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
200                     GetLastError() == E_INVALIDARG /* Vista */),
201          "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n", GetLastError());
202     }
203 
204     /* Weird--can add a CRL to the NULL store (does this have special meaning?)
205      */
206     context = NULL;
207     ret = CertAddEncodedCRLToStore(0, X509_ASN_ENCODING, signedCRL,
208      sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &context);
209     ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
210     if (context)
211         CertFreeCRLContext(context);
212 
213     /* Normal cases: a "signed" CRL is okay.. */
214     ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
215      sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
216     ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
217     /* and an unsigned one is too. */
218     ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, CRL, sizeof(CRL),
219      CERT_STORE_ADD_ALWAYS, NULL);
220     ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
221 
222     ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
223      sizeof(newerCRL), CERT_STORE_ADD_NEW, NULL);
224     ok(!ret && GetLastError() == CRYPT_E_EXISTS,
225      "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
226 
227     /* This should replace (one of) the existing CRL(s). */
228     ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, newerCRL,
229      sizeof(newerCRL), CERT_STORE_ADD_NEWER, NULL);
230     ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
231 
232     CertCloseStore(store, 0);
233 
234     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
235     ok(store != NULL, "CertOpenStore failed\n");
236 
237     context = CertCreateCRLContext(X509_ASN_ENCODING, CRL, sizeof(CRL));
238     ok(context != NULL, "CertCreateCRLContext failed\n");
239 
240     ret = CertAddCRLContextToStore(store, context, CERT_STORE_ADD_NEW, &context2);
241     ok(ret, "CertAddCRLContextToStore failed\n");
242     ok(context2 != NULL && context2 != context, "unexpected context2\n");
243 
244     ok(context->pbCrlEncoded != context2->pbCrlEncoded, "Unexpected pbCrlEncoded\n");
245     ok(context->cbCrlEncoded == context2->cbCrlEncoded, "Unexpected cbCrlEncoded\n");
246     ok(context->pCrlInfo != context2->pCrlInfo, "Unexpected pCrlInfo\n");
247 
248     CertFreeCRLContext(context2);
249     CertFreeCRLContext(context);
250     CertCloseStore(store, 0);
251 }
252 
253 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
254  0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
255  0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
256  0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
257  0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
258  0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
259 static const BYTE v2CRLWithIssuingDistPoint[] = {
260 0x30,0x70,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
261 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
262 0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
263 0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
264 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x27,
265 0x30,0x25,0x30,0x23,0x06,0x03,0x55,0x1d,0x1c,0x01,0x01,0xff,0x04,0x19,0x30,
266 0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
267 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
268 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
269  0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
270  0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
271  0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
272  0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
273  0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
274  0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
275  0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
276  0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
277  0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
278  0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
279  0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
280  0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
281  0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
282  0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
283  0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
284  0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
285  0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
286  0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
287  0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
288  0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
289  0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
290  0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
291  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
292  0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
293  0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
294  0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
295  0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
296  0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
297  0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
298  0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
299  0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
300  0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
301  0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
302  0xcd };
303 static const BYTE verisignCommercialSoftPubCA[] = {
304 0x30,0x82,0x02,0x40,0x30,0x82,0x01,0xa9,0x02,0x10,0x03,0xc7,0x8f,0x37,0xdb,0x92,
305 0x28,0xdf,0x3c,0xbb,0x1a,0xad,0x82,0xfa,0x67,0x10,0x30,0x0d,0x06,0x09,0x2a,0x86,
306 0x48,0x86,0xf7,0x0d,0x01,0x01,0x02,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
307 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,0x17,
308 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
309 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,0x55,0x04,0x0b,
310 0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6f,0x6d,0x6d,0x65,
311 0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x50,
312 0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,
313 0x39,0x36,0x30,0x34,0x30,0x39,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,
314 0x34,0x30,0x31,0x30,0x37,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x61,0x31,0x11,
315 0x30,0x0f,0x06,0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,
316 0x74,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,
317 0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
318 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6f,
319 0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,
320 0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,0x43,0x41,0x30,
321 0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
322 0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xc3,0xd3,0x69,0x65,
323 0x52,0x01,0x94,0x54,0xab,0x28,0xc6,0x62,0x18,0xb3,0x54,0x55,0xc5,0x44,0x87,0x45,
324 0x4a,0x3b,0xc2,0x7e,0xd8,0xd3,0xd7,0xc8,0x80,0x86,0x8d,0xd8,0x0c,0xf1,0x16,0x9c,
325 0xcc,0x6b,0xa9,0x29,0xb2,0x8f,0x76,0x73,0x92,0xc8,0xc5,0x62,0xa6,0x3c,0xed,0x1e,
326 0x05,0x75,0xf0,0x13,0x00,0x6c,0x14,0x4d,0xd4,0x98,0x90,0x07,0xbe,0x69,0x73,0x81,
327 0xb8,0x62,0x4e,0x31,0x1e,0xd1,0xfc,0xc9,0x0c,0xeb,0x7d,0x90,0xbf,0xae,0xb4,0x47,
328 0x51,0xec,0x6f,0xce,0x64,0x35,0x02,0xd6,0x7d,0x67,0x05,0x77,0xe2,0x8f,0xd9,0x51,
329 0xd7,0xfb,0x97,0x19,0xbc,0x3e,0xd7,0x77,0x81,0xc6,0x43,0xdd,0xf2,0xdd,0xdf,0xca,
330 0xa3,0x83,0x8b,0xcb,0x41,0xc1,0x3d,0x22,0x48,0x48,0xa6,0x19,0x02,0x03,0x01,0x00,
331 0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x02,0x05,0x00,
332 0x03,0x81,0x81,0x00,0xb5,0xbc,0xb0,0x75,0x6a,0x89,0xa2,0x86,0xbd,0x64,0x78,0xc3,
333 0xa7,0x32,0x75,0x72,0x11,0xaa,0x26,0x02,0x17,0x60,0x30,0x4c,0xe3,0x48,0x34,0x19,
334 0xb9,0x52,0x4a,0x51,0x18,0x80,0xfe,0x53,0x2d,0x7b,0xd5,0x31,0x8c,0xc5,0x65,0x99,
335 0x41,0x41,0x2f,0xf2,0xae,0x63,0x7a,0xe8,0x73,0x99,0x15,0x90,0x1a,0x1f,0x7a,0x8b,
336 0x41,0xd0,0x8e,0x3a,0xd0,0xcd,0x38,0x34,0x44,0xd0,0x75,0xf8,0xea,0x71,0xc4,0x81,
337 0x19,0x38,0x17,0x35,0x4a,0xae,0xc5,0x3e,0x32,0xe6,0x21,0xb8,0x05,0xc0,0x93,0xe1,
338 0xc7,0x38,0x5c,0xd8,0xf7,0x93,0x38,0x64,0x90,0xed,0x54,0xce,0xca,0xd3,0xd3,0xd0,
339 0x5f,0xef,0x04,0x9b,0xde,0x02,0x82,0xdd,0x88,0x29,0xb1,0xc3,0x4f,0xa5,0xcd,0x71,
340 0x64,0x31,0x3c,0x3c
341 };
342 static const BYTE rootWithKeySignAndCRLSign[] = {
343 0x30,0x82,0x01,0xdf,0x30,0x82,0x01,0x4c,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
344 0x5b,0xc7,0x0b,0x27,0x99,0xbb,0x2e,0x99,0x47,0x9d,0x45,0x4e,0x7c,0x1a,0xca,
345 0xe8,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
346 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
347 0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
348 0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
349 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
350 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
351 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
352 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
353 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
354 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
355 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
356 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
357 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
358 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
359 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
360 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
361 0x00,0x01,0xa3,0x42,0x30,0x40,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,
362 0xff,0x04,0x04,0x03,0x02,0x00,0x06,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,
363 0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1d,0x06,0x03,0x55,0x1d,
364 0x0e,0x04,0x16,0x04,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,0x28,0x89,0xa0,
365 0x58,0xff,0x98,0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x09,0x06,0x05,0x2b,
366 0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,0x81,0x00,0x74,0xcb,0x21,0xfd,0x2d,
367 0x25,0xdc,0xa5,0xaa,0xa1,0x26,0xdc,0x8b,0x40,0x11,0x64,0xae,0x5c,0x71,0x3c,
368 0x28,0xbc,0xf9,0xb3,0xcb,0xa5,0x94,0xb2,0x8d,0x4c,0x23,0x2b,0x9b,0xde,0x2c,
369 0x4c,0x30,0x04,0xc6,0x88,0x10,0x2f,0x53,0xfd,0x6c,0x82,0xf1,0x13,0xfb,0xda,
370 0x27,0x75,0x25,0x48,0xe4,0x72,0x09,0x2a,0xee,0xb4,0x1e,0xc9,0x55,0xf5,0xf7,
371 0x82,0x91,0xd8,0x4b,0xe4,0x3a,0xfe,0x97,0x87,0xdf,0xfb,0x15,0x5a,0x12,0x3e,
372 0x12,0xe6,0xad,0x40,0x0b,0xcf,0xee,0x1a,0x44,0xe0,0x83,0xb2,0x67,0x94,0xd4,
373 0x2e,0x7c,0xf2,0x06,0x9d,0xb3,0x3b,0x7e,0x2f,0xda,0x25,0x66,0x7e,0xa7,0x1f,
374 0x45,0xd4,0xf5,0xe3,0xdf,0x2a,0xf1,0x18,0x28,0x20,0xb5,0xf8,0xf5,0x8d,0x7a,
375 0x2e,0x84,0xee };
376 static const BYTE eeCert[] = {
377 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
378 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,
379 0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,
380 0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30,0x30,
381 0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30,0x30,
382 0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,
383 0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,
384 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,
385 0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,
386 0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,
387 0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,
388 0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,
389 0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,
390 0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,
391 0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,
392 0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,
393 0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,
394 0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
395 0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x22,0xf1,0x66,0x00,0x79,0xd2,
396 0xe6,0xb2,0xb2,0xf7,0x2f,0x98,0x92,0x7d,0x73,0xc3,0x6c,0x5c,0x77,0x20,0xe3,
397 0xbf,0x3e,0xe0,0xb3,0x5c,0x68,0xb4,0x9b,0x3a,0x41,0xae,0x94,0xa0,0x80,0x3a,
398 0xfe,0x5d,0x7a,0x56,0x87,0x85,0x44,0x45,0xcf,0xa6,0xd3,0x10,0xe7,0x73,0x41,
399 0xf2,0x7f,0x88,0x85,0x91,0x8e,0xe6,0xec,0xe2,0xce,0x08,0xbc,0xa5,0x76,0xe5,
400 0x4d,0x1d,0xb7,0x70,0x31,0xdd,0xc9,0x9a,0x15,0x32,0x11,0x5a,0x4e,0x62,0xc8,
401 0xd1,0xf8,0xec,0x46,0x39,0x5b,0xe7,0x67,0x1f,0x58,0xe8,0xa1,0xa0,0x5b,0xf7,
402 0x8a,0x6d,0x5f,0x91,0x18,0xd4,0x90,0x85,0xff,0x30,0xc7,0xca,0x9c,0xc6,0x92,
403 0xb0,0xca,0x16,0xc4,0xa4,0xc0,0xd6,0xe8,0xff,0x15,0x19,0xd1,0x30,0x61,0xf3,
404 0xef,0x9f };
405 static const BYTE rootSignedCRL[] = {
406 0x30,0x82,0x01,0x1d,0x30,0x81,0x87,0x02,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a,
407 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x10,0x31,0x0e,0x30,
408 0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x17,0x0d,
409 0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
410 0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x14,
411 0x30,0x12,0x02,0x01,0x01,0x17,0x0d,0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30,
412 0x30,0x30,0x30,0x30,0x5a,0xa0,0x2d,0x30,0x2b,0x30,0x0a,0x06,0x03,0x55,0x1d,
413 0x14,0x04,0x03,0x02,0x01,0x01,0x30,0x1d,0x06,0x03,0x55,0x1d,0x23,0x04,0x16,
414 0x04,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,0x28,0x89,0xa0,0x58,0xff,0x98,
415 0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
416 0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9b,0x2b,0x99,0x0d,
417 0x16,0x83,0x93,0x54,0x29,0x3a,0xa6,0x53,0x5d,0xf8,0xa6,0x73,0x9f,0x2a,0x45,
418 0x39,0x91,0xff,0x91,0x1c,0x27,0x06,0xe8,0xdb,0x72,0x3f,0x66,0x89,0x15,0x68,
419 0x55,0xd5,0x49,0x63,0xa6,0x00,0xe9,0x66,0x9c,0x97,0xf9,0xb3,0xb3,0x2b,0x1b,
420 0xc7,0x79,0x46,0xa8,0xd8,0x2b,0x78,0x27,0xa0,0x70,0x02,0x81,0xc6,0x40,0xb3,
421 0x76,0x32,0x65,0x4c,0xf8,0xff,0x1d,0x41,0x6e,0x16,0x09,0xa2,0x8a,0x7b,0x0c,
422 0xd0,0xa6,0x9b,0x61,0xa3,0x7c,0x02,0x91,0x79,0xdf,0x6a,0x5e,0x88,0x95,0x66,
423 0x33,0x17,0xcb,0x5a,0xd2,0xdc,0x89,0x05,0x62,0x97,0x60,0x73,0x7b,0x2c,0x1a,
424 0x90,0x20,0x73,0x24,0x9f,0x45,0x22,0x4b,0xc1,0x33,0xd1,0xda,0xd8,0x7e,0x1b,
425 0x3d,0x74,0xd6,0x3b };
426 
427 static void testFindCRL(void)
428 {
429     HCERTSTORE store;
430     PCCRL_CONTEXT context;
431     PCCERT_CONTEXT cert, endCert, rootCert;
432     CRL_FIND_ISSUED_FOR_PARA issuedForPara = { NULL, NULL };
433     DWORD count, revoked_count;
434     BOOL ret;
435 
436     if (!pCertFindCRLInStore || !pCertFindCertificateInCRL)
437     {
438         win_skip("CertFindCRLInStore or CertFindCertificateInCRL not available\n");
439         return;
440     }
441 
442     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
443                           CERT_STORE_CREATE_NEW_FLAG, NULL);
444     ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
445     if (!store) return;
446 
447     ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
448      sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
449     ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
450 
451     /* Crashes
452     context = pCertFindCRLInStore(NULL, 0, 0, 0, NULL, NULL);
453      */
454 
455     /* Find any context */
456     context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ANY, NULL, NULL);
457     ok(context != NULL, "Expected a context\n");
458     if (context)
459         CertFreeCRLContext(context);
460     /* Bogus flags are ignored */
461     context = pCertFindCRLInStore(store, 0, 1234, CRL_FIND_ANY, NULL, NULL);
462     ok(context != NULL, "Expected a context\n");
463     if (context)
464         CertFreeCRLContext(context);
465     /* CRL encoding type is ignored too */
466     context = pCertFindCRLInStore(store, 1234, 0, CRL_FIND_ANY, NULL, NULL);
467     ok(context != NULL, "Expected a context\n");
468     if (context)
469         CertFreeCRLContext(context);
470 
471     /* This appears to match any cert */
472     context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, NULL, NULL);
473     ok(context != NULL, "Expected a context\n");
474     if (context)
475         CertFreeCRLContext(context);
476 
477     /* Try to match an issuer that isn't in the store */
478     cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
479      sizeof(bigCert2));
480     ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
481      GetLastError());
482     context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
483     ok(context == NULL, "Expected no matching context\n");
484     CertFreeCertificateContext(cert);
485 
486     /* Match an issuer that is in the store */
487     cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
488      sizeof(bigCert));
489     ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
490      GetLastError());
491     context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY, cert, NULL);
492     ok(context != NULL, "Expected a context\n");
493     if (context)
494         CertFreeCRLContext(context);
495 
496     /* Try various find flags */
497     context = pCertFindCRLInStore(store, 0, CRL_FIND_ISSUED_BY_SIGNATURE_FLAG,
498      CRL_FIND_ISSUED_BY, cert, NULL);
499     ok(!context || broken(context != NULL /* Win9x */), "unexpected context\n");
500     /* The CRL doesn't have an AKI extension, so it matches any cert */
501     context = pCertFindCRLInStore(store, 0, CRL_FIND_ISSUED_BY_AKI_FLAG,
502      CRL_FIND_ISSUED_BY, cert, NULL);
503     ok(context != NULL, "Expected a context\n");
504     if (context)
505         CertFreeCRLContext(context);
506 
507     if (0)
508     {
509         /* Crash or return NULL/STATUS_ACCESS_VIOLATION */
510         pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR, NULL,
511          NULL);
512         pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR,
513          &issuedForPara, NULL);
514     }
515     /* Test whether the cert matches the CRL in the store */
516     issuedForPara.pSubjectCert = cert;
517     issuedForPara.pIssuerCert = cert;
518     context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR,
519      &issuedForPara, NULL);
520     ok(context != NULL || broken(!context /* Win9x, NT4 */),
521      "Expected a context\n");
522     if (context)
523     {
524         ok(context->cbCrlEncoded == sizeof(signedCRL),
525          "unexpected CRL size %d\n", context->cbCrlEncoded);
526         ok(!memcmp(context->pbCrlEncoded, signedCRL, context->cbCrlEncoded),
527          "unexpected CRL data\n");
528         CertFreeCRLContext(context);
529     }
530 
531     ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING,
532      v1CRLWithIssuerAndEntry, sizeof(v1CRLWithIssuerAndEntry),
533      CERT_STORE_ADD_ALWAYS, NULL);
534     ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
535     ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING,
536      v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
537      CERT_STORE_ADD_ALWAYS, NULL);
538     ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
539     ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING,
540      verisignCRL, sizeof(verisignCRL), CERT_STORE_ADD_ALWAYS, NULL);
541     ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
542     issuedForPara.pSubjectCert = cert;
543     issuedForPara.pIssuerCert = cert;
544     context = NULL;
545     count = revoked_count = 0;
546     do {
547         context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR,
548          &issuedForPara, context);
549         if (context)
550         {
551             PCRL_ENTRY entry;
552 
553             count++;
554             if (pCertFindCertificateInCRL(cert, context, 0, NULL, &entry) &&
555              entry)
556                 revoked_count++;
557         }
558     } while (context);
559     /* signedCRL, v1CRLWithIssuerAndEntry, and v2CRLWithIssuingDistPoint all
560      * match cert's issuer, but verisignCRL does not, so the expected count
561      * is 0.
562      */
563     ok(count == 3 || broken(count == 0 /* NT4, Win9x */),
564      "expected 3 matching CRLs, got %d\n", count);
565     /* Only v1CRLWithIssuerAndEntry and v2CRLWithIssuingDistPoint contain
566      * entries, so the count of CRL entries that match cert is 2.
567      */
568     ok(revoked_count == 2 || broken(revoked_count == 0 /* NT4, Win9x */),
569      "expected 2 matching CRL entries, got %d\n", revoked_count);
570 
571     CertFreeCertificateContext(cert);
572 
573     /* Try again with a cert that doesn't match any CRLs in the store */
574     cert = CertCreateCertificateContext(X509_ASN_ENCODING,
575      bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer));
576     ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
577      GetLastError());
578     issuedForPara.pSubjectCert = cert;
579     issuedForPara.pIssuerCert = cert;
580     context = NULL;
581     count = revoked_count = 0;
582     do {
583         context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR,
584          &issuedForPara, context);
585         if (context)
586         {
587             PCRL_ENTRY entry;
588 
589             count++;
590             if (pCertFindCertificateInCRL(cert, context, 0, NULL, &entry) &&
591              entry)
592                 revoked_count++;
593         }
594     } while (context);
595     ok(count == 0, "expected 0 matching CRLs, got %d\n", count);
596     ok(revoked_count == 0, "expected 0 matching CRL entries, got %d\n",
597      revoked_count);
598     CertFreeCertificateContext(cert);
599 
600     /* Test again with a real certificate and CRL.  The certificate wasn't
601      * revoked, but its issuer does have a CRL.
602      */
603     cert = CertCreateCertificateContext(X509_ASN_ENCODING,
604      verisignCommercialSoftPubCA, sizeof(verisignCommercialSoftPubCA));
605     ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
606      GetLastError());
607     issuedForPara.pIssuerCert = cert;
608     issuedForPara.pSubjectCert = cert;
609     context = NULL;
610     count = revoked_count = 0;
611     do {
612         context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR,
613          &issuedForPara, context);
614         if (context)
615         {
616             PCRL_ENTRY entry;
617 
618             count++;
619             if (pCertFindCertificateInCRL(cert, context, 0, NULL, &entry) &&
620              entry)
621                 revoked_count++;
622         }
623     } while (context);
624     ok(count == 1 || broken(count == 0 /* Win9x, NT4 */),
625      "expected 1 matching CRLs, got %d\n", count);
626     ok(revoked_count == 0, "expected 0 matching CRL entries, got %d\n",
627      revoked_count);
628     CertFreeCertificateContext(cert);
629 
630     CertCloseStore(store, 0);
631 
632     /* This test uses a synthesized chain (rootWithKeySignAndCRLSign ->
633      * eeCert) whose end certificate is in the CRL.
634      */
635     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
636      CERT_STORE_CREATE_NEW_FLAG, NULL);
637     /* Add a CRL for the end certificate */
638     CertAddEncodedCRLToStore(store, X509_ASN_ENCODING,
639      rootSignedCRL, sizeof(rootSignedCRL), CERT_STORE_ADD_ALWAYS, NULL);
640     /* Add another CRL unrelated to the tested chain */
641     CertAddEncodedCRLToStore(store, X509_ASN_ENCODING,
642      verisignCRL, sizeof(verisignCRL), CERT_STORE_ADD_ALWAYS, NULL);
643     endCert = CertCreateCertificateContext(X509_ASN_ENCODING,
644      eeCert, sizeof(eeCert));
645     rootCert = CertCreateCertificateContext(X509_ASN_ENCODING,
646      rootWithKeySignAndCRLSign, sizeof(rootWithKeySignAndCRLSign));
647     issuedForPara.pSubjectCert = endCert;
648     issuedForPara.pIssuerCert = rootCert;
649     context = NULL;
650     count = revoked_count = 0;
651     do {
652         context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_FOR,
653          &issuedForPara, context);
654         if (context)
655         {
656             PCRL_ENTRY entry;
657 
658             count++;
659             if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) &&
660              entry)
661                 revoked_count++;
662         }
663     } while (context);
664     ok(count == 1 || broken(count == 0 /* Win9x, NT4 */),
665      "expected 1 matching CRLs, got %d\n", count);
666     ok(revoked_count == 1 || broken(revoked_count == 0 /* Win9x, NT4 */),
667      "expected 1 matching CRL entries, got %d\n", revoked_count);
668 
669     /* Test CRL_FIND_ISSUED_BY flags */
670     count = revoked_count = 0;
671     do {
672         context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY,
673          endCert, context);
674         if (context)
675         {
676             PCRL_ENTRY entry;
677 
678             count++;
679             if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) &&
680              entry)
681                 revoked_count++;
682         }
683     } while (context);
684     ok(count == 0, "expected 0 matching CRLs, got %d\n", count);
685     ok(revoked_count == 0, "expected 0 matching CRL entries, got %d\n",
686      revoked_count);
687     count = revoked_count = 0;
688     do {
689         context = pCertFindCRLInStore(store, 0, 0, CRL_FIND_ISSUED_BY,
690          rootCert, context);
691         if (context)
692         {
693             PCRL_ENTRY entry;
694 
695             count++;
696             if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) &&
697              entry)
698                 revoked_count++;
699         }
700     } while (context);
701     ok(count == 1, "expected 1 matching CRLs, got %d\n", count);
702     ok(revoked_count == 1, "expected 1 matching CRL entries, got %d\n",
703      revoked_count);
704     count = revoked_count = 0;
705     do {
706         context = pCertFindCRLInStore(store, 0, CRL_FIND_ISSUED_BY_AKI_FLAG,
707          CRL_FIND_ISSUED_BY, endCert, context);
708         if (context)
709         {
710             PCRL_ENTRY entry;
711 
712             count++;
713             if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) &&
714              entry)
715                 revoked_count++;
716         }
717     } while (context);
718     ok(count == 0, "expected 0 matching CRLs, got %d\n", count);
719     ok(revoked_count == 0, "expected 0 matching CRL entries, got %d\n",
720      revoked_count);
721     count = revoked_count = 0;
722     do {
723         context = pCertFindCRLInStore(store, 0, CRL_FIND_ISSUED_BY_AKI_FLAG,
724          CRL_FIND_ISSUED_BY, rootCert, context);
725         if (context)
726         {
727             PCRL_ENTRY entry;
728 
729             count++;
730             if (pCertFindCertificateInCRL(rootCert, context, 0, NULL, &entry) &&
731              entry)
732                 revoked_count++;
733         }
734     } while (context);
735     ok(count == 0 || broken(count == 1 /* Win9x */),
736      "expected 0 matching CRLs, got %d\n", count);
737     ok(revoked_count == 0, "expected 0 matching CRL entries, got %d\n",
738      revoked_count);
739     count = revoked_count = 0;
740     do {
741         context = pCertFindCRLInStore(store, 0,
742          CRL_FIND_ISSUED_BY_SIGNATURE_FLAG, CRL_FIND_ISSUED_BY, endCert,
743          context);
744         if (context)
745         {
746             PCRL_ENTRY entry;
747 
748             count++;
749             if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) &&
750              entry)
751                 revoked_count++;
752         }
753     } while (context);
754     ok(count == 0, "expected 0 matching CRLs, got %d\n", count);
755     ok(revoked_count == 0, "expected 0 matching CRL entries, got %d\n",
756      revoked_count);
757     count = revoked_count = 0;
758     do {
759         context = pCertFindCRLInStore(store, 0,
760          CRL_FIND_ISSUED_BY_SIGNATURE_FLAG, CRL_FIND_ISSUED_BY, rootCert,
761          context);
762         if (context)
763         {
764             PCRL_ENTRY entry;
765 
766             count++;
767             if (pCertFindCertificateInCRL(endCert, context, 0, NULL, &entry) &&
768              entry)
769                 revoked_count++;
770         }
771     } while (context);
772     ok(count == 1, "expected 1 matching CRLs, got %d\n", count);
773     ok(revoked_count == 1, "expected 1 matching CRL entries, got %d\n",
774      revoked_count);
775     CertFreeCertificateContext(rootCert);
776     CertFreeCertificateContext(endCert);
777 
778     CertCloseStore(store, 0);
779 }
780 
781 static void testGetCRLFromStore(void)
782 {
783     HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
784      CERT_STORE_CREATE_NEW_FLAG, NULL);
785     PCCRL_CONTEXT context;
786     PCCERT_CONTEXT cert;
787     DWORD flags;
788     BOOL ret;
789 
790     ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
791     if (!store) return;
792 
793     /* Crash
794     context = CertGetCRLFromStore(NULL, NULL, NULL, NULL);
795     context = CertGetCRLFromStore(store, NULL, NULL, NULL);
796      */
797 
798     /* Bogus flags */
799     flags = 0xffffffff;
800     context = CertGetCRLFromStore(store, NULL, NULL, &flags);
801     ok(!context && GetLastError() == E_INVALIDARG,
802      "Expected E_INVALIDARG, got %08x\n", GetLastError());
803 
804     /* Test an empty store */
805     flags = 0;
806     context = CertGetCRLFromStore(store, NULL, NULL, &flags);
807     ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
808      "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
809 
810     ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
811      sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
812     ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
813 
814     /* NULL matches any CRL */
815     flags = 0;
816     context = CertGetCRLFromStore(store, NULL, NULL, &flags);
817     ok(context != NULL, "Expected a context\n");
818     CertFreeCRLContext(context);
819 
820     /* This cert's issuer isn't in */
821     cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
822      sizeof(bigCert2));
823     ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
824      GetLastError());
825     context = CertGetCRLFromStore(store, cert, NULL, &flags);
826     ok(context == NULL && GetLastError() == CRYPT_E_NOT_FOUND,
827      "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
828     CertFreeCertificateContext(cert);
829 
830     /* But this one is */
831     cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
832      sizeof(bigCert));
833     ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
834      GetLastError());
835     context = CertGetCRLFromStore(store, cert, NULL, &flags);
836     ok(context != NULL, "Expected a context\n");
837     CertFreeCRLContext(context);
838     CertFreeCertificateContext(cert);
839 
840     CertCloseStore(store, 0);
841 }
842 
843 static void checkCRLHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
844  PCCRL_CONTEXT context, DWORD propID)
845 {
846     BYTE hash[20] = { 0 }, hashProperty[20];
847     BOOL ret;
848     DWORD size;
849 
850     memset(hash, 0, sizeof(hash));
851     memset(hashProperty, 0, sizeof(hashProperty));
852     size = sizeof(hash);
853     ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
854     ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
855     ret = CertGetCRLContextProperty(context, propID, hashProperty, &size);
856     ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
857     ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
858      propID);
859 }
860 
861 static void testCRLProperties(void)
862 {
863     PCCRL_CONTEXT context = CertCreateCRLContext(X509_ASN_ENCODING,
864      CRL, sizeof(CRL));
865 
866     ok(context != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
867     if (context)
868     {
869         DWORD propID, numProps, access, size;
870         BOOL ret;
871         BYTE hash[20] = { 0 }, hashProperty[20];
872         CRYPT_DATA_BLOB blob;
873 
874         /* This crashes
875         propID = CertEnumCRLContextProperties(NULL, 0);
876          */
877 
878         propID = 0;
879         numProps = 0;
880         do {
881             propID = CertEnumCRLContextProperties(context, propID);
882             if (propID)
883                 numProps++;
884         } while (propID != 0);
885         ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
886 
887         /* Tests with a NULL cert context.  Prop ID 0 fails.. */
888         ret = CertSetCRLContextProperty(NULL, 0, 0, NULL);
889         ok(!ret && GetLastError() == E_INVALIDARG,
890          "Expected E_INVALIDARG, got %08x\n", GetLastError());
891         /* while this just crashes.
892         ret = CertSetCRLContextProperty(NULL, CERT_KEY_PROV_HANDLE_PROP_ID, 0,
893          NULL);
894          */
895 
896         ret = CertSetCRLContextProperty(context, 0, 0, NULL);
897         ok(!ret && GetLastError() == E_INVALIDARG,
898          "Expected E_INVALIDARG, got %08x\n", GetLastError());
899         /* Can't set the cert property directly, this crashes.
900         ret = CertSetCRLContextProperty(context, CERT_CRL_PROP_ID, 0, CRL);
901          */
902 
903         /* These all crash.
904         ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
905          NULL);
906         ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID, NULL, NULL);
907         ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
908          hashProperty, NULL);
909          */
910         /* A missing prop */
911         size = 0;
912         ret = CertGetCRLContextProperty(context, CERT_KEY_PROV_INFO_PROP_ID,
913          NULL, &size);
914         ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
915          "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
916         /* And, an implicit property */
917         ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
918          NULL, &size);
919         ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
920         ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID,
921          &access, &size);
922         ok(ret, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
923         ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
924          "Didn't expect a persisted crl\n");
925         /* Trying to set this "read only" property crashes.
926         access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
927         ret = CertSetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
928          &access);
929          */
930 
931         /* Can I set the hash to an invalid hash? */
932         blob.pbData = hash;
933         blob.cbData = sizeof(hash);
934         ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, &blob);
935         ok(ret, "CertSetCRLContextProperty failed: %08x\n",
936          GetLastError());
937         size = sizeof(hashProperty);
938         ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
939          hashProperty, &size);
940         ok(ret, "CertSetCRLContextProperty failed: %08x\n", GetLastError());
941         ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
942         /* Delete the (bogus) hash, and get the real one */
943         ret = CertSetCRLContextProperty(context, CERT_HASH_PROP_ID, 0, NULL);
944         ok(ret, "CertSetCRLContextProperty failed: %08x\n", GetLastError());
945         checkCRLHash(CRL, sizeof(CRL), CALG_SHA1, context, CERT_HASH_PROP_ID);
946 
947         /* Now that the hash property is set, we should get one property when
948          * enumerating.
949          */
950         propID = 0;
951         numProps = 0;
952         do {
953             propID = CertEnumCRLContextProperties(context, propID);
954             if (propID)
955                 numProps++;
956         } while (propID != 0);
957         ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
958 
959         /* Check a few other implicit properties */
960         checkCRLHash(CRL, sizeof(CRL), CALG_MD5, context,
961          CERT_MD5_HASH_PROP_ID);
962 
963         CertFreeCRLContext(context);
964     }
965 }
966 
967 static const BYTE bigCertWithCRLDistPoints[] = {
968 0x30,0x81,0xa5,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
969 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
970 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
971 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
972 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
973 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
974 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
975 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
976 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x26,0x30,0x24,0x30,0x22,0x06,
977 0x03,0x55,0x1d,0x1f,0x04,0x1b,0x30,0x19,0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,
978 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
979 0x6f,0x72,0x67 };
980 
981 static void testIsValidCRLForCert(void)
982 {
983     BOOL ret;
984     PCCERT_CONTEXT cert1, cert2, cert3;
985     PCCRL_CONTEXT crl;
986     HCERTSTORE store;
987 
988     if(!pCertIsValidCRLForCertificate) return;
989 
990     crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
991      sizeof(v1CRLWithIssuerAndEntry));
992     ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
993     cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
994      sizeof(bigCert));
995     ok(cert1 != NULL, "CertCreateCertificateContext failed: %08x\n",
996      GetLastError());
997 
998     /* Crash
999     ret = CertIsValidCRLForCertificate(NULL, NULL, 0, NULL);
1000     ret = CertIsValidCRLForCertificate(cert1, NULL, 0, NULL);
1001      */
1002 
1003     /* Curiously, any CRL is valid for the NULL certificate */
1004     ret = pCertIsValidCRLForCertificate(NULL, crl, 0, NULL);
1005     ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1006 
1007     /* Same issuer for both cert and CRL, this CRL is valid for that cert */
1008     ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
1009     ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1010 
1011     cert2 = CertCreateCertificateContext(X509_ASN_ENCODING,
1012      bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer));
1013     ok(cert2 != NULL, "CertCreateCertificateContext failed: %08x\n",
1014      GetLastError());
1015 
1016     /* Yet more curious: different issuers for these, yet the CRL is valid for
1017      * that cert.  According to MSDN, the relevant bit to check is whether the
1018      * CRL has a CRL_ISSUING_DIST_POINT extension.
1019      */
1020     ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
1021     ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1022 
1023     CertFreeCRLContext(crl);
1024 
1025     /* With a CRL_ISSUING_DIST_POINT in the CRL, it returns FALSE, since the
1026      * cert doesn't have the same extension in it.
1027      */
1028     crl = CertCreateCRLContext(X509_ASN_ENCODING, v2CRLWithIssuingDistPoint,
1029      sizeof(v2CRLWithIssuingDistPoint));
1030     ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
1031 
1032     ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
1033     ok(!ret && GetLastError() == CRYPT_E_NO_MATCH,
1034      "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
1035     ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
1036     ok(!ret && GetLastError() == CRYPT_E_NO_MATCH,
1037      "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
1038 
1039     /* With a CRL_ISSUING_DIST_POINT in the CRL, it matches the cert containing
1040      * a CRL_DIST_POINTS_INFO extension.
1041      */
1042     cert3 = CertCreateCertificateContext(X509_ASN_ENCODING,
1043      bigCertWithCRLDistPoints, sizeof(bigCertWithCRLDistPoints));
1044     ok(cert3 != NULL, "CertCreateCertificateContext failed: %08x\n",
1045      GetLastError());
1046     ret = pCertIsValidCRLForCertificate(cert3, crl, 0, NULL);
1047     ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1048 
1049     CertFreeCRLContext(crl);
1050 
1051     /* And again, with a real CRL, the CRL is valid for all three certs. */
1052     crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
1053      sizeof(verisignCRL));
1054     ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
1055 
1056     ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
1057     ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1058     ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
1059     ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1060     ret = pCertIsValidCRLForCertificate(cert3, crl, 0, NULL);
1061     ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1062 
1063     CertFreeCRLContext(crl);
1064 
1065     /* One last test: a CRL in a different store than the cert is also valid
1066      * for the cert.
1067      */
1068     store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
1069      CERT_STORE_CREATE_NEW_FLAG, NULL);
1070     ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1071 
1072     ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, verisignCRL,
1073      sizeof(verisignCRL), CERT_STORE_ADD_ALWAYS, &crl);
1074     ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
1075 
1076     ret = pCertIsValidCRLForCertificate(cert1, crl, 0, NULL);
1077     ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1078     ret = pCertIsValidCRLForCertificate(cert2, crl, 0, NULL);
1079     ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1080     ret = pCertIsValidCRLForCertificate(cert3, crl, 0, NULL);
1081     ok(ret, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
1082 
1083     CertFreeCRLContext(crl);
1084 
1085     CertCloseStore(store, 0);
1086 
1087     CertFreeCertificateContext(cert3);
1088     CertFreeCertificateContext(cert2);
1089     CertFreeCertificateContext(cert1);
1090 }
1091 
1092 static const BYTE crlWithDifferentIssuer[] = {
1093  0x30,0x47,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
1094  0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x41,0x6c,0x65,0x78,0x20,0x4c,0x61,0x6e,
1095  0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
1096  0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
1097  0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a };
1098 
1099 static void testFindCertInCRL(void)
1100 {
1101     BOOL ret;
1102     PCCERT_CONTEXT cert;
1103     PCCRL_CONTEXT crl;
1104     PCRL_ENTRY entry;
1105 
1106     if (!pCertFindCertificateInCRL)
1107     {
1108         win_skip("CertFindCertificateInCRL() is not available\n");
1109         return;
1110     }
1111 
1112     cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
1113      sizeof(bigCert));
1114     ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n",
1115      GetLastError());
1116 
1117     /* Crash
1118     ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, NULL);
1119     ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, NULL);
1120     ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, NULL);
1121     ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, NULL);
1122     ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, &entry);
1123     ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, &entry);
1124     ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, &entry);
1125      */
1126 
1127     crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
1128      sizeof(verisignCRL));
1129     ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
1130     ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
1131     ok(entry == NULL, "Expected not to find an entry in CRL\n");
1132     CertFreeCRLContext(crl);
1133 
1134     crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
1135      sizeof(v1CRLWithIssuerAndEntry));
1136     ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
1137     ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
1138     ok(entry != NULL, "Expected to find an entry in CRL\n");
1139     CertFreeCRLContext(crl);
1140 
1141     /* Entry found even though CRL issuer doesn't match cert issuer */
1142     crl = CertCreateCRLContext(X509_ASN_ENCODING, crlWithDifferentIssuer,
1143      sizeof(crlWithDifferentIssuer));
1144     ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
1145     ok(ret, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
1146     ok(entry != NULL, "Expected to find an entry in CRL\n");
1147     CertFreeCRLContext(crl);
1148 
1149     CertFreeCertificateContext(cert);
1150 }
1151 
1152 static void testVerifyCRLRevocation(void)
1153 {
1154     BOOL ret;
1155     PCCERT_CONTEXT cert;
1156     PCCRL_CONTEXT crl;
1157 
1158     ret = CertVerifyCRLRevocation(0, NULL, 0, NULL);
1159     ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
1160     ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, NULL, 0, NULL);
1161     ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
1162 
1163     cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
1164      sizeof(bigCert));
1165 
1166     /* Check against no CRL */
1167     ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 0, NULL);
1168     ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
1169     ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 0, NULL);
1170     ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
1171 
1172     /* Check against CRL with entry for the cert */
1173     crl = CertCreateCRLContext(X509_ASN_ENCODING, v1CRLWithIssuerAndEntry,
1174      sizeof(v1CRLWithIssuerAndEntry));
1175     ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
1176      (PCRL_INFO *)&crl->pCrlInfo);
1177     ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
1178     ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
1179      (PCRL_INFO *)&crl->pCrlInfo);
1180     ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
1181     CertFreeCRLContext(crl);
1182 
1183     /* Check against CRL with different issuer and entry for the cert */
1184     crl = CertCreateCRLContext(X509_ASN_ENCODING, crlWithDifferentIssuer,
1185      sizeof(crlWithDifferentIssuer));
1186     ok(crl != NULL, "CertCreateCRLContext failed: %08x\n", GetLastError());
1187     ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
1188      (PCRL_INFO *)&crl->pCrlInfo);
1189     ok(!ret, "CertVerifyCRLRevocation should have been revoked\n");
1190     CertFreeCRLContext(crl);
1191 
1192     /* Check against CRL without entry for the cert */
1193     crl = CertCreateCRLContext(X509_ASN_ENCODING, verisignCRL,
1194      sizeof(verisignCRL));
1195     ret = CertVerifyCRLRevocation(0, cert->pCertInfo, 1,
1196      (PCRL_INFO *)&crl->pCrlInfo);
1197     ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
1198     ret = CertVerifyCRLRevocation(X509_ASN_ENCODING, cert->pCertInfo, 1,
1199      (PCRL_INFO *)&crl->pCrlInfo);
1200     ok(ret, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
1201     CertFreeCRLContext(crl);
1202 
1203     CertFreeCertificateContext(cert);
1204 }
1205 
1206 START_TEST(crl)
1207 {
1208     init_function_pointers();
1209 
1210     testCreateCRL();
1211     testDupCRL();
1212     testAddCRL();
1213     testFindCRL();
1214     testGetCRLFromStore();
1215 
1216     testCRLProperties();
1217 
1218     testIsValidCRLForCert();
1219     testFindCertInCRL();
1220     testVerifyCRLRevocation();
1221 }
1222