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