2 * crypt32 CRL functions tests
4 * Copyright 2005-2006 Juan Lang
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.
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.
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
30 #include "wine/test.h"
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,
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,
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 };
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*);
84 static void init_function_pointers(void)
86 HMODULE hdll
= GetModuleHandleA("crypt32.dll");
87 pCertFindCertificateInCRL
= (void*)GetProcAddress(hdll
, "CertFindCertificateInCRL");
88 pCertFindCRLInStore
= (void*)GetProcAddress(hdll
, "CertFindCRLInStore");
89 pCertIsValidCRLForCertificate
= (void*)GetProcAddress(hdll
, "CertIsValidCRLForCertificate");
92 static void testCreateCRL(void)
94 PCCRL_CONTEXT context
;
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
,
112 ok(context
!= NULL
, "CertCreateCRLContext failed: %08x\n", GetLastError());
114 CertFreeCRLContext(context
);
115 context
= CertCreateCRLContext(X509_ASN_ENCODING
, CRL
, sizeof(CRL
));
116 ok(context
!= NULL
, "CertCreateCRLContext failed: %08x\n", GetLastError());
118 CertFreeCRLContext(context
);
121 static void testDupCRL(void)
123 PCCRL_CONTEXT context
, dupContext
;
125 context
= CertDuplicateCRLContext(NULL
);
126 ok(context
== NULL
, "expected NULL\n");
127 context
= CertCreateCRLContext(X509_ASN_ENCODING
, 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
);
136 static void testAddCRL(void)
138 HCERTSTORE store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
139 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
140 PCCRL_CONTEXT context
;
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,
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());
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
);
179 /* Weird--bad add disposition leads to an access violation in Windows.
180 * Both tests crash on some win9x boxes.
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());
196 /* Weird--can add a CRL to the NULL store (does this have special meaning?)
199 ret
= CertAddEncodedCRLToStore(0, X509_ASN_ENCODING
, signedCRL
,
200 sizeof(signedCRL
), CERT_STORE_ADD_ALWAYS
, &context
);
201 ok(ret
, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
203 CertFreeCRLContext(context
);
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());
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());
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());
223 CertCloseStore(store
, 0);
226 static void testFindCRL(void)
228 HCERTSTORE store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
229 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
230 PCCRL_CONTEXT context
;
235 if (!pCertFindCRLInStore
)
237 win_skip("CertFindCRLInStore() is not available\n");
241 ret
= CertAddEncodedCRLToStore(store
, X509_ASN_ENCODING
, signedCRL
,
242 sizeof(signedCRL
), CERT_STORE_ADD_ALWAYS
, NULL
);
243 ok(ret
, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
246 context = pCertFindCRLInStore(NULL, 0, 0, 0, NULL, NULL);
249 /* Find any context */
250 context
= pCertFindCRLInStore(store
, 0, 0, CRL_FIND_ANY
, NULL
, NULL
);
251 ok(context
!= NULL
, "Expected a context\n");
253 CertFreeCRLContext(context
);
254 /* Bogus flags are ignored */
255 context
= pCertFindCRLInStore(store
, 0, 1234, CRL_FIND_ANY
, NULL
, NULL
);
256 ok(context
!= NULL
, "Expected a context\n");
258 CertFreeCRLContext(context
);
259 /* CRL encoding type is ignored too */
260 context
= pCertFindCRLInStore(store
, 1234, 0, CRL_FIND_ANY
, NULL
, NULL
);
261 ok(context
!= NULL
, "Expected a context\n");
263 CertFreeCRLContext(context
);
265 /* This appears to match any cert */
266 context
= pCertFindCRLInStore(store
, 0, 0, CRL_FIND_ISSUED_BY
, NULL
, NULL
);
267 ok(context
!= NULL
, "Expected a context\n");
269 CertFreeCRLContext(context
);
271 /* Try to match an issuer that isn't in the store */
272 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert2
,
274 ok(cert
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
276 context
= pCertFindCRLInStore(store
, 0, 0, CRL_FIND_ISSUED_BY
, cert
, NULL
);
277 ok(context
== NULL
, "Expected no matching context\n");
278 CertFreeCertificateContext(cert
);
280 /* Match an issuer that is in the store */
281 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert
,
283 ok(cert
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
285 context
= pCertFindCRLInStore(store
, 0, 0, CRL_FIND_ISSUED_BY
, cert
, NULL
);
286 ok(context
!= NULL
, "Expected a context\n");
288 CertFreeCRLContext(context
);
289 CertFreeCertificateContext(cert
);
291 CertCloseStore(store
, 0);
294 static void testGetCRLFromStore(void)
296 HCERTSTORE store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
297 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
298 PCCRL_CONTEXT context
;
306 context = CertGetCRLFromStore(NULL, NULL, NULL, NULL);
307 context = CertGetCRLFromStore(store, NULL, NULL, NULL);
312 context
= CertGetCRLFromStore(store
, NULL
, NULL
, &flags
);
313 ok(!context
&& GetLastError() == E_INVALIDARG
,
314 "Expected E_INVALIDARG, got %08x\n", GetLastError());
316 /* Test an empty store */
318 context
= CertGetCRLFromStore(store
, NULL
, NULL
, &flags
);
319 ok(context
== NULL
&& GetLastError() == CRYPT_E_NOT_FOUND
,
320 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
322 ret
= CertAddEncodedCRLToStore(store
, X509_ASN_ENCODING
, signedCRL
,
323 sizeof(signedCRL
), CERT_STORE_ADD_ALWAYS
, NULL
);
324 ok(ret
, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
326 /* NULL matches any CRL */
328 context
= CertGetCRLFromStore(store
, NULL
, NULL
, &flags
);
329 ok(context
!= NULL
, "Expected a context\n");
330 CertFreeCRLContext(context
);
332 /* This cert's issuer isn't in */
333 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert2
,
335 ok(cert
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
337 context
= CertGetCRLFromStore(store
, cert
, NULL
, &flags
);
338 ok(context
== NULL
&& GetLastError() == CRYPT_E_NOT_FOUND
,
339 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
340 CertFreeCertificateContext(cert
);
342 /* But this one is */
343 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert
,
345 ok(cert
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
347 context
= CertGetCRLFromStore(store
, cert
, NULL
, &flags
);
348 ok(context
!= NULL
, "Expected a context\n");
349 CertFreeCRLContext(context
);
350 CertFreeCertificateContext(cert
);
352 CertCloseStore(store
, 0);
355 static void checkCRLHash(const BYTE
*data
, DWORD dataLen
, ALG_ID algID
,
356 PCCRL_CONTEXT context
, DWORD propID
)
358 BYTE hash
[20] = { 0 }, hashProperty
[20];
362 memset(hash
, 0, sizeof(hash
));
363 memset(hashProperty
, 0, sizeof(hashProperty
));
365 ret
= CryptHashCertificate(0, algID
, 0, data
, dataLen
, hash
, &size
);
366 ok(ret
, "CryptHashCertificate failed: %08x\n", GetLastError());
367 ret
= CertGetCRLContextProperty(context
, propID
, hashProperty
, &size
);
368 ok(ret
, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
369 ok(!memcmp(hash
, hashProperty
, size
), "Unexpected hash for property %d\n",
373 static void testCRLProperties(void)
375 PCCRL_CONTEXT context
= CertCreateCRLContext(X509_ASN_ENCODING
,
378 ok(context
!= NULL
, "CertCreateCRLContext failed: %08x\n", GetLastError());
381 DWORD propID
, numProps
, access
, size
;
383 BYTE hash
[20] = { 0 }, hashProperty
[20];
384 CRYPT_DATA_BLOB blob
;
387 propID = CertEnumCRLContextProperties(NULL, 0);
393 propID
= CertEnumCRLContextProperties(context
, propID
);
396 } while (propID
!= 0);
397 ok(numProps
== 0, "Expected 0 properties, got %d\n", numProps
);
399 /* Tests with a NULL cert context. Prop ID 0 fails.. */
400 ret
= CertSetCRLContextProperty(NULL
, 0, 0, NULL
);
401 ok(!ret
&& GetLastError() == E_INVALIDARG
,
402 "Expected E_INVALIDARG, got %08x\n", GetLastError());
403 /* while this just crashes.
404 ret = CertSetCRLContextProperty(NULL, CERT_KEY_PROV_HANDLE_PROP_ID, 0,
408 ret
= CertSetCRLContextProperty(context
, 0, 0, NULL
);
409 ok(!ret
&& GetLastError() == E_INVALIDARG
,
410 "Expected E_INVALIDARG, got %08x\n", GetLastError());
411 /* Can't set the cert property directly, this crashes.
412 ret = CertSetCRLContextProperty(context, CERT_CRL_PROP_ID, 0, CRL);
416 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
418 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID, NULL, NULL);
419 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
424 ret
= CertGetCRLContextProperty(context
, CERT_KEY_PROV_INFO_PROP_ID
,
426 ok(!ret
&& GetLastError() == CRYPT_E_NOT_FOUND
,
427 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
428 /* And, an implicit property */
429 ret
= CertGetCRLContextProperty(context
, CERT_ACCESS_STATE_PROP_ID
,
431 ok(ret
, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
432 ret
= CertGetCRLContextProperty(context
, CERT_ACCESS_STATE_PROP_ID
,
434 ok(ret
, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
435 ok(!(access
& CERT_ACCESS_STATE_WRITE_PERSIST_FLAG
),
436 "Didn't expect a persisted crl\n");
437 /* Trying to set this "read only" property crashes.
438 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
439 ret = CertSetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
443 /* Can I set the hash to an invalid hash? */
445 blob
.cbData
= sizeof(hash
);
446 ret
= CertSetCRLContextProperty(context
, CERT_HASH_PROP_ID
, 0, &blob
);
447 ok(ret
, "CertSetCRLContextProperty failed: %08x\n",
449 size
= sizeof(hashProperty
);
450 ret
= CertGetCRLContextProperty(context
, CERT_HASH_PROP_ID
,
451 hashProperty
, &size
);
452 ok(!memcmp(hashProperty
, hash
, sizeof(hash
)), "Unexpected hash\n");
453 /* Delete the (bogus) hash, and get the real one */
454 ret
= CertSetCRLContextProperty(context
, CERT_HASH_PROP_ID
, 0, NULL
);
455 ok(ret
, "CertSetCRLContextProperty failed: %08x\n", GetLastError());
456 checkCRLHash(CRL
, sizeof(CRL
), CALG_SHA1
, context
, CERT_HASH_PROP_ID
);
458 /* Now that the hash property is set, we should get one property when
464 propID
= CertEnumCRLContextProperties(context
, propID
);
467 } while (propID
!= 0);
468 ok(numProps
== 1, "Expected 1 properties, got %d\n", numProps
);
470 /* Check a few other implicit properties */
471 checkCRLHash(CRL
, sizeof(CRL
), CALG_MD5
, context
,
472 CERT_MD5_HASH_PROP_ID
);
474 CertFreeCRLContext(context
);
478 static const BYTE v1CRLWithIssuerAndEntry
[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
479 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
480 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
481 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
482 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
483 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
484 static const BYTE v2CRLWithIssuingDistPoint
[] = { 0x30,0x5c,0x02,0x01,0x01,
485 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
486 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
487 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
488 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
489 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
490 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
491 static const BYTE verisignCRL
[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
492 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
493 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
494 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
495 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
496 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
497 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
498 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
499 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
500 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
501 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
502 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
503 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
504 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
505 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
506 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
507 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
508 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
509 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
510 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
511 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
512 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
513 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
514 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
515 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
516 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
517 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
518 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
519 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
520 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
521 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
522 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
523 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
524 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
527 static void testIsValidCRLForCert(void)
530 PCCERT_CONTEXT cert1
, cert2
;
534 if(!pCertIsValidCRLForCertificate
) return;
536 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, v1CRLWithIssuerAndEntry
,
537 sizeof(v1CRLWithIssuerAndEntry
));
538 ok(crl
!= NULL
, "CertCreateCRLContext failed: %08x\n", GetLastError());
539 cert1
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert
,
541 ok(cert1
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
545 ret = CertIsValidCRLForCertificate(NULL, NULL, 0, NULL);
546 ret = CertIsValidCRLForCertificate(cert1, NULL, 0, NULL);
549 /* Curiously, any CRL is valid for the NULL certificate */
550 ret
= pCertIsValidCRLForCertificate(NULL
, crl
, 0, NULL
);
551 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
553 /* Same issuer for both cert and CRL, this CRL is valid for that cert */
554 ret
= pCertIsValidCRLForCertificate(cert1
, crl
, 0, NULL
);
555 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
557 cert2
= CertCreateCertificateContext(X509_ASN_ENCODING
,
558 bigCertWithDifferentIssuer
, sizeof(bigCertWithDifferentIssuer
));
559 ok(cert2
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
562 /* Yet more curious: different issuers for these, yet the CRL is valid for
563 * that cert. According to MSDN, the relevant bit to check is whether the
564 * CRL has a CRL_ISSUING_DIST_POINT extension.
566 ret
= pCertIsValidCRLForCertificate(cert2
, crl
, 0, NULL
);
567 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
569 CertFreeCRLContext(crl
);
571 /* Yet with a CRL_ISSUING_DIST_POINT in the CRL, I still can't get this
572 * to say the CRL is not valid for either cert.
574 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, v2CRLWithIssuingDistPoint
,
575 sizeof(v2CRLWithIssuingDistPoint
));
576 ok(crl
!= NULL
, "CertCreateCRLContext failed: %08x\n", GetLastError());
578 ret
= pCertIsValidCRLForCertificate(cert1
, crl
, 0, NULL
);
579 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
580 ret
= pCertIsValidCRLForCertificate(cert2
, crl
, 0, NULL
);
581 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
583 CertFreeCRLContext(crl
);
585 /* And again, with a real CRL, the CRL is valid for both certs. */
586 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, verisignCRL
,
587 sizeof(verisignCRL
));
588 ok(crl
!= NULL
, "CertCreateCRLContext failed: %08x\n", GetLastError());
590 ret
= pCertIsValidCRLForCertificate(cert1
, crl
, 0, NULL
);
591 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
592 ret
= pCertIsValidCRLForCertificate(cert2
, crl
, 0, NULL
);
593 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
595 CertFreeCRLContext(crl
);
597 /* One last test: a CRL in a different store than the cert is also valid
598 * for the cert, so CertIsValidCRLForCertificate must always return TRUE?
600 store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, X509_ASN_ENCODING
, 0,
601 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
602 ok(store
!= NULL
, "CertOpenStore failed: %08x\n", GetLastError());
604 ret
= CertAddEncodedCRLToStore(store
, X509_ASN_ENCODING
, verisignCRL
,
605 sizeof(verisignCRL
), CERT_STORE_ADD_ALWAYS
, &crl
);
606 ok(ret
, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
608 ret
= pCertIsValidCRLForCertificate(cert1
, crl
, 0, NULL
);
609 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
610 ret
= pCertIsValidCRLForCertificate(cert2
, crl
, 0, NULL
);
611 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
613 CertFreeCRLContext(crl
);
615 CertCloseStore(store
, 0);
617 CertFreeCertificateContext(cert2
);
618 CertFreeCertificateContext(cert1
);
621 static const BYTE crlWithDifferentIssuer
[] = {
622 0x30,0x47,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
623 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x41,0x6c,0x65,0x78,0x20,0x4c,0x61,0x6e,
624 0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
625 0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
626 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a };
628 static void testFindCertInCRL(void)
635 if (!pCertFindCertificateInCRL
)
637 win_skip("CertFindCertificateInCRL() is not available\n");
641 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert
,
643 ok(cert
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
647 ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, NULL);
648 ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, NULL);
649 ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, NULL);
650 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, NULL);
651 ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, &entry);
652 ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, &entry);
653 ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, &entry);
656 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, verisignCRL
,
657 sizeof(verisignCRL
));
658 ret
= pCertFindCertificateInCRL(cert
, crl
, 0, NULL
, &entry
);
659 ok(ret
, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
660 ok(entry
== NULL
, "Expected not to find an entry in CRL\n");
661 CertFreeCRLContext(crl
);
663 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, v1CRLWithIssuerAndEntry
,
664 sizeof(v1CRLWithIssuerAndEntry
));
665 ret
= pCertFindCertificateInCRL(cert
, crl
, 0, NULL
, &entry
);
666 ok(ret
, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
667 ok(entry
!= NULL
, "Expected to find an entry in CRL\n");
668 CertFreeCRLContext(crl
);
670 /* Entry found even though CRL issuer doesn't match cert issuer */
671 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, crlWithDifferentIssuer
,
672 sizeof(crlWithDifferentIssuer
));
673 ret
= pCertFindCertificateInCRL(cert
, crl
, 0, NULL
, &entry
);
674 ok(ret
, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
675 ok(entry
!= NULL
, "Expected to find an entry in CRL\n");
676 CertFreeCRLContext(crl
);
678 CertFreeCertificateContext(cert
);
681 static void testVerifyCRLRevocation(void)
687 ret
= CertVerifyCRLRevocation(0, NULL
, 0, NULL
);
688 ok(ret
, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
689 ret
= CertVerifyCRLRevocation(X509_ASN_ENCODING
, NULL
, 0, NULL
);
690 ok(ret
, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
692 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert
,
695 /* Check against no CRL */
696 ret
= CertVerifyCRLRevocation(0, cert
->pCertInfo
, 0, NULL
);
697 ok(ret
, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
698 ret
= CertVerifyCRLRevocation(X509_ASN_ENCODING
, cert
->pCertInfo
, 0, NULL
);
699 ok(ret
, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
701 /* Check against CRL with entry for the cert */
702 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, v1CRLWithIssuerAndEntry
,
703 sizeof(v1CRLWithIssuerAndEntry
));
704 ret
= CertVerifyCRLRevocation(0, cert
->pCertInfo
, 1,
705 (PCRL_INFO
*)&crl
->pCrlInfo
);
706 ok(!ret
, "CertVerifyCRLRevocation should have been revoked\n");
707 ret
= CertVerifyCRLRevocation(X509_ASN_ENCODING
, cert
->pCertInfo
, 1,
708 (PCRL_INFO
*)&crl
->pCrlInfo
);
709 ok(!ret
, "CertVerifyCRLRevocation should have been revoked\n");
710 CertFreeCRLContext(crl
);
712 /* Check against CRL with different issuer and entry for the cert */
713 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, v1CRLWithIssuerAndEntry
,
714 sizeof(v1CRLWithIssuerAndEntry
));
715 ok(crl
!= NULL
, "CertCreateCRLContext failed: %08x\n", GetLastError());
716 ret
= CertVerifyCRLRevocation(X509_ASN_ENCODING
, cert
->pCertInfo
, 1,
717 (PCRL_INFO
*)&crl
->pCrlInfo
);
718 ok(!ret
, "CertVerifyCRLRevocation should have been revoked\n");
719 CertFreeCRLContext(crl
);
721 /* Check against CRL without entry for the cert */
722 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, verisignCRL
,
723 sizeof(verisignCRL
));
724 ret
= CertVerifyCRLRevocation(0, cert
->pCertInfo
, 1,
725 (PCRL_INFO
*)&crl
->pCrlInfo
);
726 ok(ret
, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
727 ret
= CertVerifyCRLRevocation(X509_ASN_ENCODING
, cert
->pCertInfo
, 1,
728 (PCRL_INFO
*)&crl
->pCrlInfo
);
729 ok(ret
, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
730 CertFreeCRLContext(crl
);
732 CertFreeCertificateContext(cert
);
737 init_function_pointers();
743 testGetCRLFromStore();
747 testIsValidCRLForCert();
749 testVerifyCRLRevocation();