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