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 testAddCRL(void)
123 HCERTSTORE store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
124 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
125 PCCRL_CONTEXT context
;
131 /* Bad CRL encoding type */
132 ret
= CertAddEncodedCRLToStore(0, 0, NULL
, 0, 0, NULL
);
133 ok(!ret
&& GetLastError() == E_INVALIDARG
,
134 "Expected E_INVALIDARG, got %08x\n", GetLastError());
135 ret
= CertAddEncodedCRLToStore(store
, 0, NULL
, 0, 0, NULL
);
136 ok(!ret
&& GetLastError() == E_INVALIDARG
,
137 "Expected E_INVALIDARG, got %08x\n", GetLastError());
138 ret
= CertAddEncodedCRLToStore(0, 0, signedCRL
, sizeof(signedCRL
), 0, NULL
);
139 ok(!ret
&& GetLastError() == E_INVALIDARG
,
140 "Expected E_INVALIDARG, got %08x\n", GetLastError());
141 ret
= CertAddEncodedCRLToStore(store
, 0, signedCRL
, sizeof(signedCRL
), 0,
143 ok(!ret
&& GetLastError() == E_INVALIDARG
,
144 "Expected E_INVALIDARG, got %08x\n", GetLastError());
145 ret
= CertAddEncodedCRLToStore(0, 0, signedCRL
, sizeof(signedCRL
),
146 CERT_STORE_ADD_ALWAYS
, NULL
);
147 ok(!ret
&& GetLastError() == E_INVALIDARG
,
148 "Expected E_INVALIDARG, got %08x\n", GetLastError());
149 ret
= CertAddEncodedCRLToStore(store
, 0, signedCRL
, sizeof(signedCRL
),
150 CERT_STORE_ADD_ALWAYS
, NULL
);
151 ok(!ret
&& GetLastError() == E_INVALIDARG
,
152 "Expected E_INVALIDARG, got %08x\n", GetLastError());
155 ret
= CertAddEncodedCRLToStore(0, X509_ASN_ENCODING
, NULL
, 0, 0, NULL
);
156 GLE
= GetLastError();
157 ok(!ret
&& (GLE
== CRYPT_E_ASN1_EOD
|| GLE
== OSS_MORE_INPUT
),
158 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE
);
159 ret
= CertAddEncodedCRLToStore(store
, X509_ASN_ENCODING
, NULL
, 0, 0, NULL
);
160 GLE
= GetLastError();
161 ok(!ret
&& (GLE
== CRYPT_E_ASN1_EOD
|| GLE
== OSS_MORE_INPUT
),
162 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n", GLE
);
164 /* Weird--bad add disposition leads to an access violation in Windows. */
165 ret
= CertAddEncodedCRLToStore(0, X509_ASN_ENCODING
, signedCRL
,
166 sizeof(signedCRL
), 0, NULL
);
167 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
168 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
169 ret
= CertAddEncodedCRLToStore(store
, X509_ASN_ENCODING
, signedCRL
,
170 sizeof(signedCRL
), 0, NULL
);
171 ok(!ret
&& GetLastError() == STATUS_ACCESS_VIOLATION
,
172 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
174 /* Weird--can add a CRL to the NULL store (does this have special meaning?)
177 ret
= CertAddEncodedCRLToStore(0, X509_ASN_ENCODING
, signedCRL
,
178 sizeof(signedCRL
), CERT_STORE_ADD_ALWAYS
, &context
);
179 ok(ret
, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
181 CertFreeCRLContext(context
);
183 /* Normal cases: a "signed" CRL is okay.. */
184 ret
= CertAddEncodedCRLToStore(store
, X509_ASN_ENCODING
, signedCRL
,
185 sizeof(signedCRL
), CERT_STORE_ADD_ALWAYS
, NULL
);
186 /* and an unsigned one is too. */
187 ret
= CertAddEncodedCRLToStore(store
, X509_ASN_ENCODING
, CRL
, sizeof(CRL
),
188 CERT_STORE_ADD_ALWAYS
, NULL
);
189 ok(ret
, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
191 ret
= CertAddEncodedCRLToStore(store
, X509_ASN_ENCODING
, newerCRL
,
192 sizeof(newerCRL
), CERT_STORE_ADD_NEW
, NULL
);
193 ok(!ret
&& GetLastError() == CRYPT_E_EXISTS
,
194 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
196 /* This should replace (one of) the existing CRL(s). */
197 ret
= CertAddEncodedCRLToStore(store
, X509_ASN_ENCODING
, newerCRL
,
198 sizeof(newerCRL
), CERT_STORE_ADD_NEWER
, NULL
);
199 ok(ret
, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
201 CertCloseStore(store
, 0);
204 static void testFindCRL(void)
206 HCERTSTORE store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
207 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
208 PCCRL_CONTEXT context
;
213 if (!pCertFindCRLInStore
)
215 skip("CertFindCRLInStore() is not available\n");
219 ret
= CertAddEncodedCRLToStore(store
, X509_ASN_ENCODING
, signedCRL
,
220 sizeof(signedCRL
), CERT_STORE_ADD_ALWAYS
, NULL
);
221 ok(ret
, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
224 context = pCertFindCRLInStore(NULL, 0, 0, 0, NULL, NULL);
227 /* Find any context */
228 context
= pCertFindCRLInStore(store
, 0, 0, CRL_FIND_ANY
, NULL
, NULL
);
229 ok(context
!= NULL
, "Expected a context\n");
231 CertFreeCRLContext(context
);
232 /* Bogus flags are ignored */
233 context
= pCertFindCRLInStore(store
, 0, 1234, CRL_FIND_ANY
, NULL
, NULL
);
234 ok(context
!= NULL
, "Expected a context\n");
236 CertFreeCRLContext(context
);
237 /* CRL encoding type is ignored too */
238 context
= pCertFindCRLInStore(store
, 1234, 0, CRL_FIND_ANY
, NULL
, NULL
);
239 ok(context
!= NULL
, "Expected a context\n");
241 CertFreeCRLContext(context
);
243 /* This appears to match any cert */
244 context
= pCertFindCRLInStore(store
, 0, 0, CRL_FIND_ISSUED_BY
, NULL
, NULL
);
245 ok(context
!= NULL
, "Expected a context\n");
247 CertFreeCRLContext(context
);
249 /* Try to match an issuer that isn't in the store */
250 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert2
,
252 ok(cert
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
254 context
= pCertFindCRLInStore(store
, 0, 0, CRL_FIND_ISSUED_BY
, cert
, NULL
);
255 ok(context
== NULL
, "Expected no matching context\n");
256 CertFreeCertificateContext(cert
);
258 /* Match an issuer that is in the store */
259 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert
,
261 ok(cert
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
263 context
= pCertFindCRLInStore(store
, 0, 0, CRL_FIND_ISSUED_BY
, cert
, NULL
);
264 ok(context
!= NULL
, "Expected a context\n");
266 CertFreeCRLContext(context
);
267 CertFreeCertificateContext(cert
);
269 CertCloseStore(store
, 0);
272 static void testGetCRLFromStore(void)
274 HCERTSTORE store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, 0, 0,
275 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
276 PCCRL_CONTEXT context
;
284 context = CertGetCRLFromStore(NULL, NULL, NULL, NULL);
285 context = CertGetCRLFromStore(store, NULL, NULL, NULL);
290 context
= CertGetCRLFromStore(store
, NULL
, NULL
, &flags
);
291 ok(!context
&& GetLastError() == E_INVALIDARG
,
292 "Expected E_INVALIDARG, got %08x\n", GetLastError());
294 /* Test an empty store */
296 context
= CertGetCRLFromStore(store
, NULL
, NULL
, &flags
);
297 ok(context
== NULL
&& GetLastError() == CRYPT_E_NOT_FOUND
,
298 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
300 ret
= CertAddEncodedCRLToStore(store
, X509_ASN_ENCODING
, signedCRL
,
301 sizeof(signedCRL
), CERT_STORE_ADD_ALWAYS
, NULL
);
302 ok(ret
, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
304 /* NULL matches any CRL */
306 context
= CertGetCRLFromStore(store
, NULL
, NULL
, &flags
);
307 ok(context
!= NULL
, "Expected a context\n");
308 CertFreeCRLContext(context
);
310 /* This cert's issuer isn't in */
311 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert2
,
313 ok(cert
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
315 context
= CertGetCRLFromStore(store
, cert
, NULL
, &flags
);
316 ok(context
== NULL
&& GetLastError() == CRYPT_E_NOT_FOUND
,
317 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
318 CertFreeCertificateContext(cert
);
320 /* But this one is */
321 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert
,
323 ok(cert
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
325 context
= CertGetCRLFromStore(store
, cert
, NULL
, &flags
);
326 ok(context
!= NULL
, "Expected a context\n");
327 CertFreeCRLContext(context
);
328 CertFreeCertificateContext(cert
);
330 CertCloseStore(store
, 0);
333 static void checkCRLHash(const BYTE
*data
, DWORD dataLen
, ALG_ID algID
,
334 PCCRL_CONTEXT context
, DWORD propID
)
336 BYTE hash
[20] = { 0 }, hashProperty
[20];
340 memset(hash
, 0, sizeof(hash
));
341 memset(hashProperty
, 0, sizeof(hashProperty
));
343 ret
= CryptHashCertificate(0, algID
, 0, data
, dataLen
, hash
, &size
);
344 ok(ret
, "CryptHashCertificate failed: %08x\n", GetLastError());
345 ret
= CertGetCRLContextProperty(context
, propID
, hashProperty
, &size
);
346 ok(ret
, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
347 ok(!memcmp(hash
, hashProperty
, size
), "Unexpected hash for property %d\n",
351 static void testCRLProperties(void)
353 PCCRL_CONTEXT context
= CertCreateCRLContext(X509_ASN_ENCODING
,
356 ok(context
!= NULL
, "CertCreateCRLContext failed: %08x\n", GetLastError());
359 DWORD propID
, numProps
, access
, size
;
361 BYTE hash
[20] = { 0 }, hashProperty
[20];
362 CRYPT_DATA_BLOB blob
;
365 propID = CertEnumCRLContextProperties(NULL, 0);
371 propID
= CertEnumCRLContextProperties(context
, propID
);
374 } while (propID
!= 0);
375 ok(numProps
== 0, "Expected 0 properties, got %d\n", numProps
);
377 /* Tests with a NULL cert context. Prop ID 0 fails.. */
378 ret
= CertSetCRLContextProperty(NULL
, 0, 0, NULL
);
379 ok(!ret
&& GetLastError() == E_INVALIDARG
,
380 "Expected E_INVALIDARG, got %08x\n", GetLastError());
381 /* while this just crashes.
382 ret = CertSetCRLContextProperty(NULL, CERT_KEY_PROV_HANDLE_PROP_ID, 0,
386 ret
= CertSetCRLContextProperty(context
, 0, 0, NULL
);
387 ok(!ret
&& GetLastError() == E_INVALIDARG
,
388 "Expected E_INVALIDARG, got %08x\n", GetLastError());
389 /* Can't set the cert property directly, this crashes.
390 ret = CertSetCRLContextProperty(context, CERT_CRL_PROP_ID, 0, CRL);
394 ret = CertGetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
396 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID, NULL, NULL);
397 ret = CertGetCRLContextProperty(context, CERT_HASH_PROP_ID,
402 ret
= CertGetCRLContextProperty(context
, CERT_KEY_PROV_INFO_PROP_ID
,
404 ok(!ret
&& GetLastError() == CRYPT_E_NOT_FOUND
,
405 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
406 /* And, an implicit property */
407 ret
= CertGetCRLContextProperty(context
, CERT_ACCESS_STATE_PROP_ID
,
409 ok(ret
, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
410 ret
= CertGetCRLContextProperty(context
, CERT_ACCESS_STATE_PROP_ID
,
412 ok(ret
, "CertGetCRLContextProperty failed: %08x\n", GetLastError());
413 ok(!(access
& CERT_ACCESS_STATE_WRITE_PERSIST_FLAG
),
414 "Didn't expect a persisted crl\n");
415 /* Trying to set this "read only" property crashes.
416 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
417 ret = CertSetCRLContextProperty(context, CERT_ACCESS_STATE_PROP_ID, 0,
421 /* Can I set the hash to an invalid hash? */
423 blob
.cbData
= sizeof(hash
);
424 ret
= CertSetCRLContextProperty(context
, CERT_HASH_PROP_ID
, 0, &blob
);
425 ok(ret
, "CertSetCRLContextProperty failed: %08x\n",
427 size
= sizeof(hashProperty
);
428 ret
= CertGetCRLContextProperty(context
, CERT_HASH_PROP_ID
,
429 hashProperty
, &size
);
430 ok(!memcmp(hashProperty
, hash
, sizeof(hash
)), "Unexpected hash\n");
431 /* Delete the (bogus) hash, and get the real one */
432 ret
= CertSetCRLContextProperty(context
, CERT_HASH_PROP_ID
, 0, NULL
);
433 ok(ret
, "CertSetCRLContextProperty failed: %08x\n", GetLastError());
434 checkCRLHash(CRL
, sizeof(CRL
), CALG_SHA1
, context
, CERT_HASH_PROP_ID
);
436 /* Now that the hash property is set, we should get one property when
442 propID
= CertEnumCRLContextProperties(context
, propID
);
445 } while (propID
!= 0);
446 ok(numProps
== 1, "Expected 1 properties, got %d\n", numProps
);
448 /* Check a few other implicit properties */
449 checkCRLHash(CRL
, sizeof(CRL
), CALG_MD5
, context
,
450 CERT_MD5_HASH_PROP_ID
);
452 CertFreeCRLContext(context
);
456 static const BYTE v1CRLWithIssuerAndEntry
[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
457 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
458 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
459 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
460 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
461 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
462 static const BYTE v2CRLWithIssuingDistPoint
[] = { 0x30,0x5c,0x02,0x01,0x01,
463 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
464 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
465 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
466 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
467 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
468 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
469 static const BYTE verisignCRL
[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
470 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
471 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
472 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
473 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
474 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
475 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
476 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
477 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
478 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
479 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
480 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
481 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
482 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
483 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
484 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
485 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
486 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
487 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
488 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
489 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
490 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
491 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
492 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
493 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
494 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
495 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
496 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
497 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
498 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
499 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
500 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
501 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
502 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
505 static void testIsValidCRLForCert(void)
508 PCCERT_CONTEXT cert1
, cert2
;
512 if(!pCertIsValidCRLForCertificate
) return;
514 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, v1CRLWithIssuerAndEntry
,
515 sizeof(v1CRLWithIssuerAndEntry
));
516 ok(crl
!= NULL
, "CertCreateCRLContext failed: %08x\n", GetLastError());
517 cert1
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert
,
519 ok(cert1
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
523 ret = CertIsValidCRLForCertificate(NULL, NULL, 0, NULL);
524 ret = CertIsValidCRLForCertificate(cert1, NULL, 0, NULL);
527 /* Curiously, any CRL is valid for the NULL certificate */
528 ret
= pCertIsValidCRLForCertificate(NULL
, crl
, 0, NULL
);
529 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
531 /* Same issuer for both cert and CRL, this CRL is valid for that cert */
532 ret
= pCertIsValidCRLForCertificate(cert1
, crl
, 0, NULL
);
533 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
535 cert2
= CertCreateCertificateContext(X509_ASN_ENCODING
,
536 bigCertWithDifferentIssuer
, sizeof(bigCertWithDifferentIssuer
));
537 ok(cert2
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
540 /* Yet more curious: different issuers for these, yet the CRL is valid for
541 * that cert. According to MSDN, the relevant bit to check is whether the
542 * CRL has a CRL_ISSUING_DIST_POINT extension.
544 ret
= pCertIsValidCRLForCertificate(cert2
, crl
, 0, NULL
);
545 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
547 CertFreeCRLContext(crl
);
549 /* Yet with a CRL_ISSUING_DIST_POINT in the CRL, I still can't get this
550 * to say the CRL is not valid for either cert.
552 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, v2CRLWithIssuingDistPoint
,
553 sizeof(v2CRLWithIssuingDistPoint
));
554 ok(crl
!= NULL
, "CertCreateCRLContext failed: %08x\n", GetLastError());
556 ret
= pCertIsValidCRLForCertificate(cert1
, crl
, 0, NULL
);
557 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
558 ret
= pCertIsValidCRLForCertificate(cert2
, crl
, 0, NULL
);
559 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
561 CertFreeCRLContext(crl
);
563 /* And again, with a real CRL, the CRL is valid for both certs. */
564 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, verisignCRL
,
565 sizeof(verisignCRL
));
566 ok(crl
!= NULL
, "CertCreateCRLContext failed: %08x\n", GetLastError());
568 ret
= pCertIsValidCRLForCertificate(cert1
, crl
, 0, NULL
);
569 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
570 ret
= pCertIsValidCRLForCertificate(cert2
, crl
, 0, NULL
);
571 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
573 CertFreeCRLContext(crl
);
575 /* One last test: a CRL in a different store than the cert is also valid
576 * for the cert, so CertIsValidCRLForCertificate must always return TRUE?
578 store
= CertOpenStore(CERT_STORE_PROV_MEMORY
, X509_ASN_ENCODING
, 0,
579 CERT_STORE_CREATE_NEW_FLAG
, NULL
);
580 ok(store
!= NULL
, "CertOpenStore failed: %08x\n", GetLastError());
582 ret
= CertAddEncodedCRLToStore(store
, X509_ASN_ENCODING
, verisignCRL
,
583 sizeof(verisignCRL
), CERT_STORE_ADD_ALWAYS
, &crl
);
584 ok(ret
, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
586 ret
= pCertIsValidCRLForCertificate(cert1
, crl
, 0, NULL
);
587 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
588 ret
= pCertIsValidCRLForCertificate(cert2
, crl
, 0, NULL
);
589 ok(ret
, "CertIsValidCRLForCertificate failed: %08x\n", GetLastError());
591 CertFreeCRLContext(crl
);
593 CertCloseStore(store
, 0);
595 CertFreeCertificateContext(cert2
);
596 CertFreeCertificateContext(cert1
);
599 static const BYTE crlWithDifferentIssuer
[] = {
600 0x30,0x47,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
601 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x41,0x6c,0x65,0x78,0x20,0x4c,0x61,0x6e,
602 0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
603 0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,
604 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a };
606 static void testFindCertInCRL(void)
613 if (!pCertFindCertificateInCRL
)
615 skip("CertFindCertificateInCRL() is not available\n");
619 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert
,
621 ok(cert
!= NULL
, "CertCreateCertificateContext failed: %08x\n",
625 ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, NULL);
626 ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, NULL);
627 ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, NULL);
628 ret = pCertFindCertificateInCRL(cert, crl, 0, NULL, NULL);
629 ret = pCertFindCertificateInCRL(NULL, NULL, 0, NULL, &entry);
630 ret = pCertFindCertificateInCRL(NULL, crl, 0, NULL, &entry);
631 ret = pCertFindCertificateInCRL(cert, NULL, 0, NULL, &entry);
634 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, verisignCRL
,
635 sizeof(verisignCRL
));
636 ret
= pCertFindCertificateInCRL(cert
, crl
, 0, NULL
, &entry
);
637 ok(ret
, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
638 ok(entry
== NULL
, "Expected not to find an entry in CRL\n");
639 CertFreeCRLContext(crl
);
641 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, v1CRLWithIssuerAndEntry
,
642 sizeof(v1CRLWithIssuerAndEntry
));
643 ret
= pCertFindCertificateInCRL(cert
, crl
, 0, NULL
, &entry
);
644 ok(ret
, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
645 ok(entry
!= NULL
, "Expected to find an entry in CRL\n");
646 CertFreeCRLContext(crl
);
648 /* Entry found even though CRL issuer doesn't match cert issuer */
649 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, crlWithDifferentIssuer
,
650 sizeof(crlWithDifferentIssuer
));
651 ret
= pCertFindCertificateInCRL(cert
, crl
, 0, NULL
, &entry
);
652 ok(ret
, "CertFindCertificateInCRL failed: %08x\n", GetLastError());
653 ok(entry
!= NULL
, "Expected to find an entry in CRL\n");
654 CertFreeCRLContext(crl
);
656 CertFreeCertificateContext(cert
);
659 static void testVerifyCRLRevocation(void)
665 ret
= CertVerifyCRLRevocation(0, NULL
, 0, NULL
);
666 ok(ret
, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
667 ret
= CertVerifyCRLRevocation(X509_ASN_ENCODING
, NULL
, 0, NULL
);
668 ok(ret
, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
670 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, bigCert
,
673 /* Check against no CRL */
674 ret
= CertVerifyCRLRevocation(0, cert
->pCertInfo
, 0, NULL
);
675 ok(ret
, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
676 ret
= CertVerifyCRLRevocation(X509_ASN_ENCODING
, cert
->pCertInfo
, 0, NULL
);
677 ok(ret
, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
679 /* Check against CRL with entry for the cert */
680 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, v1CRLWithIssuerAndEntry
,
681 sizeof(v1CRLWithIssuerAndEntry
));
682 ret
= CertVerifyCRLRevocation(0, cert
->pCertInfo
, 1,
683 (PCRL_INFO
*)&crl
->pCrlInfo
);
684 ok(!ret
, "CertVerifyCRLRevocation should have been revoked\n");
685 ret
= CertVerifyCRLRevocation(X509_ASN_ENCODING
, cert
->pCertInfo
, 1,
686 (PCRL_INFO
*)&crl
->pCrlInfo
);
687 ok(!ret
, "CertVerifyCRLRevocation should have been revoked\n");
688 CertFreeCRLContext(crl
);
690 /* Check against CRL with different issuer and entry for the cert */
691 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, v1CRLWithIssuerAndEntry
,
692 sizeof(v1CRLWithIssuerAndEntry
));
693 ok(crl
!= NULL
, "CertCreateCRLContext failed: %08x\n", GetLastError());
694 ret
= CertVerifyCRLRevocation(X509_ASN_ENCODING
, cert
->pCertInfo
, 1,
695 (PCRL_INFO
*)&crl
->pCrlInfo
);
696 ok(!ret
, "CertVerifyCRLRevocation should have been revoked\n");
697 CertFreeCRLContext(crl
);
699 /* Check against CRL without entry for the cert */
700 crl
= CertCreateCRLContext(X509_ASN_ENCODING
, verisignCRL
,
701 sizeof(verisignCRL
));
702 ret
= CertVerifyCRLRevocation(0, cert
->pCertInfo
, 1,
703 (PCRL_INFO
*)&crl
->pCrlInfo
);
704 ok(ret
, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
705 ret
= CertVerifyCRLRevocation(X509_ASN_ENCODING
, cert
->pCertInfo
, 1,
706 (PCRL_INFO
*)&crl
->pCrlInfo
);
707 ok(ret
, "CertVerifyCRLRevocation failed: %08x\n", GetLastError());
708 CertFreeCRLContext(crl
);
710 CertFreeCertificateContext(cert
);
715 init_function_pointers();
720 testGetCRLFromStore();
724 testIsValidCRLForCert();
726 testVerifyCRLRevocation();