Release 20050930.
[wine/gsoc-2012-control.git] / dlls / crypt32 / tests / cert.c
blob64b06de1ad29eca925e496e747d99586722b3fee
1 /*
2 * crypt32 cert functions tests
4 * Copyright 2005 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winreg.h>
26 #include <winerror.h>
27 #include <wincrypt.h>
29 #include "wine/test.h"
31 /* The following aren't defined in wincrypt.h, as they're "reserved" */
32 #define CERT_CERT_PROP_ID 32
33 #define CERT_CRL_PROP_ID 33
34 #define CERT_CTL_PROP_ID 34
36 struct CertPropIDHeader
38 DWORD propID;
39 DWORD unknown1;
40 DWORD cb;
43 static void testCryptHashCert(void)
45 static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b,
46 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07,
47 0x09 };
48 static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee,
49 0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8,
50 0xa2 };
51 static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:";
52 BOOL ret;
53 BYTE hash[20];
54 DWORD hashLen = sizeof(hash);
56 /* NULL buffer and nonzero length crashes
57 ret = CryptHashCertificate(0, 0, 0, NULL, size, hash, &hashLen);
58 empty hash length also crashes
59 ret = CryptHashCertificate(0, 0, 0, buf, size, hash, NULL);
61 /* Test empty hash */
62 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), NULL,
63 &hashLen);
64 ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError());
65 ok(hashLen == sizeof(hash),
66 "Got unexpected size of hash %ld, expected %d\n", hashLen, sizeof(hash));
67 /* Test with empty buffer */
68 ret = CryptHashCertificate(0, 0, 0, NULL, 0, hash, &hashLen);
69 ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError());
70 ok(!memcmp(hash, emptyHash, sizeof(emptyHash)),
71 "Unexpected hash of nothing\n");
72 /* Test a known value */
73 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), hash,
74 &hashLen);
75 ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError());
76 ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
79 static const BYTE emptyCert[] = { 0x30, 0x00 };
80 static const BYTE bigCert[] = "\x30\x7a\x02\x01\x01\x30\x02\x06\x00"
81 "\x30\x15\x31\x13\x30\x11\x06\x03\x55\x04\x03\x13\x0a\x4a\x75\x61\x6e\x20\x4c"
82 "\x61\x6e\x67\x00\x30\x22\x18\x0f\x31\x36\x30\x31\x30\x31\x30\x31\x30\x30\x30"
83 "\x30\x30\x30\x5a\x18\x0f\x31\x36\x30\x31\x30\x31\x30\x31\x30\x30\x30\x30\x30"
84 "\x30\x5a\x30\x15\x31\x13\x30\x11\x06\x03\x55\x04\x03\x13\x0a\x4a\x75\x61\x6e"
85 "\x20\x4c\x61\x6e\x67\x00\x30\x07\x30\x02\x06\x00\x03\x01\x00\xa3\x16\x30\x14"
86 "\x30\x12\x06\x03\x55\x1d\x13\x01\x01\xff\x04\x08\x30\x06\x01\x01\xff\x02\x01"
87 "\x01";
88 static const BYTE signedBigCert[] = {
89 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
90 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
91 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
92 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
93 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
94 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
95 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
96 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
97 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
98 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
99 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
100 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
101 static const BYTE serializedCert[] = { 0x20, 0x00, 0x00, 0x00,
102 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x7a, 0x02, 0x01, 0x01,
103 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
104 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67,
105 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31,
106 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
107 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15,
108 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75,
109 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06,
110 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
111 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
112 0x01, 0x01 };
113 static const BYTE signedCRL[] = { 0x30, 0x45, 0x30, 0x2c, 0x30, 0x02, 0x06,
114 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
115 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
116 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
117 0x30, 0x5a, 0x30, 0x02, 0x06, 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c,
118 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
120 static void testMemStore(void)
122 HCERTSTORE store1, store2;
123 PCCERT_CONTEXT context;
124 BOOL ret;
126 /* NULL provider */
127 store1 = CertOpenStore(0, 0, 0, 0, NULL);
128 ok(!store1 && GetLastError() == ERROR_FILE_NOT_FOUND,
129 "Expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError());
130 /* weird flags */
131 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
132 CERT_STORE_DELETE_FLAG, NULL);
133 ok(!store1 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
134 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %ld\n", GetLastError());
136 /* normal */
137 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
138 CERT_STORE_CREATE_NEW_FLAG, NULL);
139 ok(store1 != NULL, "CertOpenStore failed: %ld\n", GetLastError());
140 /* open existing doesn't */
141 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
142 CERT_STORE_OPEN_EXISTING_FLAG, NULL);
143 ok(store2 != NULL, "CertOpenStore failed: %ld\n", GetLastError());
144 ok(store1 != store2, "Expected different stores\n");
146 /* add a bogus (empty) cert */
147 context = NULL;
148 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, emptyCert,
149 sizeof(emptyCert), CERT_STORE_ADD_ALWAYS, &context);
150 /* Windows returns CRYPT_E_ASN1_EOD, but accept CRYPT_E_ASN1_CORRUPT as
151 * well (because matching errors is tough in this case)
153 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || GetLastError() ==
154 CRYPT_E_ASN1_CORRUPT),
155 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08lx\n",
156 GetLastError());
157 /* add a "signed" cert--the signature isn't a real signature, so this adds
158 * without any check of the signature's validity
160 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
161 signedBigCert, sizeof(signedBigCert), CERT_STORE_ADD_ALWAYS, &context);
162 ok(ret, "CertAddEncodedCertificateToStore failed: %08lx\n", GetLastError());
163 ok(context != NULL, "Expected a valid cert context\n");
164 if (context)
166 ok(context->cbCertEncoded == sizeof(signedBigCert),
167 "Expected cert of %d bytes, got %ld\n", sizeof(signedBigCert),
168 context->cbCertEncoded);
169 ok(!memcmp(context->pbCertEncoded, signedBigCert,
170 sizeof(signedBigCert)), "Unexpected encoded cert in context\n");
171 /* remove it, the rest of the tests will work on an unsigned cert */
172 ret = CertDeleteCertificateFromStore(context);
173 ok(ret, "CertDeleteCertificateFromStore failed: %08lx\n",
174 GetLastError());
176 /* try adding a "signed" CRL as a cert */
177 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
178 signedCRL, sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &context);
179 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG || GetLastError() ==
180 CRYPT_E_ASN1_CORRUPT),
181 "Expected CRYPT_E_ASN1_BADTAG or CRYPT_E_ASN1_CORRUPT, got %08lx\n",
182 GetLastError());
183 /* add a cert to store1 */
184 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, bigCert,
185 sizeof(bigCert) - 1, CERT_STORE_ADD_ALWAYS, &context);
186 ok(ret, "CertAddEncodedCertificateToStore failed: %08lx\n", GetLastError());
187 ok(context != NULL, "Expected a valid cert context\n");
188 if (context)
190 DWORD size;
191 BYTE *buf;
193 ok(context->cbCertEncoded == sizeof(bigCert) - 1,
194 "Expected cert of %d bytes, got %ld\n", sizeof(bigCert) - 1,
195 context->cbCertEncoded);
196 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert) - 1),
197 "Unexpected encoded cert in context\n");
198 ok(context->hCertStore == store1, "Unexpected store\n");
200 /* check serializing this element */
201 /* These crash
202 ret = CertSerializeCertificateStoreElement(NULL, 0, NULL, NULL);
203 ret = CertSerializeCertificateStoreElement(context, 0, NULL, NULL);
204 ret = CertSerializeCertificateStoreElement(NULL, 0, NULL, &size);
206 /* apparently flags are ignored */
207 ret = CertSerializeCertificateStoreElement(context, 1, NULL, &size);
208 ok(ret, "CertSerializeCertificateStoreElement failed: %08lx\n",
209 GetLastError());
210 buf = HeapAlloc(GetProcessHeap(), 0, size);
211 if (buf)
213 ret = CertSerializeCertificateStoreElement(context, 0, buf, &size);
214 ok(size == sizeof(serializedCert), "Expected size %d, got %ld\n",
215 sizeof(serializedCert), size);
216 ok(!memcmp(serializedCert, buf, size),
217 "Unexpected serialized cert\n");
218 HeapFree(GetProcessHeap(), 0, buf);
221 ret = CertFreeCertificateContext(context);
222 ok(ret, "CertFreeCertificateContext failed: %08lx\n", GetLastError());
224 /* verify the cert's in store1 */
225 context = CertEnumCertificatesInStore(store1, NULL);
226 ok(context != NULL, "Expected a valid context\n");
227 context = CertEnumCertificatesInStore(store1, context);
228 ok(!context && GetLastError() == CRYPT_E_NOT_FOUND,
229 "Expected CRYPT_E_NOT_FOUND, got %08lx\n", GetLastError());
230 /* verify store2 (the "open existing" mem store) is still empty */
231 context = CertEnumCertificatesInStore(store2, NULL);
232 ok(!context, "Expected an empty store\n");
233 /* delete the cert from store1, and check it's empty */
234 context = CertEnumCertificatesInStore(store1, NULL);
235 if (context)
237 /* Deleting a bitwise copy crashes with an access to an uninitialized
238 * pointer, so a cert context has some special data out there in memory
239 * someplace
240 CERT_CONTEXT copy;
241 memcpy(&copy, context, sizeof(copy));
242 ret = CertDeleteCertificateFromStore(&copy);
244 PCCERT_CONTEXT copy = CertDuplicateCertificateContext(context);
246 ok(copy != NULL, "CertDuplicateCertificateContext failed: %08lx\n",
247 GetLastError());
248 ret = CertDeleteCertificateFromStore(context);
249 ok(ret, "CertDeleteCertificateFromStore failed: %08lx\n",
250 GetLastError());
251 /* try deleting a copy */
252 ret = CertDeleteCertificateFromStore(copy);
253 ok(ret, "CertDeleteCertificateFromStore failed: %08lx\n",
254 GetLastError());
255 /* check that the store is empty */
256 context = CertEnumCertificatesInStore(store1, NULL);
257 ok(!context, "Expected an empty store\n");
260 /* close an empty store */
261 ret = CertCloseStore(NULL, 0);
262 ok(ret, "CertCloseStore failed: %ld\n", GetLastError());
263 ret = CertCloseStore(store1, 0);
264 ok(ret, "CertCloseStore failed: %ld\n", GetLastError());
265 ret = CertCloseStore(store2, 0);
266 ok(ret, "CertCloseStore failed: %ld\n", GetLastError());
268 /* This seems nonsensical, but you can open a read-only mem store, only
269 * it isn't read-only
271 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
272 CERT_STORE_READONLY_FLAG, NULL);
273 ok(store1 != NULL, "CertOpenStore failed: %ld\n", GetLastError());
274 /* yep, this succeeds */
275 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, bigCert,
276 sizeof(bigCert) - 1, CERT_STORE_ADD_ALWAYS, &context);
277 ok(ret, "CertAddEncodedCertificateToStore failed: %08lx\n", GetLastError());
278 ok(context != NULL, "Expected a valid cert context\n");
279 if (context)
281 ok(context->cbCertEncoded == sizeof(bigCert) - 1,
282 "Expected cert of %d bytes, got %ld\n", sizeof(bigCert) - 1,
283 context->cbCertEncoded);
284 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert) - 1),
285 "Unexpected encoded cert in context\n");
286 ok(context->hCertStore == store1, "Unexpected store\n");
287 ret = CertDeleteCertificateFromStore(context);
288 ok(ret, "CertDeleteCertificateFromStore failed: %08lx\n",
289 GetLastError());
291 CertCloseStore(store1, 0);
294 static const BYTE bigCert2[] = "\x30\x7a\x02\x01\x01\x30\x02\x06\x00"
295 "\x30\x15\x31\x13\x30\x11\x06\x03\x55\x04\x03\x13\x0a\x41\x6c\x65\x78\x20\x4c"
296 "\x61\x6e\x67\x00\x30\x22\x18\x0f\x31\x36\x30\x31\x30\x31\x30\x31\x30\x30\x30"
297 "\x30\x30\x30\x5a\x18\x0f\x31\x36\x30\x31\x30\x31\x30\x31\x30\x30\x30\x30\x30"
298 "\x30\x5a\x30\x15\x31\x13\x30\x11\x06\x03\x55\x04\x03\x13\x0a\x41\x6c\x65\x78"
299 "\x20\x4c\x61\x6e\x67\x00\x30\x07\x30\x02\x06\x00\x03\x01\x00\xa3\x16\x30\x14"
300 "\x30\x12\x06\x03\x55\x1d\x13\x01\x01\xff\x04\x08\x30\x06\x01\x01\xff\x02\x01"
301 "\x01";
303 static void testCollectionStore(void)
305 HCERTSTORE store1, store2, collection, collection2;
306 PCCERT_CONTEXT context;
307 BOOL ret;
309 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
310 CERT_STORE_CREATE_NEW_FLAG, NULL);
312 /* Try adding a cert to any empty collection */
313 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING,
314 bigCert, sizeof(bigCert) - 1, CERT_STORE_ADD_ALWAYS, NULL);
315 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED),
316 "Expected HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), got %08lx\n",
317 GetLastError());
319 /* Create and add a cert to a memory store */
320 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
321 CERT_STORE_CREATE_NEW_FLAG, NULL);
322 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
323 bigCert, sizeof(bigCert) - 1, CERT_STORE_ADD_ALWAYS, NULL);
324 ok(ret, "CertAddEncodedCertificateToStore failed: %08lx\n", GetLastError());
325 /* Add the memory store to the collection, without allowing adding */
326 ret = CertAddStoreToCollection(collection, store1, 0, 0);
327 ok(ret, "CertAddStoreToCollection failed: %08lx\n", GetLastError());
328 /* Verify the cert is in the collection */
329 context = CertEnumCertificatesInStore(collection, NULL);
330 ok(context != NULL, "Expected a valid context\n");
331 if (context)
333 ok(context->hCertStore == collection, "Unexpected store\n");
334 CertFreeCertificateContext(context);
336 /* Check that adding to the collection isn't allowed */
337 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING,
338 bigCert2, sizeof(bigCert2) - 1, CERT_STORE_ADD_ALWAYS, NULL);
339 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED),
340 "Expected HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), got %08lx\n",
341 GetLastError());
343 /* Create a new memory store */
344 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
345 CERT_STORE_CREATE_NEW_FLAG, NULL);
346 /* Try adding a store to a non-collection store */
347 ret = CertAddStoreToCollection(store1, store2,
348 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
349 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
350 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
351 GetLastError());
352 /* Try adding some bogus stores */
353 /* This crashes in Windows
354 ret = CertAddStoreToCollection(0, store2,
355 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
357 /* This "succeeds"... */
358 ret = CertAddStoreToCollection(collection, 0,
359 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
360 ok(ret, "CertAddStoreToCollection failed: %08lx\n", GetLastError());
361 /* while this crashes.
362 ret = CertAddStoreToCollection(collection, 1,
363 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
366 /* Add it to the collection, this time allowing adding */
367 ret = CertAddStoreToCollection(collection, store2,
368 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
369 ok(ret, "CertAddStoreToCollection failed: %08lx\n", GetLastError());
370 /* Check that adding to the collection is allowed */
371 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING,
372 bigCert2, sizeof(bigCert2) - 1, CERT_STORE_ADD_ALWAYS, NULL);
373 ok(ret, "CertAddEncodedCertificateToStore failed: %08lx\n", GetLastError());
374 /* Now check that it was actually added to store2 */
375 context = CertEnumCertificatesInStore(store2, NULL);
376 ok(context != NULL, "Expected a valid context\n");
377 if (context)
379 ok(context->hCertStore == store2, "Unexpected store\n");
380 CertFreeCertificateContext(context);
382 /* Check that the collection has both bigCert and bigCert2. bigCert comes
383 * first because store1 was added first.
385 context = CertEnumCertificatesInStore(collection, NULL);
386 ok(context != NULL, "Expected a valid context\n");
387 if (context)
389 ok(context->hCertStore == collection, "Unexpected store\n");
390 ok(context->cbCertEncoded == sizeof(bigCert) - 1,
391 "Expected size %d, got %ld\n", sizeof(bigCert) - 1,
392 context->cbCertEncoded);
393 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded),
394 "Unexpected cert\n");
395 context = CertEnumCertificatesInStore(collection, context);
396 ok(context != NULL, "Expected a valid context\n");
397 if (context)
399 ok(context->hCertStore == collection, "Unexpected store\n");
400 ok(context->cbCertEncoded == sizeof(bigCert2) - 1,
401 "Expected size %d, got %ld\n", sizeof(bigCert2) - 1,
402 context->cbCertEncoded);
403 ok(!memcmp(context->pbCertEncoded, bigCert2,
404 context->cbCertEncoded), "Unexpected cert\n");
405 context = CertEnumCertificatesInStore(collection, context);
406 ok(!context, "Unexpected cert\n");
409 /* close store2, and check that the collection is unmodified */
410 CertCloseStore(store2, 0);
411 context = CertEnumCertificatesInStore(collection, NULL);
412 ok(context != NULL, "Expected a valid context\n");
413 if (context)
415 ok(context->hCertStore == collection, "Unexpected store\n");
416 ok(context->cbCertEncoded == sizeof(bigCert) - 1,
417 "Expected size %d, got %ld\n", sizeof(bigCert) - 1,
418 context->cbCertEncoded);
419 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded),
420 "Unexpected cert\n");
421 context = CertEnumCertificatesInStore(collection, context);
422 ok(context != NULL, "Expected a valid context\n");
423 if (context)
425 ok(context->hCertStore == collection, "Unexpected store\n");
426 ok(context->cbCertEncoded == sizeof(bigCert2) - 1,
427 "Expected size %d, got %ld\n", sizeof(bigCert2) - 1,
428 context->cbCertEncoded);
429 ok(!memcmp(context->pbCertEncoded, bigCert2,
430 context->cbCertEncoded), "Unexpected cert\n");
431 context = CertEnumCertificatesInStore(collection, context);
432 ok(!context, "Unexpected cert\n");
436 /* Adding a collection to a collection is legal */
437 collection2 = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
438 CERT_STORE_CREATE_NEW_FLAG, NULL);
439 ret = CertAddStoreToCollection(collection2, collection,
440 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
441 ok(ret, "CertAddStoreToCollection failed: %08lx\n", GetLastError());
442 /* check the contents of collection2 */
443 context = CertEnumCertificatesInStore(collection2, NULL);
444 ok(context != NULL, "Expected a valid context\n");
445 if (context)
447 ok(context->hCertStore == collection2, "Unexpected store\n");
448 ok(context->cbCertEncoded == sizeof(bigCert) - 1,
449 "Expected size %d, got %ld\n", sizeof(bigCert) - 1,
450 context->cbCertEncoded);
451 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded),
452 "Unexpected cert\n");
453 context = CertEnumCertificatesInStore(collection2, context);
454 ok(context != NULL, "Expected a valid context\n");
455 if (context)
457 ok(context->hCertStore == collection2, "Unexpected store\n");
458 ok(context->cbCertEncoded == sizeof(bigCert2) - 1,
459 "Expected size %d, got %ld\n", sizeof(bigCert2) - 1,
460 context->cbCertEncoded);
461 ok(!memcmp(context->pbCertEncoded, bigCert2,
462 context->cbCertEncoded), "Unexpected cert\n");
463 context = CertEnumCertificatesInStore(collection2, context);
464 ok(!context, "Unexpected cert\n");
468 /* I'd like to test closing the collection in the middle of enumeration,
469 * but my tests have been inconsistent. The first time calling
470 * CertEnumCertificatesInStore on a closed collection succeeded, while the
471 * second crashed. So anything appears to be fair game.
472 * I'd also like to test removing a store from a collection in the middle
473 * of an enumeration, but my tests in Windows have been inconclusive.
474 * In one scenario it worked. In another scenario, about a third of the
475 * time this leads to "random" crashes elsewhere in the code. This
476 * probably means this is not allowed.
479 CertCloseStore(store1, 0);
480 CertCloseStore(collection, 0);
481 CertCloseStore(collection2, 0);
483 /* Add the same cert to two memory stores, then put them in a collection */
484 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
485 CERT_STORE_CREATE_NEW_FLAG, NULL);
486 ok(store1 != 0, "CertOpenStore failed: %08lx\n", GetLastError());
487 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
488 CERT_STORE_CREATE_NEW_FLAG, NULL);
489 ok(store2 != 0, "CertOpenStore failed: %08lx\n", GetLastError());
491 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
492 bigCert, sizeof(bigCert) - 1, CERT_STORE_ADD_ALWAYS, NULL);
493 ok(ret, "CertAddEncodedCertificateToStore failed: %08lx\n", GetLastError());
494 ret = CertAddEncodedCertificateToStore(store2, X509_ASN_ENCODING,
495 bigCert, sizeof(bigCert) - 1, CERT_STORE_ADD_ALWAYS, NULL);
496 ok(ret, "CertAddEncodedCertificateToStore failed: %08lx\n", GetLastError());
497 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
498 CERT_STORE_CREATE_NEW_FLAG, NULL);
499 ok(collection != 0, "CertOpenStore failed: %08lx\n", GetLastError());
501 ret = CertAddStoreToCollection(collection, store1,
502 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
503 ok(ret, "CertAddStoreToCollection failed: %08lx\n", GetLastError());
504 ret = CertAddStoreToCollection(collection, store2,
505 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
506 ok(ret, "CertAddStoreToCollection failed: %08lx\n", GetLastError());
508 /* Check that the collection has two copies of the same cert */
509 context = CertEnumCertificatesInStore(collection, NULL);
510 ok(context != NULL, "Expected a valid context\n");
511 if (context)
513 ok(context->hCertStore == collection, "Unexpected store\n");
514 ok(context->cbCertEncoded == sizeof(bigCert) - 1,
515 "Expected size %d, got %ld\n", sizeof(bigCert) - 1,
516 context->cbCertEncoded);
517 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded),
518 "Unexpected cert\n");
519 context = CertEnumCertificatesInStore(collection, context);
520 ok(context != NULL, "Expected a valid context\n");
521 if (context)
523 ok(context->hCertStore == collection, "Unexpected store\n");
524 ok(context->cbCertEncoded == sizeof(bigCert) - 1,
525 "Expected size %d, got %ld\n", sizeof(bigCert) - 1,
526 context->cbCertEncoded);
527 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded),
528 "Unexpected cert\n");
529 context = CertEnumCertificatesInStore(collection, context);
530 ok(context == NULL, "Unexpected cert\n");
534 /* The following would check whether I can delete an identical cert, rather
535 * than one enumerated from the store. It crashes, so that means I must
536 * only call CertDeleteCertificateFromStore with contexts enumerated from
537 * the store.
538 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
539 sizeof(bigCert) - 1);
540 ok(context != NULL, "CertCreateCertificateContext failed: %08lx\n",
541 GetLastError());
542 if (context)
544 ret = CertDeleteCertificateFromStore(collection, context);
545 printf("ret is %d, GetLastError is %08lx\n", ret, GetLastError());
546 CertFreeCertificateContext(context);
550 /* Now check deleting from the collection. */
551 context = CertEnumCertificatesInStore(collection, NULL);
552 ok(context != NULL, "Expected a valid context\n");
553 if (context)
555 CertDeleteCertificateFromStore(context);
556 /* store1 should now be empty */
557 context = CertEnumCertificatesInStore(store1, NULL);
558 ok(!context, "Unexpected cert\n");
559 /* and there should be one certificate in the collection */
560 context = CertEnumCertificatesInStore(collection, NULL);
561 ok(context != NULL, "Expected a valid cert\n");
562 if (context)
564 ok(context->hCertStore == collection, "Unexpected store\n");
565 ok(context->cbCertEncoded == sizeof(bigCert) - 1,
566 "Expected size %d, got %ld\n", sizeof(bigCert) - 1,
567 context->cbCertEncoded);
568 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded),
569 "Unexpected cert\n");
571 context = CertEnumCertificatesInStore(collection, context);
572 ok(context == NULL, "Unexpected cert\n");
575 /* Finally, test removing stores from the collection. No return value, so
576 * it's a bit funny to test.
578 /* This crashes
579 CertRemoveStoreFromCollection(NULL, NULL);
581 /* This "succeeds," no crash, no last error set */
582 SetLastError(0xdeadbeef);
583 CertRemoveStoreFromCollection(store2, collection);
584 ok(GetLastError() == 0xdeadbeef,
585 "Didn't expect an error to be set: %08lx\n", GetLastError());
587 /* After removing store2, the collection should be empty */
588 SetLastError(0xdeadbeef);
589 CertRemoveStoreFromCollection(collection, store2);
590 ok(GetLastError() == 0xdeadbeef,
591 "Didn't expect an error to be set: %08lx\n", GetLastError());
592 context = CertEnumCertificatesInStore(collection, NULL);
593 ok(!context, "Unexpected cert\n");
595 CertCloseStore(collection, 0);
596 CertCloseStore(store2, 0);
597 CertCloseStore(store1, 0);
600 /* Looks for the property with ID propID in the buffer buf. Returns a pointer
601 * to its header if found, NULL if not.
603 static const struct CertPropIDHeader *findPropID(const BYTE *buf, DWORD size,
604 DWORD propID)
606 const struct CertPropIDHeader *ret = NULL;
607 BOOL failed = FALSE;
609 while (size && !ret && !failed)
611 if (size < sizeof(struct CertPropIDHeader))
612 failed = TRUE;
613 else
615 const struct CertPropIDHeader *hdr =
616 (const struct CertPropIDHeader *)buf;
618 size -= sizeof(struct CertPropIDHeader);
619 buf += sizeof(struct CertPropIDHeader);
620 if (size < hdr->cb)
621 failed = TRUE;
622 else if (hdr->propID == propID)
623 ret = hdr;
624 else
626 buf += hdr->cb;
627 size -= hdr->cb;
631 return ret;
634 typedef DWORD (WINAPI *SHDeleteKeyAFunc)(HKEY, LPCSTR);
636 static void testRegStore(void)
638 static const char tempKey[] = "Software\\Wine\\CryptTemp";
639 HCERTSTORE store;
640 LONG rc;
641 HKEY key = NULL;
642 DWORD disp;
644 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 0, NULL);
645 ok(!store && GetLastError() == ERROR_INVALID_HANDLE,
646 "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
647 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 0, key);
648 ok(!store && GetLastError() == ERROR_INVALID_HANDLE,
649 "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
651 /* Opening up any old key works.. */
652 key = HKEY_CURRENT_USER;
653 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 0, key);
654 /* Not sure if this is a bug in DuplicateHandle, marking todo_wine for now
656 todo_wine ok(store != 0, "CertOpenStore failed: %08lx\n", GetLastError());
657 CertCloseStore(store, 0);
659 rc = RegCreateKeyExA(HKEY_CURRENT_USER, tempKey, 0, NULL, 0, KEY_ALL_ACCESS,
660 NULL, &key, NULL);
661 ok(!rc, "RegCreateKeyExA failed: %ld\n", rc);
662 if (key)
664 BOOL ret;
665 BYTE hash[20];
666 DWORD size, i;
667 static const char certificates[] = "Certificates\\";
668 char subKeyName[sizeof(certificates) + 20 * 2 + 1], *ptr;
669 HKEY subKey;
670 PCCERT_CONTEXT context;
672 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 0, key);
673 ok(store != 0, "CertOpenStore failed: %08lx\n", GetLastError());
674 /* Add a certificate. It isn't persisted right away, since it's only
675 * added to the cache..
677 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
678 bigCert2, sizeof(bigCert2) - 1, CERT_STORE_ADD_ALWAYS, NULL);
679 ok(ret, "CertAddEncodedCertificateToStore failed: %08lx\n",
680 GetLastError());
681 /* so flush the cache to force a commit.. */
682 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL);
683 ok(ret, "CertControlStore failed: %08lx\n", GetLastError());
684 /* and check that the expected subkey was written. */
685 size = sizeof(hash);
686 ret = CryptHashCertificate(0, 0, 0, bigCert2, sizeof(bigCert2) - 1,
687 hash, &size);
688 ok(ret, "CryptHashCertificate failed: %ld\n", GetLastError());
689 strcpy(subKeyName, certificates);
690 for (i = 0, ptr = subKeyName + sizeof(certificates) - 1; i < size;
691 i++, ptr += 2)
692 sprintf(ptr, "%02X", hash[i]);
693 rc = RegCreateKeyExA(key, subKeyName, 0, NULL, 0, KEY_ALL_ACCESS, NULL,
694 &subKey, NULL);
695 ok(!rc, "RegCreateKeyExA failed: %ld\n", rc);
696 if (subKey)
698 LPBYTE buf;
700 size = 0;
701 RegQueryValueExA(subKey, "Blob", NULL, NULL, NULL, &size);
702 buf = HeapAlloc(GetProcessHeap(), 0, size);
703 if (buf)
705 rc = RegQueryValueExA(subKey, "Blob", NULL, NULL, buf, &size);
706 ok(!rc, "RegQueryValueExA failed: %ld\n", rc);
707 if (!rc)
709 const struct CertPropIDHeader *hdr;
711 /* Both the hash and the cert should be present */
712 hdr = findPropID(buf, size, CERT_CERT_PROP_ID);
713 ok(hdr != NULL, "Expected to find a cert property\n");
714 if (hdr)
716 ok(hdr->cb == sizeof(bigCert2) - 1,
717 "Unexpected size %ld of cert property, expected %d\n",
718 hdr->cb, sizeof(bigCert2) - 1);
719 ok(!memcmp((BYTE *)hdr + sizeof(*hdr), bigCert2,
720 hdr->cb), "Unexpected cert in cert property\n");
722 hdr = findPropID(buf, size, CERT_HASH_PROP_ID);
723 ok(hdr != NULL, "Expected to find a hash property\n");
724 if (hdr)
726 ok(hdr->cb == sizeof(hash),
727 "Unexpected size %ld of hash property, expected %d\n",
728 hdr->cb, sizeof(hash));
729 ok(!memcmp((BYTE *)hdr + sizeof(*hdr), hash,
730 hdr->cb), "Unexpected hash in cert property\n");
733 HeapFree(GetProcessHeap(), 0, buf);
735 RegCloseKey(subKey);
738 /* Remove the existing context */
739 context = CertEnumCertificatesInStore(store, NULL);
740 ok(context != NULL, "Expected a cert context\n");
741 if (context)
742 CertDeleteCertificateFromStore(context);
743 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL);
744 ok(ret, "CertControlStore failed: %08lx\n", GetLastError());
746 /* Add a serialized cert with a bogus hash directly to the registry */
747 memset(hash, 0, sizeof(hash));
748 strcpy(subKeyName, certificates);
749 for (i = 0, ptr = subKeyName + sizeof(certificates) - 1;
750 i < sizeof(hash); i++, ptr += 2)
751 sprintf(ptr, "%02X", hash[i]);
752 rc = RegCreateKeyExA(key, subKeyName, 0, NULL, 0, KEY_ALL_ACCESS, NULL,
753 &subKey, NULL);
754 ok(!rc, "RegCreateKeyExA failed: %ld\n", rc);
755 if (subKey)
757 BYTE buf[sizeof(struct CertPropIDHeader) * 2 + sizeof(hash) +
758 sizeof(bigCert) - 1], *ptr;
759 DWORD certCount = 0;
760 struct CertPropIDHeader *hdr;
762 hdr = (struct CertPropIDHeader *)buf;
763 hdr->propID = CERT_HASH_PROP_ID;
764 hdr->unknown1 = 1;
765 hdr->cb = sizeof(hash);
766 ptr = buf + sizeof(*hdr);
767 memcpy(ptr, hash, sizeof(hash));
768 ptr += sizeof(hash);
769 hdr = (struct CertPropIDHeader *)ptr;
770 hdr->propID = CERT_CERT_PROP_ID;
771 hdr->unknown1 = 1;
772 hdr->cb = sizeof(bigCert) - 1;
773 ptr += sizeof(*hdr);
774 memcpy(ptr, bigCert, sizeof(bigCert) - 1);
776 rc = RegSetValueExA(subKey, "Blob", 0, REG_BINARY, buf,
777 sizeof(buf));
778 ok(!rc, "RegSetValueExA failed: %ld\n", rc);
780 ret = CertControlStore(store, 0, CERT_STORE_CTRL_RESYNC, NULL);
781 ok(ret, "CertControlStore failed: %08lx\n", GetLastError());
783 /* Make sure the bogus hash cert gets loaded. */
784 certCount = 0;
785 context = NULL;
786 do {
787 context = CertEnumCertificatesInStore(store, context);
788 if (context)
789 certCount++;
790 } while (context != NULL);
791 ok(certCount == 1, "Expected 1 certificates, got %ld\n", certCount);
793 RegCloseKey(subKey);
796 /* Add another serialized cert directly to the registry, this time
797 * under the correct key name (named with the correct hash value).
799 size = sizeof(hash);
800 ret = CryptHashCertificate(0, 0, 0, bigCert2,
801 sizeof(bigCert2) - 1, hash, &size);
802 ok(ret, "CryptHashCertificate failed: %ld\n", GetLastError());
803 strcpy(subKeyName, certificates);
804 for (i = 0, ptr = subKeyName + sizeof(certificates) - 1;
805 i < sizeof(hash); i++, ptr += 2)
806 sprintf(ptr, "%02X", hash[i]);
807 rc = RegCreateKeyExA(key, subKeyName, 0, NULL, 0, KEY_ALL_ACCESS, NULL,
808 &subKey, NULL);
809 ok(!rc, "RegCreateKeyExA failed: %ld\n", rc);
810 if (subKey)
812 BYTE buf[sizeof(struct CertPropIDHeader) * 2 + sizeof(hash) +
813 sizeof(bigCert2) - 1], *ptr;
814 DWORD certCount = 0;
815 PCCERT_CONTEXT context;
816 struct CertPropIDHeader *hdr;
818 /* First try with a bogus hash... */
819 hdr = (struct CertPropIDHeader *)buf;
820 hdr->propID = CERT_HASH_PROP_ID;
821 hdr->unknown1 = 1;
822 hdr->cb = sizeof(hash);
823 ptr = buf + sizeof(*hdr);
824 memset(ptr, 0, sizeof(hash));
825 ptr += sizeof(hash);
826 hdr = (struct CertPropIDHeader *)ptr;
827 hdr->propID = CERT_CERT_PROP_ID;
828 hdr->unknown1 = 1;
829 hdr->cb = sizeof(bigCert2) - 1;
830 ptr += sizeof(*hdr);
831 memcpy(ptr, bigCert2, sizeof(bigCert2) - 1);
833 rc = RegSetValueExA(subKey, "Blob", 0, REG_BINARY, buf,
834 sizeof(buf));
835 ok(!rc, "RegSetValueExA failed: %ld\n", rc);
837 ret = CertControlStore(store, 0, CERT_STORE_CTRL_RESYNC, NULL);
838 ok(ret, "CertControlStore failed: %08lx\n", GetLastError());
840 /* and make sure just one cert still gets loaded. */
841 certCount = 0;
842 context = NULL;
843 do {
844 context = CertEnumCertificatesInStore(store, context);
845 if (context)
846 certCount++;
847 } while (context != NULL);
848 ok(certCount == 1, "Expected 1 certificates, got %ld\n", certCount);
850 /* Try again with the correct hash... */
851 ptr = buf + sizeof(*hdr);
852 memcpy(ptr, hash, sizeof(hash));
854 rc = RegSetValueExA(subKey, "Blob", 0, REG_BINARY, buf,
855 sizeof(buf));
856 ok(!rc, "RegSetValueExA failed: %ld\n", rc);
858 ret = CertControlStore(store, 0, CERT_STORE_CTRL_RESYNC, NULL);
859 ok(ret, "CertControlStore failed: %08lx\n", GetLastError());
861 /* and make sure two certs get loaded. */
862 certCount = 0;
863 context = NULL;
864 do {
865 context = CertEnumCertificatesInStore(store, context);
866 if (context)
867 certCount++;
868 } while (context != NULL);
869 ok(certCount == 2, "Expected 2 certificates, got %ld\n", certCount);
871 RegCloseKey(subKey);
873 CertCloseStore(store, 0);
874 /* Is delete allowed on a reg store? */
875 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0,
876 CERT_STORE_DELETE_FLAG, key);
877 ok(store == NULL, "Expected NULL return from CERT_STORE_DELETE_FLAG\n");
878 ok(GetLastError() == 0, "CertOpenStore failed: %08lx\n",
879 GetLastError());
881 RegCloseKey(key);
883 /* The CertOpenStore with CERT_STORE_DELETE_FLAG above will delete the
884 * contents of the key, but not the key itself.
886 rc = RegCreateKeyExA(HKEY_CURRENT_USER, tempKey, 0, NULL, 0, KEY_ALL_ACCESS,
887 NULL, &key, &disp);
888 ok(!rc, "RegCreateKeyExA failed: %ld\n", rc);
889 ok(disp == REG_OPENED_EXISTING_KEY,
890 "Expected REG_OPENED_EXISTING_KEY, got %ld\n", disp);
891 if (!rc)
893 RegCloseKey(key);
894 rc = RegDeleteKeyA(HKEY_CURRENT_USER, tempKey);
895 if (rc)
897 HMODULE shlwapi = LoadLibraryA("shlwapi");
899 /* Use shlwapi's SHDeleteKeyA to _really_ blow away the key,
900 * otherwise subsequent tests will fail.
902 if (shlwapi)
904 SHDeleteKeyAFunc pSHDeleteKeyA =
905 (SHDeleteKeyAFunc)GetProcAddress(shlwapi, "SHDeleteKeyA");
907 if (pSHDeleteKeyA)
908 pSHDeleteKeyA(HKEY_CURRENT_USER, tempKey);
909 FreeLibrary(shlwapi);
915 static const char MyA[] = { 'M','y',0,0 };
916 static const WCHAR MyW[] = { 'M','y',0 };
917 static const WCHAR BogusW[] = { 'B','o','g','u','s',0 };
918 static const WCHAR BogusPathW[] = { 'S','o','f','t','w','a','r','e','\\',
919 'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m','C','e','r',
920 't','i','f','i','c','a','t','e','s','\\','B','o','g','u','s',0 };
922 static void testSystemRegStore(void)
924 HCERTSTORE store, memStore;
926 /* Check with a UNICODE name */
927 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
928 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, MyW);
929 /* Not all OSes support CERT_STORE_PROV_SYSTEM_REGISTRY, so don't continue
930 * testing if they don't.
932 if (!store)
933 return;
935 /* Check that it isn't a collection store */
936 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
937 CERT_STORE_CREATE_NEW_FLAG, NULL);
938 if (memStore)
940 BOOL ret = CertAddStoreToCollection(store, memStore, 0, 0);
942 ok(!ret && GetLastError() ==
943 HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
944 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
945 GetLastError());
946 CertCloseStore(memStore, 0);
948 CertCloseStore(store, 0);
950 /* Check opening a bogus store */
951 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
952 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, BogusW);
953 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
954 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
955 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
956 CERT_SYSTEM_STORE_CURRENT_USER, BogusW);
957 ok(store != 0, "CertOpenStore failed: %08lx\n", GetLastError());
958 if (store)
959 CertCloseStore(store, 0);
960 /* Now check whether deleting is allowed */
961 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
962 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, BogusW);
963 RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW);
965 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, 0, NULL);
966 ok(!store && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
967 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
968 GetLastError());
969 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
970 CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_SYSTEM_STORE_CURRENT_USER, MyA);
971 ok(!store && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
972 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
973 GetLastError());
974 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
975 CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_SYSTEM_STORE_CURRENT_USER, MyW);
976 ok(!store && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
977 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
978 GetLastError());
979 /* The name is expected to be UNICODE, check with an ASCII name */
980 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
981 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, MyA);
982 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
983 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
986 static void testSystemStore(void)
988 static const WCHAR baskslashW[] = { '\\',0 };
989 HCERTSTORE store;
990 WCHAR keyName[MAX_PATH];
991 HKEY key;
992 LONG rc;
994 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, 0, NULL);
995 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
996 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
997 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
998 CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_SYSTEM_STORE_CURRENT_USER, MyA);
999 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1000 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
1001 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1002 CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_SYSTEM_STORE_CURRENT_USER, MyW);
1003 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1004 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
1005 /* The name is expected to be UNICODE, first check with an ASCII name */
1006 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1007 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, MyA);
1008 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1009 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
1010 /* Create the expected key */
1011 lstrcpyW(keyName, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH);
1012 lstrcatW(keyName, baskslashW);
1013 lstrcatW(keyName, MyW);
1014 rc = RegCreateKeyExW(HKEY_CURRENT_USER, keyName, 0, NULL, 0, KEY_READ,
1015 NULL, &key, NULL);
1016 ok(!rc, "RegCreateKeyEx failed: %ld\n", rc);
1017 if (!rc)
1018 RegCloseKey(key);
1019 /* Check opening with a UNICODE name, specifying the create new flag */
1020 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1021 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_CREATE_NEW_FLAG, MyW);
1022 ok(!store && GetLastError() == ERROR_FILE_EXISTS,
1023 "Expected ERROR_FILE_EXISTS, got %08lx\n", GetLastError());
1024 /* Now check opening with a UNICODE name, this time opening existing */
1025 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1026 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, MyW);
1027 ok(store != 0, "CertOpenStore failed: %08lx\n", GetLastError());
1028 if (store)
1030 HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1031 CERT_STORE_CREATE_NEW_FLAG, NULL);
1033 /* Check that it's a collection store */
1034 if (memStore)
1036 BOOL ret = CertAddStoreToCollection(store, memStore, 0, 0);
1038 /* FIXME: this'll fail on NT4, but what error will it give? */
1039 ok(ret, "CertAddStoreToCollection failed: %08lx\n", GetLastError());
1040 CertCloseStore(memStore, 0);
1042 CertCloseStore(store, 0);
1045 /* Check opening a bogus store */
1046 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1047 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, BogusW);
1048 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1049 "Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
1050 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1051 CERT_SYSTEM_STORE_CURRENT_USER, BogusW);
1052 ok(store != 0, "CertOpenStore failed: %08lx\n", GetLastError());
1053 if (store)
1054 CertCloseStore(store, 0);
1055 /* Now check whether deleting is allowed */
1056 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1057 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, BogusW);
1058 RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW);
1061 static void testCertOpenSystemStore(void)
1063 HCERTSTORE store;
1065 store = CertOpenSystemStoreW(0, NULL);
1066 ok(!store && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1067 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1068 GetLastError());
1069 /* This succeeds, and on WinXP at least, the Bogus key is created under
1070 * HKCU (but not under HKLM, even when run as an administrator.)
1072 store = CertOpenSystemStoreW(0, BogusW);
1073 ok(store != 0, "CertOpenSystemStore failed: %08lx\n", GetLastError());
1074 if (store)
1075 CertCloseStore(store, 0);
1076 /* Delete it so other tests succeed next time around */
1077 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1078 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, BogusW);
1079 RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW);
1082 static void testCertProperties(void)
1084 PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
1085 bigCert, sizeof(bigCert) - 1);
1087 ok(context != NULL, "CertCreateCertificateContext failed: %08lx\n",
1088 GetLastError());
1089 if (context)
1091 DWORD propID, numProps, access, size;
1092 BOOL ret;
1093 BYTE hash[20] = { 0 }, hashProperty[20];
1094 CRYPT_DATA_BLOB blob;
1096 /* This crashes
1097 propID = CertEnumCertificateContextProperties(NULL, 0);
1100 propID = 0;
1101 numProps = 0;
1102 do {
1103 propID = CertEnumCertificateContextProperties(context, propID);
1104 if (propID)
1105 numProps++;
1106 } while (propID != 0);
1107 ok(numProps == 0, "Expected 0 properties, got %ld\n", numProps);
1109 /* Tests with a NULL cert context. Prop ID 0 fails.. */
1110 ret = CertSetCertificateContextProperty(NULL, 0, 0, NULL);
1111 ok(!ret && GetLastError() ==
1112 HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1113 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1114 GetLastError());
1115 /* while this just crashes.
1116 ret = CertSetCertificateContextProperty(NULL,
1117 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
1120 ret = CertSetCertificateContextProperty(context, 0, 0, NULL);
1121 ok(!ret && GetLastError() ==
1122 HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1123 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1124 GetLastError());
1125 /* Can't set the cert property directly, this crashes.
1126 ret = CertSetCertificateContextProperty(context,
1127 CERT_CERT_PROP_ID, 0, bigCert2);
1130 /* This crashes.
1131 ret = CertGetCertificateContextProperty(context,
1132 CERT_ACCESS_STATE_PROP_ID, 0, NULL);
1134 size = sizeof(access);
1135 ret = CertGetCertificateContextProperty(context,
1136 CERT_ACCESS_STATE_PROP_ID, &access, &size);
1137 ok(ret, "CertGetCertificateContextProperty failed: %08lx\n",
1138 GetLastError());
1139 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
1140 "Didn't expect a persisted cert\n");
1141 /* Trying to set this "read only" property crashes.
1142 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
1143 ret = CertSetCertificateContextProperty(context,
1144 CERT_ACCESS_STATE_PROP_ID, 0, &access);
1147 /* Can I set the hash to an invalid hash? */
1148 blob.pbData = hash;
1149 blob.cbData = sizeof(hash);
1150 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
1151 &blob);
1152 ok(ret, "CertSetCertificateContextProperty failed: %08lx\n",
1153 GetLastError());
1154 size = sizeof(hashProperty);
1155 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
1156 hashProperty, &size);
1157 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
1158 /* Delete the (bogus) hash, and get the real one */
1159 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
1160 NULL);
1161 ok(ret, "CertSetCertificateContextProperty failed: %08lx\n",
1162 GetLastError());
1163 size = sizeof(hash);
1164 ret = CryptHashCertificate(0, 0, 0, bigCert, sizeof(bigCert) - 1,
1165 hash, &size);
1166 ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError());
1167 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
1168 hashProperty, &size);
1169 ok(ret, "CertGetCertificateContextProperty failed: %08lx\n",
1170 GetLastError());
1171 ok(!memcmp(hash, hashProperty, sizeof(hash)), "Unexpected hash\n");
1173 /* Now that the hash property is set, we should get one property when
1174 * enumerating.
1176 propID = 0;
1177 numProps = 0;
1178 do {
1179 propID = CertEnumCertificateContextProperties(context, propID);
1180 if (propID)
1181 numProps++;
1182 } while (propID != 0);
1183 ok(numProps == 1, "Expected 1 properties, got %ld\n", numProps);
1185 CertFreeCertificateContext(context);
1189 static void testAddSerialized(void)
1191 BOOL ret;
1192 HCERTSTORE store;
1193 BYTE buf[sizeof(struct CertPropIDHeader) * 2 + 20 + sizeof(bigCert) - 1] =
1194 { 0 };
1195 BYTE hash[20];
1196 struct CertPropIDHeader *hdr;
1197 PCCERT_CONTEXT context;
1199 ret = CertAddSerializedElementToStore(0, NULL, 0, 0, 0, 0, NULL, NULL);
1200 ok(!ret && GetLastError() == ERROR_END_OF_MEDIA,
1201 "Expected ERROR_END_OF_MEDIA, got %08lx\n", GetLastError());
1203 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1204 CERT_STORE_CREATE_NEW_FLAG, NULL);
1205 ok(store != 0, "CertOpenStore failed: %08lx\n", GetLastError());
1207 ret = CertAddSerializedElementToStore(store, NULL, 0, 0, 0, 0, NULL, NULL);
1208 ok(!ret && GetLastError() == ERROR_END_OF_MEDIA,
1209 "Expected ERROR_END_OF_MEDIA, got %08lx\n", GetLastError());
1211 /* Test with an empty property */
1212 hdr = (struct CertPropIDHeader *)buf;
1213 hdr->propID = CERT_CERT_PROP_ID;
1214 hdr->unknown1 = 1;
1215 hdr->cb = 0;
1216 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0, 0,
1217 NULL, NULL);
1218 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1219 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1220 GetLastError());
1221 /* Test with a bad size in property header */
1222 hdr->cb = sizeof(bigCert) - 2;
1223 memcpy(buf + sizeof(struct CertPropIDHeader), bigCert, sizeof(bigCert) - 1);
1224 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0, 0,
1225 NULL, NULL);
1226 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1227 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1228 GetLastError());
1229 ret = CertAddSerializedElementToStore(store, buf,
1230 sizeof(struct CertPropIDHeader) + sizeof(bigCert) - 1, 0, 0, 0, NULL,
1231 NULL);
1232 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1233 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1234 GetLastError());
1235 ret = CertAddSerializedElementToStore(store, buf,
1236 sizeof(struct CertPropIDHeader) + sizeof(bigCert) - 1, CERT_STORE_ADD_NEW,
1237 0, 0, NULL, NULL);
1238 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1239 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1240 GetLastError());
1241 /* Kosher size in property header, but no context type */
1242 hdr->cb = sizeof(bigCert) - 1;
1243 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0, 0,
1244 NULL, NULL);
1245 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1246 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1247 GetLastError());
1248 ret = CertAddSerializedElementToStore(store, buf,
1249 sizeof(struct CertPropIDHeader) + sizeof(bigCert) - 1, 0, 0, 0, NULL,
1250 NULL);
1251 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1252 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1253 GetLastError());
1254 ret = CertAddSerializedElementToStore(store, buf,
1255 sizeof(struct CertPropIDHeader) + sizeof(bigCert) - 1, CERT_STORE_ADD_NEW,
1256 0, 0, NULL, NULL);
1257 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1258 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1259 GetLastError());
1260 /* With a bad context type */
1261 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0,
1262 CERT_STORE_CRL_CONTEXT_FLAG, NULL, NULL);
1263 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1264 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1265 GetLastError());
1266 ret = CertAddSerializedElementToStore(store, buf,
1267 sizeof(struct CertPropIDHeader) + sizeof(bigCert) - 1, 0, 0,
1268 CERT_STORE_CRL_CONTEXT_FLAG, NULL, NULL);
1269 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1270 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1271 GetLastError());
1272 ret = CertAddSerializedElementToStore(store, buf,
1273 sizeof(struct CertPropIDHeader) + sizeof(bigCert) - 1, CERT_STORE_ADD_NEW,
1274 0, CERT_STORE_CRL_CONTEXT_FLAG, NULL, NULL);
1275 ok(!ret && GetLastError() == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
1276 "Expected HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got %08lx\n",
1277 GetLastError());
1278 /* Bad unknown field, good type */
1279 hdr->unknown1 = 2;
1280 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0,
1281 CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
1282 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1283 "Expected ERROR_FILE_NOT_FOUND got %08lx\n", GetLastError());
1284 ret = CertAddSerializedElementToStore(store, buf,
1285 sizeof(struct CertPropIDHeader) + sizeof(bigCert) - 1, 0, 0,
1286 CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
1287 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1288 "Expected ERROR_FILE_NOT_FOUND got %08lx\n", GetLastError());
1289 ret = CertAddSerializedElementToStore(store, buf,
1290 sizeof(struct CertPropIDHeader) + sizeof(bigCert) - 1, CERT_STORE_ADD_NEW,
1291 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
1292 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1293 "Expected ERROR_FILE_NOT_FOUND got %08lx\n", GetLastError());
1294 /* Most everything okay, but bad add disposition */
1295 hdr->unknown1 = 1;
1296 /* This crashes
1297 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0,
1298 CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
1299 * as does this
1300 ret = CertAddSerializedElementToStore(store, buf,
1301 sizeof(struct CertPropIDHeader) + sizeof(bigCert) - 1, 0, 0,
1302 CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
1304 /* Everything okay, but buffer's too big */
1305 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf),
1306 CERT_STORE_ADD_NEW, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
1307 ok(ret, "CertAddSerializedElementToStore failed: %08lx\n", GetLastError());
1308 /* Everything okay, check it's not re-added */
1309 ret = CertAddSerializedElementToStore(store, buf,
1310 sizeof(struct CertPropIDHeader) + sizeof(bigCert) - 1, CERT_STORE_ADD_NEW,
1311 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
1312 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
1313 "Expected CRYPT_E_EXISTS, got %08lx\n", GetLastError());
1315 context = CertEnumCertificatesInStore(store, NULL);
1316 ok(context != NULL, "Expected a cert\n");
1317 if (context)
1318 CertDeleteCertificateFromStore(context);
1320 /* Try adding with a bogus hash. Oddly enough, it succeeds, and the hash,
1321 * when queried, is the real hash rather than the bogus hash.
1323 hdr = (struct CertPropIDHeader *)(buf + sizeof(struct CertPropIDHeader) +
1324 sizeof(bigCert) - 1);
1325 hdr->propID = CERT_HASH_PROP_ID;
1326 hdr->unknown1 = 1;
1327 hdr->cb = sizeof(hash);
1328 memset(hash, 0xc, sizeof(hash));
1329 memcpy((LPBYTE)hdr + sizeof(struct CertPropIDHeader), hash, sizeof(hash));
1330 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf),
1331 CERT_STORE_ADD_NEW, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL,
1332 (const void **)&context);
1333 ok(ret, "CertAddSerializedElementToStore failed: %08lx\n", GetLastError());
1334 if (context)
1336 BYTE hashVal[20], realHash[20];
1337 DWORD size = sizeof(hashVal);
1339 ret = CryptHashCertificate(0, 0, 0, bigCert, sizeof(bigCert) - 1,
1340 realHash, &size);
1341 ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError());
1342 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
1343 hashVal, &size);
1344 ok(ret, "CertGetCertificateContextProperty failed: %08lx\n",
1345 GetLastError());
1346 ok(!memcmp(hashVal, realHash, size), "Unexpected hash\n");
1349 CertCloseStore(store, 0);
1352 START_TEST(cert)
1354 testCryptHashCert();
1356 /* various combinations of CertOpenStore */
1357 testMemStore();
1358 testCollectionStore();
1359 testRegStore();
1360 testSystemRegStore();
1361 testSystemStore();
1363 testCertOpenSystemStore();
1365 testCertProperties();
1366 testAddSerialized();