ReactOS 0.4.16-dev-311-g9382aa2
store.c
Go to the documentation of this file.
1/*
2 * crypt32 cert store function tests
3 *
4 * Copyright 2005-2006 Juan Lang
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdio.h>
22#include <stdarg.h>
23
24#include <windef.h>
25#include <winbase.h>
26#include <winuser.h>
27#include <shlobj.h>
28#include <shlwapi.h>
29#include <winreg.h>
30#include <winerror.h>
31#include <wincrypt.h>
32
33#include "wine/test.h"
34
35/* The following aren't defined in wincrypt.h, as they're "reserved" */
36#define CERT_CERT_PROP_ID 32
37#define CERT_CRL_PROP_ID 33
38#define CERT_CTL_PROP_ID 34
39
41{
45};
46
47static const BYTE emptyCert[] = { 0x30, 0x00 };
48static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
49 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
50 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
51 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
52 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
53 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
54 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
55 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
56 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
57 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
58static const BYTE signedBigCert[] = {
59 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
60 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
61 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
62 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
63 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
64 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
65 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
66 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
67 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
68 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
69 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
70 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
71static const BYTE serializedCert[] = { 0x20, 0x00, 0x00, 0x00,
72 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x7a, 0x02, 0x01, 0x01,
73 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
74 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67,
75 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31,
76 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
77 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15,
78 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75,
79 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06,
80 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
81 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
82 0x01, 0x01 };
83static const BYTE signedCRL[] = { 0x30, 0x45, 0x30, 0x2c, 0x30, 0x02, 0x06,
84 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
85 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
86 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
87 0x30, 0x5a, 0x30, 0x02, 0x06, 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c,
88 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
89static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
90 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
91 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
92 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
93 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
94 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
95 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20,
96 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
97 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
98 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
1000x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
1010xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
1020x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
1030x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
1040x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1050x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
1060x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
1070x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
1080x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
1090x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
1100x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
1110x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1120x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
1130x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
1140x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
1150x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
1160x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
1170x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
1180x57,0x6c,0x0b,0x47,0xb8 };
119
120#define test_store_is_empty(store) _test_store_is_empty(__LINE__,store)
121static void _test_store_is_empty(unsigned line, HCERTSTORE store)
122{
123 const CERT_CONTEXT *cert;
124
126 ok_(__FILE__,line)(!cert && GetLastError() == CRYPT_E_NOT_FOUND, "store is not empty\n");
127}
128
129static void testMemStore(void)
130{
131 HCERTSTORE store1, store2;
133 BOOL ret;
134 DWORD GLE;
135
136 /* NULL provider */
137 store1 = CertOpenStore(0, 0, 0, 0, NULL);
138 ok(!store1 && GetLastError() == ERROR_FILE_NOT_FOUND,
139 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
140 /* weird flags */
144 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %d\n", GetLastError());
145
146 /* normal */
149 ok(store1 != NULL, "CertOpenStore failed: %d\n", GetLastError());
150 /* open existing doesn't */
153 ok(store2 != NULL, "CertOpenStore failed: %d\n", GetLastError());
154 ok(store1 != store2, "Expected different stores\n");
155
156 /* add a bogus (empty) cert */
157 context = NULL;
160 /* Windows returns CRYPT_E_ASN1_EOD or OSS_DATA_ERROR, but accept
161 * CRYPT_E_ASN1_CORRUPT as well (because matching errors is tough in this
162 * case)
163 */
164 GLE = GetLastError();
167 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
168 GLE);
169 /* add a "signed" cert--the signature isn't a real signature, so this adds
170 * without any check of the signature's validity
171 */
174 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
175 ok(context != NULL, "Expected a valid cert context\n");
176 if (context)
177 {
178 ok(context->cbCertEncoded == sizeof(signedBigCert),
179 "Wrong cert size %d\n", context->cbCertEncoded);
180 ok(!memcmp(context->pbCertEncoded, signedBigCert,
181 sizeof(signedBigCert)), "Unexpected encoded cert in context\n");
182 /* remove it, the rest of the tests will work on an unsigned cert */
184 ok(ret, "CertDeleteCertificateFromStore failed: %08x\n",
185 GetLastError());
186 }
187 /* try adding a "signed" CRL as a cert */
190 GLE = GetLastError();
193 "Expected CRYPT_E_ASN1_BADTAG or CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
194 GLE);
195 /* add a cert to store1 */
198 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
199 ok(context != NULL, "Expected a valid cert context\n");
200 if (context)
201 {
202 DWORD size;
203 BYTE *buf;
204
205 ok(context->cbCertEncoded == sizeof(bigCert),
206 "Wrong cert size %d\n", context->cbCertEncoded);
207 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)),
208 "Unexpected encoded cert in context\n");
209 ok(context->hCertStore == store1, "Unexpected store\n");
210
211 /* check serializing this element */
212 /* These crash
213 ret = CertSerializeCertificateStoreElement(NULL, 0, NULL, NULL);
214 ret = CertSerializeCertificateStoreElement(context, 0, NULL, NULL);
215 ret = CertSerializeCertificateStoreElement(NULL, 0, NULL, &size);
216 */
217 /* apparently flags are ignored */
219 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
220 GetLastError());
222 if (buf)
223 {
225 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", GetLastError());
226 ok(size == sizeof(serializedCert), "Wrong size %d\n", size);
228 "Unexpected serialized cert\n");
230 }
231
233 ok(ret, "CertFreeCertificateContext failed: %08x\n", GetLastError());
234 }
235 /* verify the cert's in store1 */
237 ok(context != NULL, "Expected a valid context\n");
240 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
241 /* verify store2 (the "open existing" mem store) is still empty */
243 ok(!context, "Expected an empty store\n");
244 /* delete the cert from store1, and check it's empty */
246 if (context)
247 {
248 /* Deleting a bitwise copy crashes with an access to an uninitialized
249 * pointer, so a cert context has some special data out there in memory
250 * someplace
251 CERT_CONTEXT copy;
252 memcpy(&copy, context, sizeof(copy));
253 ret = CertDeleteCertificateFromStore(&copy);
254 */
256
257 ok(copy != NULL, "CertDuplicateCertificateContext failed: %08x\n",
258 GetLastError());
260 ok(ret, "CertDeleteCertificateFromStore failed: %08x\n",
261 GetLastError());
262 /* try deleting a copy */
264 ok(ret, "CertDeleteCertificateFromStore failed: %08x\n",
265 GetLastError());
266 /* check that the store is empty */
268 ok(!context, "Expected an empty store\n");
269 }
270
271 /* close an empty store */
272 ret = CertCloseStore(NULL, 0);
273 ok(ret, "CertCloseStore failed: %d\n", GetLastError());
274 ret = CertCloseStore(store1, 0);
275 ok(ret, "CertCloseStore failed: %d\n", GetLastError());
276 ret = CertCloseStore(store2, 0);
277 ok(ret, "CertCloseStore failed: %d\n", GetLastError());
278
279 /* This seems nonsensical, but you can open a read-only mem store, only
280 * it isn't read-only
281 */
284 ok(store1 != NULL, "CertOpenStore failed: %d\n", GetLastError());
285 /* yep, this succeeds */
288 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
289 ok(context != NULL, "Expected a valid cert context\n");
290 if (context)
291 {
292 ok(context->cbCertEncoded == sizeof(bigCert),
293 "Wrong cert size %d\n", context->cbCertEncoded);
294 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)),
295 "Unexpected encoded cert in context\n");
296 ok(context->hCertStore == store1, "Unexpected store\n");
298 ok(ret, "CertDeleteCertificateFromStore failed: %08x\n",
299 GetLastError());
300 }
301 CertCloseStore(store1, 0);
302}
303
304static void compareStore(HCERTSTORE store, LPCSTR name, const BYTE *pb,
305 DWORD cb, BOOL todo)
306{
307 BOOL ret;
308 CRYPT_DATA_BLOB blob = { 0, NULL };
309
312 ok(ret, "CertSaveStore failed: %08x\n", GetLastError());
314 ok(blob.cbData == cb, "%s: expected size %d, got %d\n", name, cb,
315 blob.cbData);
316 blob.pbData = HeapAlloc(GetProcessHeap(), 0, blob.cbData);
317 if (blob.pbData)
318 {
321 ok(ret, "CertSaveStore failed: %08x\n", GetLastError());
323 ok(!memcmp(pb, blob.pbData, cb), "%s: unexpected value\n", name);
324 HeapFree(GetProcessHeap(), 0, blob.pbData);
325 }
326}
327
329 0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x20,0x00,0x00,0x00,0x01,0x00,0x00,
330 0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
331 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
332 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
333 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
334 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
335 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
336 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
337 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
338 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
339 0x00,0x00,0x00,0x00,0x00,0x00 };
340
341static const struct
342{
350 {'R','O','O','T',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH },
355 /* Adding to HKCU\Root triggers safety warning. */
361
362/* Testing whether system stores are available for adding new certs
363 * and checking directly in the registry whether they are actually saved or deleted.
364 * Windows treats HKCU\My (at least) as a special case and uses AppData directory
365 * for storing certs, not registry.
366 */
367static void testRegStoreSavedCerts(void)
368{
369 static const WCHAR fmt[] =
370 { '%','s','\\','%','s','\\','%','s','\\','%','s',0},
371 ms_certs[] =
372 { 'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m','C','e','r','t','i','f','i','c','a','t','e','s',0},
373 certs[] =
374 {'C','e','r','t','i','f','i','c','a','t','e','s',0},
375 bigCert_hash[] = {
376 '6','E','3','0','9','0','7','1','5','F','D','9','2','3',
377 '5','6','E','B','A','E','2','5','4','0','E','6','2','2',
378 'D','A','1','9','2','6','0','2','A','6','0','8',0};
380 HCERTSTORE store;
381 HANDLE cert_file;
382 HRESULT pathres;
383 WCHAR key_name[MAX_PATH], appdata_path[MAX_PATH];
384 HKEY key;
385 BOOL ret;
386 DWORD res,i;
387
388 for (i = 0; i < ARRAY_SIZE(reg_store_saved_certs); i++)
389 {
390 DWORD err;
391
394
395 err = GetLastError();
396 if (!store)
397 {
398 ok (err == ERROR_ACCESS_DENIED, "Failed to create store at %d (%08x)\n", i, err);
399 skip("Insufficient privileges for the test %d\n", i);
400 continue;
401 }
402 ok (store!=NULL, "Failed to open the store at %d, %x\n", i, GetLastError());
404 ok (cert1 != NULL, "Create cert context failed at %d, %x\n", i, GetLastError());
406 /* Addittional skip per Win7, it allows opening HKLM store, but disallows adding certs */
407 err = GetLastError();
408 if (!ret)
409 {
410 ok (err == ERROR_ACCESS_DENIED, "Failed to add certificate to store at %d (%08x)\n", i, err);
411 skip("Insufficient privileges for the test %d\n", i);
412 continue;
413 }
414 ok (ret, "Adding to the store failed at %d, %x\n", i, err);
416 CertCloseStore(store, 0);
417
419 reg_store_saved_certs[i].store_name, certs, bigCert_hash);
420
422 {
424 ok (!res, "The cert hasn't been saved at %d, %x\n", i, GetLastError());
425 if (!res) RegCloseKey(key);
426 } else
427 {
428 pathres = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, appdata_path);
429 ok (pathres == S_OK,
430 "Failed to get app data path at %d (%x)\n", pathres, GetLastError());
431 if (pathres == S_OK)
432 {
433 PathAppendW(appdata_path, ms_certs);
435 PathAppendW(appdata_path, certs);
436 PathAppendW(appdata_path, bigCert_hash);
437
438 cert_file = CreateFileW(appdata_path, GENERIC_READ, 0, NULL,
440 todo_wine ok (cert_file != INVALID_HANDLE_VALUE,
441 "Cert was not saved in AppData at %d (%x)\n", i, GetLastError());
442 CloseHandle(cert_file);
443 }
444 }
445
446 /* deleting cert from store */
449 ok (store!=NULL, "Failed to open the store at %d, %x\n", i, GetLastError());
450
452 ok (cert1 != NULL, "Create cert context failed at %d, %x\n", i, GetLastError());
453
456 ok (cert2 != NULL, "Failed to find cert in the store at %d, %x\n", i, GetLastError());
457
459 ok (ret, "Failed to delete certificate from store at %d, %x\n", i, GetLastError());
460
463 CertCloseStore(store, 0);
464
466 ok (res, "The cert's registry entry should be absent at %i, %x\n", i, GetLastError());
467 if (!res) RegCloseKey(key);
468
470 {
471 cert_file = CreateFileW(appdata_path, GENERIC_READ, 0, NULL,
473 ok (cert_file == INVALID_HANDLE_VALUE,
474 "Cert should have been absent in AppData %d\n", i);
475
476 CloseHandle(cert_file);
477 }
478 }
479}
480
485static void testStoresInCollection(void)
486{
487 PCCERT_CONTEXT cert1, cert2, tcert1;
488 HCERTSTORE collection, ro_store, rw_store, rw_store_2, tstore;
489 static const WCHAR WineTestRO_W[] = { 'W','i','n','e','T','e','s','t','_','R','O',0 },
490 WineTestRW_W[] = { 'W','i','n','e','T','e','s','t','_','R','W',0 },
491 WineTestRW2_W[]= { 'W','i','n','e','T','e','s','t','_','R','W','2',0 };
492 BOOL ret;
493
496 ok(collection != NULL, "Failed to init collection store, last error %x\n", GetLastError());
497 /* Add read-only store to collection with very high priority*/
499 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRO_W);
500 ok(ro_store != NULL, "Failed to init ro store %x\n", GetLastError());
501
502 ret = CertAddStoreToCollection(collection, ro_store, 0, 1000);
503 ok (ret, "Failed to add read-only store to collection %x\n", GetLastError());
504
506 ok (cert1 != NULL, "Create cert context failed %x\n", GetLastError());
508 ok (!ret, "Added cert to collection with single read-only store %x\n", GetLastError());
509
510 /* Add read-write store to collection with the lowest priority*/
512 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW_W);
513 ok (rw_store != NULL, "Failed to open rw store %x\n", GetLastError());
515 ok (ret, "Failed to add rw store to collection %x\n", GetLastError());
519 ok (ret, "Failed to add cert to the collection %x\n", GetLastError());
520
521 tcert1 = CertEnumCertificatesInStore(ro_store, NULL);
522 ok (!tcert1, "Read-only ro_store contains cert\n");
523
524 tcert1 = CertEnumCertificatesInStore(rw_store, NULL);
525 ok (cert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
526 "Unexpected cert in the rw store\n");
528
530 ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
531 "Unexpected cert in the collection\n");
533
536 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW2_W);
537 ok (rw_store_2 != NULL, "Failed to init second rw store %x\n", GetLastError());
539 ok (ret, "Failed to add rw_store_2 to collection %x\n",GetLastError());
540
542 ok (cert2 != NULL, "Failed to create cert context %x\n", GetLastError());
544 ok (ret, "Failed to add cert2 to the store %x\n",GetLastError());
545
547 tcert1 = CertEnumCertificatesInStore(ro_store, 0);
548 ok (tcert1 == NULL, "Read-only store not empty\n");
549
550 tcert1 = CertEnumCertificatesInStore(rw_store, NULL);
551 ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
552 "Unexpected cert in the rw_store\n");
554
555 tcert1 = CertEnumCertificatesInStore(rw_store_2, NULL);
556 ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded,
557 "Unexpected cert in the rw_store_2\n");
559
562 ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded,
563 "cert2 expected in the collection got %p, %x\n",tcert1, GetLastError());
564 tcert1 = CertEnumCertificatesInStore(collection, tcert1);
565 ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
566 "cert1 expected in the collection got %p, %x\n",tcert1, GetLastError());
567 tcert1 = CertEnumCertificatesInStore(collection, tcert1);
568 ok (tcert1==NULL,"Unexpected cert in the collection %p %x\n",tcert1, GetLastError());
569
570 /* checking whether certs had been saved */
573 ok (tstore!=NULL, "Failed to open existing rw store\n");
574 tcert1 = CertEnumCertificatesInStore(tstore, NULL);
576 ok(tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded, "cert1 wasn't saved\n");
578 CertCloseStore(tstore,0);
579
582 ok (tstore!=NULL, "Failed to open existing rw2 store\n");
583 tcert1 = CertEnumCertificatesInStore(tstore, NULL);
585 ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded, "cert2 wasn't saved\n");
587 CertCloseStore(tstore,0);
588
590 CertCloseStore(ro_store,0);
591 CertCloseStore(rw_store,0);
592 CertCloseStore(rw_store_2,0);
593
594 /* reopening registry stores to check whether certs had been saved */
596 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW_W);
597 tcert1 = CertEnumCertificatesInStore(rw_store, NULL);
598 ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
599 "Unexpected cert in store %p\n", tcert1);
601 CertCloseStore(rw_store,0);
602
604 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW2_W);
605 tcert1 = CertEnumCertificatesInStore(rw_store_2, NULL);
606 ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded,
607 "Unexpected cert in store %p\n", tcert1);
609 CertCloseStore(rw_store_2,0);
610
619
620}
621
622static void testCollectionStore(void)
623{
624 HCERTSTORE store1, store2, collection, collection2;
626 BOOL ret;
627 static const WCHAR szPrefix[] = { 'c','e','r',0 };
628 static const WCHAR szDot[] = { '.',0 };
630 HANDLE file;
631
634
635 /* Try adding a cert to any empty collection */
639 "Expected E_ACCESSDENIED, got %08x\n", GetLastError());
640
641 /* Create and add a cert to a memory store */
646 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
647 /* Add the memory store to the collection, without allowing adding */
648 ret = CertAddStoreToCollection(collection, store1, 0, 0);
649 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError());
650 /* Verify the cert is in the collection */
652 ok(context != NULL, "Expected a valid context\n");
653 if (context)
654 {
655 ok(context->hCertStore == collection, "Unexpected store\n");
657 }
658 /* Check that adding to the collection isn't allowed */
662 "Expected E_ACCESSDENIED, got %08x\n", GetLastError());
663
664 /* Create a new memory store */
667 /* Try adding a store to a non-collection store */
668 ret = CertAddStoreToCollection(store1, store2,
671 "Expected E_INVALIDARG, got %08x\n", GetLastError());
672 /* Try adding some bogus stores */
673 /* This crashes in Windows
674 ret = pCertAddStoreToCollection(0, store2,
675 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
676 */
677 /* This "succeeds"... */
680 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError());
681 /* while this crashes.
682 ret = pCertAddStoreToCollection(collection, 1,
683 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
684 */
685
686 /* Add it to the collection, this time allowing adding */
689 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError());
690 /* Check that adding to the collection is allowed */
693 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
694 /* Now check that it was actually added to store2 */
696 ok(context != NULL, "Expected a valid context\n");
697 if (context)
698 {
699 ok(context->hCertStore == store2, "Unexpected store\n");
701 }
702 /* Check that the collection has both bigCert and bigCert2. bigCert comes
703 * first because store1 was added first.
704 */
706 ok(context != NULL, "Expected a valid context\n");
707 if (context)
708 {
709 ok(context->hCertStore == collection, "Unexpected store\n");
710 ok(context->cbCertEncoded == sizeof(bigCert),
711 "Wrong size %d\n", context->cbCertEncoded);
712 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded),
713 "Unexpected cert\n");
715 ok(context != NULL, "Expected a valid context\n");
716 if (context)
717 {
718 ok(context->hCertStore == collection, "Unexpected store\n");
719 ok(context->cbCertEncoded == sizeof(bigCert2),
720 "Wrong size %d\n", context->cbCertEncoded);
721 ok(!memcmp(context->pbCertEncoded, bigCert2,
722 context->cbCertEncoded), "Unexpected cert\n");
724 ok(!context, "Unexpected cert\n");
725 }
726 }
727 /* close store2, and check that the collection is unmodified */
728 CertCloseStore(store2, 0);
730 ok(context != NULL, "Expected a valid context\n");
731 if (context)
732 {
733 ok(context->hCertStore == collection, "Unexpected store\n");
734 ok(context->cbCertEncoded == sizeof(bigCert),
735 "Wrong size %d\n", context->cbCertEncoded);
736 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded),
737 "Unexpected cert\n");
739 ok(context != NULL, "Expected a valid context\n");
740 if (context)
741 {
742 ok(context->hCertStore == collection, "Unexpected store\n");
743 ok(context->cbCertEncoded == sizeof(bigCert2),
744 "Wrong size %d\n", context->cbCertEncoded);
745 ok(!memcmp(context->pbCertEncoded, bigCert2,
746 context->cbCertEncoded), "Unexpected cert\n");
748 ok(!context, "Unexpected cert\n");
749 }
750 }
751
752 /* Adding a collection to a collection is legal */
753 collection2 = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
757 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError());
758 /* check the contents of collection2 */
760 ok(context != NULL, "Expected a valid context\n");
761 if (context)
762 {
763 ok(context->hCertStore == collection2, "Unexpected store\n");
764 ok(context->cbCertEncoded == sizeof(bigCert),
765 "Wrong size %d\n", context->cbCertEncoded);
766 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded),
767 "Unexpected cert\n");
769 ok(context != NULL, "Expected a valid context\n");
770 if (context)
771 {
772 ok(context->hCertStore == collection2, "Unexpected store\n");
773 ok(context->cbCertEncoded == sizeof(bigCert2),
774 "Wrong size %d\n", context->cbCertEncoded);
775 ok(!memcmp(context->pbCertEncoded, bigCert2,
776 context->cbCertEncoded), "Unexpected cert\n");
778 ok(!context, "Unexpected cert\n");
779 }
780 }
781
782 /* I'd like to test closing the collection in the middle of enumeration,
783 * but my tests have been inconsistent. The first time calling
784 * CertEnumCertificatesInStore on a closed collection succeeded, while the
785 * second crashed. So anything appears to be fair game.
786 * I'd also like to test removing a store from a collection in the middle
787 * of an enumeration, but my tests in Windows have been inconclusive.
788 * In one scenario it worked. In another scenario, about a third of the
789 * time this leads to "random" crashes elsewhere in the code. This
790 * probably means this is not allowed.
791 */
792
793 CertCloseStore(store1, 0);
795 CertCloseStore(collection2, 0);
796
797 /* Add the same cert to two memory stores, then put them in a collection */
800 ok(store1 != 0, "CertOpenStore failed: %08x\n", GetLastError());
803 ok(store2 != 0, "CertOpenStore failed: %08x\n", GetLastError());
804
807 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
810 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
813 ok(collection != 0, "CertOpenStore failed: %08x\n", GetLastError());
814
816 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError());
818 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError());
819
820 /* Check that the collection has two copies of the same cert */
822 ok(context != NULL, "Expected a valid context\n");
823 if (context)
824 {
825 ok(context->hCertStore == collection, "Unexpected store\n");
826 ok(context->cbCertEncoded == sizeof(bigCert),
827 "Wrong size %d\n", context->cbCertEncoded);
828 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded),
829 "Unexpected cert\n");
831 ok(context != NULL, "Expected a valid context\n");
832 if (context)
833 {
834 ok(context->hCertStore == collection, "Unexpected store\n");
835 ok(context->cbCertEncoded == sizeof(bigCert),
836 "Wrong size %d\n", context->cbCertEncoded);
837 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded),
838 "Unexpected cert\n");
840 ok(context == NULL, "Unexpected cert\n");
841 }
842 }
843
844 /* The following would check whether I can delete an identical cert, rather
845 * than one enumerated from the store. It crashes, so that means I must
846 * only call CertDeleteCertificateFromStore with contexts enumerated from
847 * the store.
848 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
849 sizeof(bigCert));
850 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
851 GetLastError());
852 if (context)
853 {
854 ret = CertDeleteCertificateFromStore(collection, context);
855 printf("ret is %d, GetLastError is %08x\n", ret, GetLastError());
856 CertFreeCertificateContext(context);
857 }
858 */
859
860 /* Now check deleting from the collection. */
862 ok(context != NULL, "Expected a valid context\n");
863 if (context)
864 {
866 /* store1 should now be empty */
868 ok(!context, "Unexpected cert\n");
869 /* and there should be one certificate in the collection */
871 ok(context != NULL, "Expected a valid cert\n");
872 if (context)
873 {
874 ok(context->hCertStore == collection, "Unexpected store\n");
875 ok(context->cbCertEncoded == sizeof(bigCert),
876 "Wrong size %d\n", context->cbCertEncoded);
877 ok(!memcmp(context->pbCertEncoded, bigCert, context->cbCertEncoded),
878 "Unexpected cert\n");
879 }
881 ok(context == NULL, "Unexpected cert\n");
882 }
883
884 /* Finally, test removing stores from the collection. No return
885 * value, so it's a bit funny to test.
886 */
887 /* This crashes
888 * CertRemoveStoreFromCollection(NULL, NULL);
889 */
890 /* This "succeeds," no crash, no last error set */
891 SetLastError(0xdeadbeef);
893 ok(GetLastError() == 0xdeadbeef,
894 "Didn't expect an error to be set: %08x\n", GetLastError());
895
896 /* After removing store2, the collection should be empty */
897 SetLastError(0xdeadbeef);
899 ok(GetLastError() == 0xdeadbeef,
900 "Didn't expect an error to be set: %08x\n", GetLastError());
902 ok(!context, "Unexpected cert\n");
903
905 CertCloseStore(store2, 0);
906 CertCloseStore(store1, 0);
907
908 /* Test adding certificates to and deleting certificates from collections.
909 */
910 store1 = CertOpenSystemStoreA(0, "My");
913
916 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
918
920
923 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
925
927 CertCloseStore(store1, 0);
928
929 /* Test whether a collection store can be committed */
932
933 SetLastError(0xdeadbeef);
935 ok(ret, "CertControlStore failed: %08x\n", GetLastError());
936
937 /* Adding a mem store that can't be committed prevents a successful commit.
938 */
942 SetLastError(0xdeadbeef);
945 "expected ERROR_CALL_NOT_IMPLEMENTED, got %d\n", GetLastError());
947 CertCloseStore(store1, 0);
948
949 /* Test adding a cert to a collection with a file store, committing the
950 * change to the collection, and comparing the resulting file.
951 */
952 if (!GetTempFileNameW(szDot, szPrefix, 0, filename))
953 return;
954
959 return;
960
961 store1 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
963 ok(store1 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
966 CertCloseStore(store1, 0);
967
970 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
971 GetLastError());
973 ok(ret, "CertControlStore failed: %d\n", ret);
974 compareStore(collection, "serialized store with cert",
977
979}
980
981/* Looks for the property with ID propID in the buffer buf. Returns a pointer
982 * to its header if found, NULL if not.
983 */
984static const struct CertPropIDHeader *findPropID(const BYTE *buf, DWORD size,
986{
987 const struct CertPropIDHeader *ret = NULL;
988 BOOL failed = FALSE;
989
990 while (size && !ret && !failed)
991 {
992 if (size < sizeof(struct CertPropIDHeader))
993 failed = TRUE;
994 else
995 {
996 const struct CertPropIDHeader *hdr =
997 (const struct CertPropIDHeader *)buf;
998
999 size -= sizeof(struct CertPropIDHeader);
1000 buf += sizeof(struct CertPropIDHeader);
1001 if (size < hdr->cb)
1002 failed = TRUE;
1003 else if (hdr->propID == propID)
1004 ret = hdr;
1005 else
1006 {
1007 buf += hdr->cb;
1008 size -= hdr->cb;
1009 }
1010 }
1011 }
1012 return ret;
1013}
1014
1015static void testRegStore(void)
1016{
1017 static const char tempKey[] = "Software\\Wine\\CryptTemp";
1018 HCERTSTORE store;
1019 LONG rc;
1020 HKEY key = NULL;
1021 DWORD disp, GLE;
1022
1023 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 0, NULL);
1024 GLE = GetLastError();
1025 ok(!store && (GLE == ERROR_INVALID_HANDLE || GLE == ERROR_BADKEY),
1026 "Expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", GLE);
1027 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 0, key);
1028 GLE = GetLastError();
1029 ok(!store && (GLE == ERROR_INVALID_HANDLE || GLE == ERROR_BADKEY),
1030 "Expected ERROR_INVALID_HANDLE or ERROR_BADKEY, got %d\n", GLE);
1031
1032 /* Opening up any old key works.. */
1034 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 0, key);
1035 /* Not sure if this is a bug in DuplicateHandle, marking todo_wine for now
1036 */
1037 todo_wine ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError());
1038 CertCloseStore(store, 0);
1039
1041 NULL, &key, NULL);
1042 ok(!rc, "RegCreateKeyExA failed: %d\n", rc);
1043 if (key)
1044 {
1045 BOOL ret;
1046 BYTE hash[20];
1047 DWORD size, i;
1048 static const char certificates[] = "Certificates\\";
1049 char subKeyName[sizeof(certificates) + 20 * 2 + 1], *ptr;
1050 HKEY subKey;
1052
1053 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0, 0, key);
1054 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError());
1055 /* Add a certificate. It isn't persisted right away, since it's only
1056 * added to the cache..
1057 */
1060 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1061 GetLastError());
1062 /* so flush the cache to force a commit.. */
1064 ok(ret, "CertControlStore failed: %08x\n", GetLastError());
1065 /* and check that the expected subkey was written. */
1066 size = sizeof(hash);
1067 ret = CryptHashCertificate(0, 0, 0, bigCert2, sizeof(bigCert2),
1068 hash, &size);
1069 ok(ret, "CryptHashCertificate failed: %d\n", GetLastError());
1070 strcpy(subKeyName, certificates);
1071 for (i = 0, ptr = subKeyName + sizeof(certificates) - 1; i < size;
1072 i++, ptr += 2)
1073 sprintf(ptr, "%02X", hash[i]);
1074 rc = RegCreateKeyExA(key, subKeyName, 0, NULL, 0, KEY_ALL_ACCESS, NULL,
1075 &subKey, NULL);
1076 ok(!rc, "RegCreateKeyExA failed: %d\n", rc);
1077 if (subKey)
1078 {
1079 LPBYTE buf;
1080
1081 size = 0;
1082 RegQueryValueExA(subKey, "Blob", NULL, NULL, NULL, &size);
1084 if (buf)
1085 {
1086 rc = RegQueryValueExA(subKey, "Blob", NULL, NULL, buf, &size);
1087 ok(!rc, "RegQueryValueExA failed: %d\n", rc);
1088 if (!rc)
1089 {
1090 const struct CertPropIDHeader *hdr;
1091
1092 /* Both the hash and the cert should be present */
1094 ok(hdr != NULL, "Expected to find a cert property\n");
1095 if (hdr)
1096 {
1097 ok(hdr->cb == sizeof(bigCert2),
1098 "Wrong size %d of cert property\n", hdr->cb);
1099 ok(!memcmp((const BYTE *)hdr + sizeof(*hdr), bigCert2,
1100 hdr->cb), "Unexpected cert in cert property\n");
1101 }
1103 ok(hdr != NULL, "Expected to find a hash property\n");
1104 if (hdr)
1105 {
1106 ok(hdr->cb == sizeof(hash),
1107 "Wrong size %d of hash property\n", hdr->cb);
1108 ok(!memcmp((const BYTE *)hdr + sizeof(*hdr), hash,
1109 hdr->cb), "Unexpected hash in cert property\n");
1110 }
1111 }
1113 }
1114 RegCloseKey(subKey);
1115 }
1116
1117 /* Remove the existing context */
1119 ok(context != NULL, "Expected a cert context\n");
1120 if (context)
1123 ok(ret, "CertControlStore failed: %08x\n", GetLastError());
1124
1125 /* Add a serialized cert with a bogus hash directly to the registry */
1126 memset(hash, 0, sizeof(hash));
1127 strcpy(subKeyName, certificates);
1128 for (i = 0, ptr = subKeyName + sizeof(certificates) - 1;
1129 i < sizeof(hash); i++, ptr += 2)
1130 sprintf(ptr, "%02X", hash[i]);
1131 rc = RegCreateKeyExA(key, subKeyName, 0, NULL, 0, KEY_ALL_ACCESS, NULL,
1132 &subKey, NULL);
1133 ok(!rc, "RegCreateKeyExA failed: %d\n", rc);
1134 if (subKey)
1135 {
1136 BYTE buf[sizeof(struct CertPropIDHeader) * 2 + sizeof(hash) +
1137 sizeof(bigCert)], *ptr;
1138 DWORD certCount = 0;
1139 struct CertPropIDHeader *hdr;
1140
1141 hdr = (struct CertPropIDHeader *)buf;
1142 hdr->propID = CERT_HASH_PROP_ID;
1143 hdr->unknown1 = 1;
1144 hdr->cb = sizeof(hash);
1145 ptr = buf + sizeof(*hdr);
1146 memcpy(ptr, hash, sizeof(hash));
1147 ptr += sizeof(hash);
1148 hdr = (struct CertPropIDHeader *)ptr;
1149 hdr->propID = CERT_CERT_PROP_ID;
1150 hdr->unknown1 = 1;
1151 hdr->cb = sizeof(bigCert);
1152 ptr += sizeof(*hdr);
1153 memcpy(ptr, bigCert, sizeof(bigCert));
1154
1155 rc = RegSetValueExA(subKey, "Blob", 0, REG_BINARY, buf,
1156 sizeof(buf));
1157 ok(!rc, "RegSetValueExA failed: %d\n", rc);
1158
1160 ok(ret, "CertControlStore failed: %08x\n", GetLastError());
1161
1162 /* Make sure the bogus hash cert gets loaded. */
1163 certCount = 0;
1164 context = NULL;
1165 do {
1167 if (context)
1168 certCount++;
1169 } while (context != NULL);
1170 ok(certCount == 1, "Expected 1 certificates, got %d\n", certCount);
1171
1172 RegCloseKey(subKey);
1173 }
1174
1175 /* Add another serialized cert directly to the registry, this time
1176 * under the correct key name (named with the correct hash value).
1177 */
1178 size = sizeof(hash);
1180 sizeof(bigCert2), hash, &size);
1181 ok(ret, "CryptHashCertificate failed: %d\n", GetLastError());
1182 strcpy(subKeyName, certificates);
1183 for (i = 0, ptr = subKeyName + sizeof(certificates) - 1;
1184 i < sizeof(hash); i++, ptr += 2)
1185 sprintf(ptr, "%02X", hash[i]);
1186 rc = RegCreateKeyExA(key, subKeyName, 0, NULL, 0, KEY_ALL_ACCESS, NULL,
1187 &subKey, NULL);
1188 ok(!rc, "RegCreateKeyExA failed: %d\n", rc);
1189 if (subKey)
1190 {
1191 BYTE buf[sizeof(struct CertPropIDHeader) * 2 + sizeof(hash) +
1192 sizeof(bigCert2)], *ptr;
1193 DWORD certCount = 0;
1195 struct CertPropIDHeader *hdr;
1196
1197 /* First try with a bogus hash... */
1198 hdr = (struct CertPropIDHeader *)buf;
1199 hdr->propID = CERT_HASH_PROP_ID;
1200 hdr->unknown1 = 1;
1201 hdr->cb = sizeof(hash);
1202 ptr = buf + sizeof(*hdr);
1203 memset(ptr, 0, sizeof(hash));
1204 ptr += sizeof(hash);
1205 hdr = (struct CertPropIDHeader *)ptr;
1206 hdr->propID = CERT_CERT_PROP_ID;
1207 hdr->unknown1 = 1;
1208 hdr->cb = sizeof(bigCert2);
1209 ptr += sizeof(*hdr);
1210 memcpy(ptr, bigCert2, sizeof(bigCert2));
1211
1212 rc = RegSetValueExA(subKey, "Blob", 0, REG_BINARY, buf,
1213 sizeof(buf));
1214 ok(!rc, "RegSetValueExA failed: %d\n", rc);
1215
1217 ok(ret, "CertControlStore failed: %08x\n", GetLastError());
1218
1219 /* and make sure just one cert still gets loaded. */
1220 certCount = 0;
1221 context = NULL;
1222 do {
1224 if (context)
1225 certCount++;
1226 } while (context != NULL);
1227 ok(certCount == 1, "Expected 1 certificate, got %d\n", certCount);
1228
1229 /* Try again with the correct hash... */
1230 ptr = buf + sizeof(*hdr);
1231 memcpy(ptr, hash, sizeof(hash));
1232
1233 rc = RegSetValueExA(subKey, "Blob", 0, REG_BINARY, buf,
1234 sizeof(buf));
1235 ok(!rc, "RegSetValueExA failed: %d\n", rc);
1236
1238 ok(ret, "CertControlStore failed: %08x\n", GetLastError());
1239
1240 /* and make sure two certs get loaded. */
1241 certCount = 0;
1242 context = NULL;
1243 do {
1245 if (context)
1246 certCount++;
1247 } while (context != NULL);
1248 ok(certCount == 2, "Expected 2 certificates, got %d\n", certCount);
1249
1250 RegCloseKey(subKey);
1251 }
1252 CertCloseStore(store, 0);
1253 /* Is delete allowed on a reg store? */
1254 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0,
1256 ok(store == NULL, "Expected NULL return from CERT_STORE_DELETE_FLAG\n");
1257 ok(GetLastError() == 0, "CertOpenStore failed: %08x\n",
1258 GetLastError());
1259
1261 }
1262 /* The CertOpenStore with CERT_STORE_DELETE_FLAG above will delete the
1263 * contents of the key, but not the key itself.
1264 */
1266 NULL, &key, &disp);
1267 ok(!rc, "RegCreateKeyExA failed: %d\n", rc);
1269 "Expected REG_OPENED_EXISTING_KEY, got %d\n", disp);
1270 if (!rc)
1271 {
1273 rc = RegDeleteKeyA(HKEY_CURRENT_USER, tempKey);
1274 if (rc)
1275 {
1276 /* Use shlwapi's SHDeleteKeyA to _really_ blow away the key,
1277 * otherwise subsequent tests will fail.
1278 */
1280 }
1281 }
1282}
1283
1284static const char MyA[] = { 'M','y',0,0 };
1285static const WCHAR MyW[] = { 'M','y',0 };
1286static const WCHAR BogusW[] = { 'B','o','g','u','s',0 };
1287static const WCHAR BogusPathW[] = { 'S','o','f','t','w','a','r','e','\\',
1288 'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m','C','e','r',
1289 't','i','f','i','c','a','t','e','s','\\','B','o','g','u','s',0 };
1290
1291static void testSystemRegStore(void)
1292{
1293 HCERTSTORE store, memStore;
1294
1295 /* Check with a UNICODE name */
1298 /* Not all OSes support CERT_STORE_PROV_SYSTEM_REGISTRY, so don't continue
1299 * testing if they don't.
1300 */
1301 if (!store)
1302 return;
1303
1304 /* Check that it isn't a collection store */
1305 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1307 if (memStore)
1308 {
1309 BOOL ret = CertAddStoreToCollection(store, memStore, 0, 0);
1310 ok(!ret && GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", GetLastError());
1311 CertCloseStore(memStore, 0);
1312 }
1313 CertCloseStore(store, 0);
1314
1315 /* Check opening a bogus store */
1318 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1319 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1322 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError());
1323 if (store)
1324 CertCloseStore(store, 0);
1325 /* Now check whether deleting is allowed */
1328 ok(!store, "CertOpenStore failed: %08x\n", GetLastError());
1330
1332 ok(!store && GetLastError() == E_INVALIDARG,
1333 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1336 ok(!store && GetLastError() == E_INVALIDARG,
1337 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1340 ok(!store && GetLastError() == E_INVALIDARG,
1341 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1342 /* The name is expected to be UNICODE, check with an ASCII name */
1345 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1346 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1347}
1348
1349static void testSystemStore(void)
1350{
1351 static const WCHAR baskslashW[] = { '\\',0 };
1352 HCERTSTORE store;
1353 WCHAR keyName[MAX_PATH];
1354 HKEY key;
1355 LONG rc;
1356
1357 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, 0, NULL);
1358 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1359 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1362 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1363 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1366 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1367 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1368 /* The name is expected to be UNICODE, first check with an ASCII name */
1371 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1372 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1373 /* Create the expected key */
1375 lstrcatW(keyName, baskslashW);
1376 lstrcatW(keyName, MyW);
1377 rc = RegCreateKeyExW(HKEY_CURRENT_USER, keyName, 0, NULL, 0, KEY_READ,
1378 NULL, &key, NULL);
1379 ok(!rc, "RegCreateKeyEx failed: %d\n", rc);
1380 if (!rc)
1382 /* Check opening with a UNICODE name, specifying the create new flag */
1385 ok(!store && GetLastError() == ERROR_FILE_EXISTS,
1386 "Expected ERROR_FILE_EXISTS, got %08x\n", GetLastError());
1387 /* Now check opening with a UNICODE name, this time opening existing */
1390 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError());
1391 if (store)
1392 {
1395
1396 /* Check that it's a collection store */
1397 if (memStore)
1398 {
1399 BOOL ret = CertAddStoreToCollection(store, memStore, 0, 0);
1400 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError());
1401 CertCloseStore(memStore, 0);
1402 }
1403 CertCloseStore(store, 0);
1404 }
1405
1406 /* Check opening a bogus store */
1409 ok(!store, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1412 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError());
1413 if (store)
1414 CertCloseStore(store, 0);
1415 /* Now check whether deleting is allowed */
1418 ok(!store, "Didn't expect a store to be returned when deleting\n");
1420}
1421
1423 0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x20,0x00,0x00,0x00,0x01,0x00,0x00,
1424 0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
1425 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1426 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
1427 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
1428 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
1429 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1430 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
1431 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
1432 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x21,0x00,0x00,0x00,0x01,0x00,
1433 0x00,0x00,0x47,0x00,0x00,0x00,0x30,0x45,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,
1434 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
1435 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1436 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x03,0x11,
1437 0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,
1438 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1439
1440static void testFileStore(void)
1441{
1442 static const WCHAR szPrefix[] = { 'c','e','r',0 };
1443 static const WCHAR szDot[] = { '.',0 };
1445 HCERTSTORE store;
1446 BOOL ret;
1448 HANDLE file;
1449
1450 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, 0, NULL);
1451 ok(!store && GetLastError() == ERROR_INVALID_HANDLE,
1452 "Expected ERROR_INVALID_HANDLE, got %08x\n", GetLastError());
1453
1454 if (!GetTempFileNameW(szDot, szPrefix, 0, filename))
1455 return;
1456
1461 return;
1462
1464 file);
1465 ok(!store && GetLastError() == E_INVALIDARG,
1466 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1467 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
1469 ok(!store && GetLastError() == E_INVALIDARG,
1470 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1471
1472 /* A "read-only" file store.. */
1473 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
1475 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1476 if (store)
1477 {
1478 DWORD size;
1479
1482 /* apparently allows adding certificates.. */
1483 ok(ret, "CertAddEncodedCertificateToStore failed: %d\n", ret);
1484 /* but not commits.. */
1487 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %08x\n", GetLastError());
1488 /* It still has certs in memory.. */
1490 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
1491 GetLastError());
1493 /* but the file size is still 0. */
1495 ok(size == 0, "Expected size 0, got %d\n", size);
1496 CertCloseStore(store, 0);
1497 }
1498
1499 /* The create new flag is allowed.. */
1500 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
1502 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1503 if (store)
1504 {
1505 /* but without the commit enable flag, commits don't happen. */
1508 ok(ret, "CertAddEncodedCertificateToStore failed: %d\n", ret);
1511 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %08x\n", GetLastError());
1512 CertCloseStore(store, 0);
1513 }
1514 /* as is the open existing flag. */
1515 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
1517 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1518 if (store)
1519 {
1520 /* but without the commit enable flag, commits don't happen. */
1523 ok(ret, "CertAddEncodedCertificateToStore failed: %d\n", ret);
1526 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %08x\n", GetLastError());
1527 CertCloseStore(store, 0);
1528 }
1529 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
1531 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1532 if (store)
1533 {
1537 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1538 GetLastError());
1539 /* with commits enabled, commit is allowed */
1541 ok(ret, "CertControlStore failed: %d\n", ret);
1542 compareStore(store, "serialized store with cert",
1544 CertCloseStore(store, 0);
1545 }
1549 return;
1550 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
1552 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1553 if (store)
1554 {
1558 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
1559 compareStore(store, "serialized store with cert and CRL",
1561 FALSE);
1562 CertCloseStore(store, 0);
1563 }
1564
1566}
1567
1569{
1572 BOOL ret;
1573
1575 {
1576 DWORD written;
1577
1578 ret = WriteFile(file, pb, cb, &written, NULL);
1580 }
1581 else
1582 ret = FALSE;
1583 return ret;
1584}
1585
1586static const BYTE base64SPC[] =
1587"MIICJQYJKoZIhvcNAQcCoIICFjCCAhICAQExADALBgkqhkiG9w0BBwGgggH6MIIB"
1588"9jCCAV+gAwIBAgIQnP8+EF4opr9OxH7h4uBPWTANBgkqhkiG9w0BAQQFADAUMRIw"
1589"EAYDVQQDEwlKdWFuIExhbmcwHhcNMDgxMjEyMTcxMDE0WhcNMzkxMjMxMjM1OTU5"
1590"WjAUMRIwEAYDVQQDEwlKdWFuIExhbmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ"
1591"AoGBALCgNjyNvOic0FOfjxvi43HbM+D5joDkhiGSXe+gbZlf8f16k07kkObFEunz"
1592"mdB5coscmA7gyqiWNN4ZUyr2cA3lCbnpGPA/0IblyyOcuGIFmmCzeZaVa5ZG6xZP"
1593"K7L7o+73Qo6jXVbGhBGnMZ7Q9sAn6s2933olnStnejnqwV0NAgMBAAGjSTBHMEUG"
1594"A1UdAQQ+MDyAEFKbKEdXYyx+CWKcV6vxM6ShFjAUMRIwEAYDVQQDEwlKdWFuIExh"
1595"bmeCEJz/PhBeKKa/TsR+4eLgT1kwDQYJKoZIhvcNAQEEBQADgYEALpkgLgW3mEaK"
1596"idPQ3iPJYLG0Ub1wraqEl9bd42hrhzIdcDzlQgxnm8/5cHYVxIF/C20x/HJplb1R"
1597"G6U1ipFe/q8byWD/9JpiBKMGPi9YlUTgXHfS9d4S/QWO1h9Z7KeipBYhoslQpHXu"
1598"y9bUr8Adqi6SzgHpCnMu53dxgxUD1r4xAA==";
1599/* Same as base64SPC, but as a wide-char string */
1600static const WCHAR utf16Base64SPC[] = {
1601'M','I','I','C','J','Q','Y','J','K','o','Z','I','h','v','c','N','A',
1602'Q','c','C','o','I','I','C','F','j','C','C','A','h','I','C','A','Q',
1603'E','x','A','D','A','L','B','g','k','q','h','k','i','G','9','w','0',
1604'B','B','w','G','g','g','g','H','6','M','I','I','B','9','j','C','C',
1605'A','V','+','g','A','w','I','B','A','g','I','Q','n','P','8','+','E',
1606'F','4','o','p','r','9','O','x','H','7','h','4','u','B','P','W','T',
1607'A','N','B','g','k','q','h','k','i','G','9','w','0','B','A','Q','Q',
1608'F','A','D','A','U','M','R','I','w','E','A','Y','D','V','Q','Q','D',
1609'E','w','l','K','d','W','F','u','I','E','x','h','b','m','c','w','H',
1610'h','c','N','M','D','g','x','M','j','E','y','M','T','c','x','M','D',
1611'E','0','W','h','c','N','M','z','k','x','M','j','M','x','M','j','M',
1612'1','O','T','U','5','W','j','A','U','M','R','I','w','E','A','Y','D',
1613'V','Q','Q','D','E','w','l','K','d','W','F','u','I','E','x','h','b',
1614'm','c','w','g','Z','8','w','D','Q','Y','J','K','o','Z','I','h','v',
1615'c','N','A','Q','E','B','B','Q','A','D','g','Y','0','A','M','I','G',
1616'J','A','o','G','B','A','L','C','g','N','j','y','N','v','O','i','c',
1617'0','F','O','f','j','x','v','i','4','3','H','b','M','+','D','5','j',
1618'o','D','k','h','i','G','S','X','e','+','g','b','Z','l','f','8','f',
1619'1','6','k','0','7','k','k','O','b','F','E','u','n','z','m','d','B',
1620'5','c','o','s','c','m','A','7','g','y','q','i','W','N','N','4','Z',
1621'U','y','r','2','c','A','3','l','C','b','n','p','G','P','A','/','0',
1622'I','b','l','y','y','O','c','u','G','I','F','m','m','C','z','e','Z',
1623'a','V','a','5','Z','G','6','x','Z','P','K','7','L','7','o','+','7',
1624'3','Q','o','6','j','X','V','b','G','h','B','G','n','M','Z','7','Q',
1625'9','s','A','n','6','s','2','9','3','3','o','l','n','S','t','n','e',
1626'j','n','q','w','V','0','N','A','g','M','B','A','A','G','j','S','T',
1627'B','H','M','E','U','G','A','1','U','d','A','Q','Q','+','M','D','y',
1628'A','E','F','K','b','K','E','d','X','Y','y','x','+','C','W','K','c',
1629'V','6','v','x','M','6','S','h','F','j','A','U','M','R','I','w','E',
1630'A','Y','D','V','Q','Q','D','E','w','l','K','d','W','F','u','I','E',
1631'x','h','b','m','e','C','E','J','z','/','P','h','B','e','K','K','a',
1632'/','T','s','R','+','4','e','L','g','T','1','k','w','D','Q','Y','J',
1633'K','o','Z','I','h','v','c','N','A','Q','E','E','B','Q','A','D','g',
1634'Y','E','A','L','p','k','g','L','g','W','3','m','E','a','K','i','d',
1635'P','Q','3','i','P','J','Y','L','G','0','U','b','1','w','r','a','q',
1636'E','l','9','b','d','4','2','h','r','h','z','I','d','c','D','z','l',
1637'Q','g','x','n','m','8','/','5','c','H','Y','V','x','I','F','/','C',
1638'2','0','x','/','H','J','p','l','b','1','R','G','6','U','1','i','p',
1639'F','e','/','q','8','b','y','W','D','/','9','J','p','i','B','K','M',
1640'G','P','i','9','Y','l','U','T','g','X','H','f','S','9','d','4','S',
1641'/','Q','W','O','1','h','9','Z','7','K','e','i','p','B','Y','h','o',
1642's','l','Q','p','H','X','u','y','9','b','U','r','8','A','d','q','i',
1643'6','S','z','g','H','p','C','n','M','u','5','3','d','x','g','x','U',
1644'D','1','r','4','x','A','A','=','=',0 };
1645
1646static void testFileNameStore(void)
1647{
1648 static const WCHAR szPrefix[] = { 'c','e','r',0 };
1649 static const WCHAR spcPrefix[] = { 's','p','c',0 };
1650 static const WCHAR szDot[] = { '.',0 };
1652 HCERTSTORE store;
1653 BOOL ret;
1654 DWORD GLE;
1655
1657 GLE = GetLastError();
1659 "Expected ERROR_PATH_NOT_FOUND or ERROR_INVALID_PARAMETER, got %08x\n",
1660 GLE);
1661
1662 if (!GetTempFileNameW(szDot, szPrefix, 0, filename))
1663 return;
1665
1666 /* The two flags are mutually exclusive */
1669 ok(!store && GetLastError() == E_INVALIDARG,
1670 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1671
1672 /* In all of the following tests, the encoding type seems to be ignored */
1674 {
1677
1680 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1681
1683 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
1684 GetLastError());
1686 ok(!cert, "Expected only one cert\n");
1687 crl = CertEnumCRLsInStore(store, NULL);
1688 ok(!crl, "Expected no CRLs\n");
1689
1690 CertCloseStore(store, 0);
1692 }
1694 sizeof(serializedStoreWithCert)))
1695 {
1698
1701 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1702
1704 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
1705 GetLastError());
1707 ok(!cert, "Expected only one cert\n");
1708 crl = CertEnumCRLsInStore(store, NULL);
1709 ok(!crl, "Expected no CRLs\n");
1710
1711 CertCloseStore(store, 0);
1713 }
1716 {
1719
1722 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1723
1725 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
1726 GetLastError());
1728 ok(!cert, "Expected only one cert\n");
1729 crl = CertEnumCRLsInStore(store, NULL);
1730 ok(crl != NULL, "CertEnumCRLsInStore failed: %08x\n", GetLastError());
1731 crl = CertEnumCRLsInStore(store, crl);
1732 ok(!crl, "Expected only one CRL\n");
1733
1734 CertCloseStore(store, 0);
1735 /* Don't delete it this time, the next test uses it */
1736 }
1737 /* Now that the file exists, we can open it read-only */
1740 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1741 CertCloseStore(store, 0);
1743
1746 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1747 if (store)
1748 {
1751 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1752 GetLastError());
1753 compareStore(store, "serialized store with cert",
1755 CertCloseStore(store, 0);
1756 }
1759 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1760 if (store)
1761 {
1764 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
1765 compareStore(store, "serialized store with cert and CRL",
1767 FALSE);
1768 CertCloseStore(store, 0);
1769 }
1771
1772 if (!GetTempFileNameW(szDot, spcPrefix, 0, filename))
1773 return;
1775
1777 {
1780
1783 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1784
1786 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
1787 GetLastError());
1789 ok(!cert, "Expected only one cert\n");
1790 crl = CertEnumCRLsInStore(store, NULL);
1791 ok(!crl, "Expected no CRLs\n");
1792
1793 CertCloseStore(store, 0);
1795 }
1797 sizeof(utf16Base64SPC)))
1798 {
1801
1804 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1805
1807 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
1808 GetLastError());
1810 ok(!cert, "Expected only one cert\n");
1811 crl = CertEnumCRLsInStore(store, NULL);
1812 ok(!crl, "Expected no CRLs\n");
1813
1814 CertCloseStore(store, 0);
1816 }
1817}
1818
1819static const BYTE signedContent[] = {
18200x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
18210x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
18220x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
18230x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
18240x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
18250x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
18260x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
18270x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
18280xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
18290x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
18300x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
18310xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
18320x0d };
18340x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
18350x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
18360x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
18370x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
18380x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
18390x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
18400x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
18410x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
18420x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
18430x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
18440x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
18450x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
18460x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
18470x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
18480x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
18490x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
18500x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
18510x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
18520x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
18530xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
18540xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
18550x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
18560x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1857static const BYTE hashContent[] = {
18580x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
18590x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
18600x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
18610x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
18620x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1863static const BYTE hashBareContent[] = {
18640x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
18650x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
18660x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
18670x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1868
1869static void testMessageStore(void)
1870{
1871 HCERTSTORE store;
1873 NULL);
1876 DWORD count, size;
1877 BOOL ret;
1878
1879 /* Crashes
1880 store = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0, NULL);
1881 */
1882 SetLastError(0xdeadbeef);
1883 store = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0, msg);
1885 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1887 store = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0, msg);
1888 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1889 if (store)
1890 {
1893
1894 count = 0;
1895 do {
1897 if (cert)
1898 count++;
1899 } while (cert);
1900 ok(count == 0, "Expected 0 certificates, got %d\n", count);
1901
1902 count = 0;
1903 do {
1904 crl = CertEnumCRLsInStore(store, crl);
1905 if (crl)
1906 count++;
1907 } while (crl);
1908 ok(count == 0, "Expected 0 CRLs, got %d\n", count);
1909
1910 /* Can add certs to a message store */
1913 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1914 GetLastError());
1915 count = 0;
1916 do {
1918 if (cert)
1919 count++;
1920 } while (cert);
1921 ok(count == 1, "Expected 1 certificate, got %d\n", count);
1922
1923 CertCloseStore(store, 0);
1924 }
1925 /* but the added certs weren't actually added to the message */
1926 size = sizeof(count);
1928 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1929 ok(count == 0, "Expected 0 certificates, got %d\n", count);
1931
1932 /* Crashes
1933 store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, NULL);
1934 */
1935 store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, &blob);
1936 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1937 if (store)
1938 {
1939 DWORD count = 0;
1942
1943 do {
1945 if (cert)
1946 count++;
1947 } while (cert);
1948 ok(count == 1, "Expected 1 certificate, got %d\n", count);
1949
1950 count = 0;
1951 do {
1952 crl = CertEnumCRLsInStore(store, crl);
1953 if (crl)
1954 count++;
1955 } while (crl);
1956 ok(count == 1, "Expected 1 CRL, got %d\n", count);
1957
1958 CertCloseStore(store, 0);
1959 }
1960 /* Encoding appears to be ignored */
1962 &blob);
1963 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1964 if (store)
1965 CertCloseStore(store, 0);
1966 /* Messages other than signed messages aren't allowed */
1967 blob.cbData = sizeof(hashContent);
1968 blob.pbData = (LPBYTE)hashContent;
1969 SetLastError(0xdeadbeef);
1970 store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, &blob);
1972 "Expected CRYPT_E_INVALID_MSG_TYPE, got %08x\n", GetLastError());
1973 blob.cbData = sizeof(hashBareContent);
1974 blob.pbData = (LPBYTE)hashBareContent;
1975 SetLastError(0xdeadbeef);
1976 store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, &blob);
1977 ok(!store && GetLastError() == CRYPT_E_ASN1_BADTAG,
1978 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1979}
1980
1981static void testSerializedStore(void)
1982{
1983 HCERTSTORE store;
1985
1986 if (0)
1987 {
1988 /* Crash */
1992 }
1993 blob.cbData = sizeof(serializedStoreWithCert);
1994 blob.pbData = (BYTE *)serializedStoreWithCert;
1998 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %08x\n", GetLastError());
1999 store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 0, &blob);
2000 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2001 if (store)
2002 {
2005
2007 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
2008 GetLastError());
2010 ok(!cert, "Expected only one cert\n");
2011 crl = CertEnumCRLsInStore(store, NULL);
2012 ok(!crl, "Expected no CRLs\n");
2013
2014 CertCloseStore(store, 0);
2015 }
2016 blob.cbData = sizeof(serializedStoreWithCertAndCRL);
2018 store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 0, &blob);
2019 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2020 if (store)
2021 {
2024
2026 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
2027 GetLastError());
2029 ok(!cert, "Expected only one cert\n");
2030 crl = CertEnumCRLsInStore(store, NULL);
2031 ok(crl != NULL, "CertEnumCRLsInStore failed: %08x\n",
2032 GetLastError());
2033 crl = CertEnumCRLsInStore(store, crl);
2034 ok(!crl, "Expected only one CRL\n");
2035
2036 CertCloseStore(store, 0);
2037 }
2038}
2039
2041{
2042 HCERTSTORE store;
2043
2044 store = CertOpenSystemStoreW(0, NULL);
2045 ok(!store && GetLastError() == E_INVALIDARG,
2046 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2047 /* This succeeds, and on WinXP at least, the Bogus key is created under
2048 * HKCU (but not under HKLM, even when run as an administrator.)
2049 */
2050 store = CertOpenSystemStoreW(0, BogusW);
2051 ok(store != 0, "CertOpenSystemStore failed: %08x\n", GetLastError());
2052 if (store)
2053 CertCloseStore(store, 0);
2054 /* Delete it so other tests succeed next time around */
2058}
2059
2060static const struct
2061{
2067 /* Following tests could require administrator privileges and thus could be skipped */
2074
2076{
2077 BOOL ret, cur_flag;
2078 DWORD err = 0;
2079 HCERTSTORE hstore;
2080 static const WCHAR WineTestW[] = {'W','i','n','e','T','e','s','t',0};
2081 const CERT_CONTEXT *cert, *cert2;
2082 unsigned int i;
2083
2084 for (i = 0; i < ARRAY_SIZE(reg_system_store_test_data); i++) {
2085 cur_flag = reg_system_store_test_data[i].cert_store;
2086 ret = CertRegisterSystemStore(WineTestW, cur_flag, NULL, NULL);
2087 if (!ret)
2088 {
2089 err = GetLastError();
2090 if (err == ERROR_ACCESS_DENIED)
2091 {
2092 win_skip("Insufficient privileges for the flag %08x test\n", cur_flag);
2093 continue;
2094 }
2095 }
2098 "Store registration (dwFlags=%08x) failed, last error %x\n", cur_flag, err);
2099 if (!ret)
2100 {
2101 skip("Nothing to test without registered store at %08x\n", cur_flag);
2102 continue;
2103 }
2104
2105 hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, CERT_STORE_OPEN_EXISTING_FLAG | cur_flag, WineTestW);
2106 ok (hstore != NULL, "Opening just registered store at %08x failed, last error %x\n", cur_flag, GetLastError());
2107
2109 ok (cert != NULL, "Failed creating cert at %08x, last error: %x\n", cur_flag, GetLastError());
2110 if (cert)
2111 {
2113 ok (ret, "Failed to add cert at %08x, last error: %x\n", cur_flag, GetLastError());
2114
2116 ok (cert2 != NULL && cert2->cbCertEncoded == cert->cbCertEncoded,
2117 "Unexpected cert encoded size at %08x, last error: %x\n", cur_flag, GetLastError());
2118
2120 ok (ret, "Failed to delete certificate from the new store at %08x, last error: %x\n", cur_flag, GetLastError());
2121
2123 }
2124
2125 ret = CertCloseStore(hstore, 0);
2126 ok (ret, "CertCloseStore failed at %08x, last error %x\n", cur_flag, GetLastError());
2127
2128 ret = CertUnregisterSystemStore(WineTestW, cur_flag );
2131 "Unregistering failed at %08x, last error %d\n", cur_flag, GetLastError());
2132 }
2133
2134}
2135
2137{
2140};
2141
2142static BOOL CALLBACK enumSystemStoreCB(const void *systemStore, DWORD dwFlags,
2143 PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved, void *pvArg)
2144{
2145 struct EnumSystemStoreInfo *info = pvArg;
2146
2147 info->storeCount++;
2148 return info->goOn;
2149}
2150
2152{
2153 BOOL ret;
2154 struct EnumSystemStoreInfo info = { FALSE, 0 };
2155
2156 SetLastError(0xdeadbeef);
2159 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2160 /* Crashes
2161 ret = CertEnumSystemStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, NULL, NULL,
2162 NULL);
2163 */
2164
2165 SetLastError(0xdeadbeef);
2168 /* Callback returning FALSE stops enumeration */
2169 ok(!ret, "Expected CertEnumSystemStore to stop\n");
2170 ok(info.storeCount == 0 || info.storeCount == 1,
2171 "Expected 0 or 1 stores\n");
2172
2173 info.goOn = TRUE;
2174 info.storeCount = 0;
2177 ok(ret, "CertEnumSystemStore failed: %08x\n", GetLastError());
2178 /* There should always be at least My, Root, and CA stores */
2179 ok(info.storeCount == 0 || info.storeCount >= 3,
2180 "Expected at least 3 stores\n");
2181}
2182
2183static void testStoreProperty(void)
2184{
2185 HCERTSTORE store;
2186 BOOL ret;
2187 DWORD propID, size = 0, state;
2189
2190 /* Crash
2191 ret = CertGetStoreProperty(NULL, 0, NULL, NULL);
2192 ret = CertGetStoreProperty(NULL, 0, NULL, &size);
2193 ret = CertGetStoreProperty(store, 0, NULL, NULL);
2194 */
2195
2198 /* Check a missing prop ID */
2199 SetLastError(0xdeadbeef);
2200 ret = CertGetStoreProperty(store, 0, NULL, &size);
2202 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2203 /* Contrary to MSDN, CERT_ACCESS_STATE_PROP_ID is supported for stores.. */
2204 size = sizeof(state);
2206 ok(ret, "CertGetStoreProperty failed for CERT_ACCESS_STATE_PROP_ID: %08x\n",
2207 GetLastError());
2208 ok(!state, "Expected a non-persisted store\n");
2209 /* and CERT_STORE_LOCALIZED_NAME_PROP_ID isn't supported by default. */
2210 size = 0;
2212 &size);
2214 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2215 /* Delete an arbitrary property on a store */
2217 ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError());
2218 /* Set an arbitrary property on a store */
2219 blob.pbData = (LPBYTE)&state;
2220 blob.cbData = sizeof(state);
2222 ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError());
2223 /* Get an arbitrary property that's been set */
2225 ok(ret, "CertGetStoreProperty failed: %08x\n", GetLastError());
2226 ok(size == sizeof(state), "Unexpected data size %d\n", size);
2228 ok(ret, "CertGetStoreProperty failed: %08x\n", GetLastError());
2229 ok(propID == state, "CertGetStoreProperty got the wrong value\n");
2230 /* Delete it again */
2232 ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError());
2233 /* And check that it's missing */
2234 SetLastError(0xdeadbeef);
2237 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2238 CertCloseStore(store, 0);
2239
2240 /* Recheck on the My store.. */
2241 store = CertOpenSystemStoreW(0, MyW);
2242 size = sizeof(state);
2244 ok(ret, "CertGetStoreProperty failed for CERT_ACCESS_STATE_PROP_ID: %08x\n",
2245 GetLastError());
2246 ok(state, "Expected a persisted store\n");
2247 SetLastError(0xdeadbeef);
2248 size = 0;
2250 &size);
2252 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2253 CertCloseStore(store, 0);
2254}
2255
2256static void testAddSerialized(void)
2257{
2258 BOOL ret;
2259 HCERTSTORE store;
2260 BYTE buf[sizeof(struct CertPropIDHeader) * 2 + 20 + sizeof(bigCert)] =
2261 { 0 };
2262 BYTE hash[20];
2263 struct CertPropIDHeader *hdr;
2265
2266 ret = CertAddSerializedElementToStore(0, NULL, 0, 0, 0, 0, NULL, NULL);
2268 "Expected ERROR_END_OF_MEDIA, got %08x\n", GetLastError());
2269
2272 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError());
2273
2274 ret = CertAddSerializedElementToStore(store, NULL, 0, 0, 0, 0, NULL, NULL);
2276 "Expected ERROR_END_OF_MEDIA, got %08x\n", GetLastError());
2277
2278 /* Test with an empty property */
2279 hdr = (struct CertPropIDHeader *)buf;
2280 hdr->propID = CERT_CERT_PROP_ID;
2281 hdr->unknown1 = 1;
2282 hdr->cb = 0;
2283 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0, 0,
2284 NULL, NULL);
2286 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2287 /* Test with a bad size in property header */
2288 hdr->cb = sizeof(bigCert) - 1;
2289 memcpy(buf + sizeof(struct CertPropIDHeader), bigCert, sizeof(bigCert));
2290 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0, 0,
2291 NULL, NULL);
2293 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2295 sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0, 0, NULL,
2296 NULL);
2298 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2300 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW,
2301 0, 0, NULL, NULL);
2303 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2304 /* Kosher size in property header, but no context type */
2305 hdr->cb = sizeof(bigCert);
2306 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0, 0,
2307 NULL, NULL);
2309 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2311 sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0, 0, NULL,
2312 NULL);
2314 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2316 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW,
2317 0, 0, NULL, NULL);
2319 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2320 /* With a bad context type */
2321 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0,
2324 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2326 sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0,
2329 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2331 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW,
2334 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2335 /* Bad unknown field, good type */
2336 hdr->unknown1 = 2;
2337 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0,
2340 "Expected ERROR_FILE_NOT_FOUND got %08x\n", GetLastError());
2342 sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0,
2345 "Expected ERROR_FILE_NOT_FOUND got %08x\n", GetLastError());
2347 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW,
2350 "Expected ERROR_FILE_NOT_FOUND got %08x\n", GetLastError());
2351 /* Most everything okay, but bad add disposition */
2352 hdr->unknown1 = 1;
2353 /* This crashes
2354 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0,
2355 CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
2356 * as does this
2357 ret = CertAddSerializedElementToStore(store, buf,
2358 sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0,
2359 CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
2360 */
2361 /* Everything okay, but buffer's too big */
2362 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf),
2364 ok(ret, "CertAddSerializedElementToStore failed: %08x\n", GetLastError());
2365 /* Everything okay, check it's not re-added */
2367 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW,
2370 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
2371
2373 ok(context != NULL, "Expected a cert\n");
2374 if (context)
2376
2377 /* Try adding with a bogus hash. Oddly enough, it succeeds, and the hash,
2378 * when queried, is the real hash rather than the bogus hash.
2379 */
2380 hdr = (struct CertPropIDHeader *)(buf + sizeof(struct CertPropIDHeader) +
2381 sizeof(bigCert));
2382 hdr->propID = CERT_HASH_PROP_ID;
2383 hdr->unknown1 = 1;
2384 hdr->cb = sizeof(hash);
2385 memset(hash, 0xc, sizeof(hash));
2386 memcpy((LPBYTE)hdr + sizeof(struct CertPropIDHeader), hash, sizeof(hash));
2387 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf),
2389 (const void **)&context);
2390 ok(ret, "CertAddSerializedElementToStore failed: %08x\n", GetLastError());
2391 if (context)
2392 {
2393 BYTE hashVal[20], realHash[20];
2394 DWORD size = sizeof(hashVal);
2395
2396 ret = CryptHashCertificate(0, 0, 0, bigCert, sizeof(bigCert),
2397 realHash, &size);
2398 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
2400 hashVal, &size);
2401 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2402 GetLastError());
2403 ok(!memcmp(hashVal, realHash, size), "Unexpected hash\n");
2405 }
2406
2407 CertCloseStore(store, 0);
2408}
2409
24110x0b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x57,0x00,0x69,
24120x00,0x6e,0x00,0x65,0x00,0x54,0x00,0x65,0x00,0x73,0x00,0x74,0x00,0x00,0x00,
24130x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,
24140x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
24150x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
24160x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
24170x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
24180x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
24190x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,
24200x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
24210x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
24220x01 };
24240x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x0b,0x00,0x00,0x00,0x01,0x00,0x00,
24250x00,0x12,0x00,0x00,0x00,0x57,0x00,0x69,0x00,0x6e,0x00,0x65,0x00,0x54,0x00,
24260x65,0x00,0x73,0x00,0x74,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x01,0x00,0x00,
24270x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
24280x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
24290x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
24300x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
24310x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
24320x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
24330x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
24340xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
24350x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
24360x00,0x00,0x00,0x00,0x00,0x00 };
24380x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x03,0x00,0x00,0x00,0x01,0x00,0x00,
24390x00,0x14,0x00,0x00,0x00,0x6e,0x30,0x90,0x71,0x5f,0xd9,0x23,0x56,0xeb,0xae,
24400x25,0x40,0xe6,0x22,0xda,0x19,0x26,0x02,0xa6,0x08,0x20,0x00,0x00,0x00,0x01,
24410x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,
24420x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
24430x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
24440x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
24450x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
24460x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
24470x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,
24480x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
24490xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,
24500x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
2451
2452static void delete_test_key(void)
2453{
2454 HKEY root_key, test_key;
2455 static const WCHAR SysCertW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
2456 'S','y','s','t','e','m','C','e','r','t','i','f','i','c','a','t','e','s',0};
2457 static const WCHAR WineTestW[] = {'W','i','n','e','T','e','s','t',0};
2458 WCHAR subkey_name[32];
2459 DWORD num_subkeys, subkey_name_len;
2460 int idx;
2461
2462 if (RegOpenKeyExW(HKEY_CURRENT_USER, SysCertW, 0, KEY_READ, &root_key))
2463 return;
2464 if (RegOpenKeyExW(root_key, WineTestW, 0, KEY_READ, &test_key))
2465 {
2466 RegCloseKey(root_key);
2467 return;
2468 }
2469 RegQueryInfoKeyW(test_key, NULL, NULL, NULL, &num_subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
2470 for (idx = num_subkeys; idx-- > 0;)
2471 {
2472 subkey_name_len = ARRAY_SIZE(subkey_name);
2473 RegEnumKeyExW(test_key, idx, subkey_name, &subkey_name_len, NULL, NULL, NULL, NULL);
2474 RegDeleteKeyW(test_key, subkey_name);
2475 }
2476 RegCloseKey(test_key);
2477 RegDeleteKeyW(root_key, WineTestW);
2478 RegCloseKey(root_key);
2479}
2480
2481static void testAddCertificateLink(void)
2482{
2483 BOOL ret;
2484 HCERTSTORE store1, store2;
2485 PCCERT_CONTEXT source, linked;
2486 DWORD size;
2487 LPBYTE buf;
2489 static const WCHAR szPrefix[] = { 'c','e','r',0 };
2490 static const WCHAR szDot[] = { '.',0 };
2491 static const WCHAR WineTestW[] = { 'W','i','n','e','T','e','s','t',0 };
2492 WCHAR filename1[MAX_PATH], filename2[MAX_PATH];
2493 HANDLE file;
2494
2495 if (0)
2496 {
2497 /* Crashes, i.e. the store is dereferenced without checking. */
2499 }
2500
2501 /* Adding a certificate link to a store requires a valid add disposition */
2504 SetLastError(0xdeadbeef);
2507 "expected E_INVALIDARG, got %08x\n", GetLastError());
2509 sizeof(bigCert));
2510 SetLastError(0xdeadbeef);
2513 "expected E_INVALIDARG, got %08x\n", GetLastError());
2515 NULL);
2516 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
2517 if (0)
2518 {
2519 /* Crashes, i.e. the source certificate is dereferenced without
2520 * checking when a valid add disposition is given.
2521 */
2523 NULL);
2524 }
2525 CertCloseStore(store1, 0);
2526
2530 &linked);
2531 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
2532 if (ret)
2533 {
2534 ok(linked->hCertStore == store1, "unexpected store\n");
2536 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
2537 GetLastError());
2539 if (buf)
2540 {
2542 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
2543 GetLastError());
2544 /* The serialized linked certificate is identical to the serialized
2545 * original certificate.
2546 */
2547 ok(size == sizeof(serializedCert), "Wrong size %d\n", size);
2549 "Unexpected serialized cert\n");
2551 }
2552 /* Set a friendly name on the source certificate... */
2553 blob.pbData = (LPBYTE)WineTestW;
2554 blob.cbData = sizeof(WineTestW);
2557 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
2558 GetLastError());
2559 /* and the linked certificate has the same friendly name. */
2562 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2563 GetLastError());
2565 if (buf)
2566 {
2569 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2570 GetLastError());
2571 ok(!lstrcmpW((LPCWSTR)buf, WineTestW),
2572 "unexpected friendly name\n");
2574 }
2576 }
2578 CertCloseStore(store1, 0);
2579
2580 /* Test adding a cert to a file store, committing the change to the store,
2581 * and creating a link to the resulting cert.
2582 */
2583 if (!GetTempFileNameW(szDot, szPrefix, 0, filename1))
2584 return;
2585
2586 DeleteFileW(filename1);
2587 file = CreateFileW(filename1, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2590 return;
2591
2592 store1 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
2594 ok(store1 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2596
2599 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
2600 GetLastError());
2601
2602 /* Test adding a link to a memory store. */
2606 &linked);
2607 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
2608 if (ret)
2609 {
2610 ok(linked->hCertStore == store2, "unexpected store\n");
2612 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
2613 GetLastError());
2615 if (buf)
2616 {
2618 /* The serialized linked certificate is identical to the serialized
2619 * original certificate.
2620 */
2621 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", GetLastError());
2622 ok(size == sizeof(serializedCert), "Wrong size %d\n", size);
2624 "Unexpected serialized cert\n");
2626 }
2627 /* Set a friendly name on the source certificate... */
2628 blob.pbData = (LPBYTE)WineTestW;
2629 blob.cbData = sizeof(WineTestW);
2632 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
2633 GetLastError());
2634 /* and the linked certificate has the same friendly name. */
2637 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2638 GetLastError());
2640 if (buf)
2641 {
2644 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
2645 ok(!lstrcmpW((LPCWSTR)buf, WineTestW),
2646 "unexpected friendly name\n");
2648 }
2650 }
2651 CertCloseStore(store2, 0);
2652
2653 if (!GetTempFileNameW(szDot, szPrefix, 0, filename2))
2654 return;
2655
2660 return;
2661
2662 store2 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
2664 ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2666 /* Test adding a link to a file store. */
2668 &linked);
2669 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
2670 if (ret)
2671 {
2672 ok(linked->hCertStore == store2, "unexpected store\n");
2674 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
2675 GetLastError());
2677 if (buf)
2678 {
2680 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
2681 GetLastError());
2682 /* The serialized linked certificate now contains the friendly
2683 * name property.
2684 */
2686 "Wrong size %d\n", size);
2688 "Unexpected serialized cert\n");
2690 }
2692 compareStore(store2, "file store -> file store",
2695 }
2696 CertCloseStore(store2, 0);
2698
2700
2701 CertCloseStore(store1, 0);
2702 DeleteFileW(filename1);
2703
2704 /* Test adding a link to a system store (which is a collection store.) */
2705 store1 = CertOpenSystemStoreA(0, "My");
2707 sizeof(bigCert));
2708 SetLastError(0xdeadbeef);
2710 &linked);
2712 "expected E_INVALIDARG, got %08x\n", GetLastError());
2714
2715 /* Test adding a link to a file store, where the linked certificate is
2716 * in a system store.
2717 */
2720 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
2721 GetLastError());
2722 if (!GetTempFileNameW(szDot, szPrefix, 0, filename1))
2723 return;
2724
2725 DeleteFileW(filename1);
2726 file = CreateFileW(filename1, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2729 return;
2730
2731 store2 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
2733 ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2735
2737 &linked);
2738 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
2739 if (ret)
2740 {
2741 ok(linked->hCertStore == store2, "unexpected store\n");
2743 ok(ret, "CertControlStore failed: %d\n", ret);
2744 compareStore(store2, "file store -> system store",
2748 }
2749
2750 CertCloseStore(store2, 0);
2751 DeleteFileW(filename1);
2752
2753 /* Test adding a link to a registry store, where the linked certificate is
2754 * in a system store.
2755 */
2758 ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2760 &linked);
2761 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
2762 if (ret)
2763 {
2764 ok(linked->hCertStore == store2, "unexpected store\n");
2766 }
2767 CertCloseStore(store2, 0);
2768
2770 CertCloseStore(store1, 0);
2771
2773}
2774
2776{
2778 DWORD certs = 0;
2779
2780 do {
2782 if (cert)
2783 certs++;
2784 } while (cert);
2785 return certs;
2786}
2787
2789{
2791 DWORD crls = 0;
2792
2793 do {
2794 crl = CertEnumCRLsInStore(store, crl);
2795 if (crl)
2796 crls++;
2797 } while (crl);
2798 return crls;
2799}
2800
2801static void testEmptyStore(void)
2802{
2803 const CERT_CONTEXT *cert, *cert2, *cert3;
2804 const CRL_CONTEXT *crl;
2805 const CTL_CONTEXT *ctl;
2806 HCERTSTORE store;
2807 BOOL res;
2808
2810 ok(cert != NULL, "CertCreateCertificateContext failed\n");
2811 ok(cert->hCertStore != NULL, "cert->hCertStore == NULL\n");
2812 if(!cert->hCertStore) {
2814 return;
2815 }
2816
2817 test_store_is_empty(cert->hCertStore);
2818
2820 ok(cert2 != NULL, "CertCreateCertificateContext failed\n");
2821 ok(cert2->hCertStore == cert->hCertStore, "Unexpected hCertStore\n");
2822
2823 test_store_is_empty(cert2->hCertStore);
2824
2826 ok(res, "CertAddCertificateContextToStore failed\n");
2827 todo_wine
2828 ok(cert3 && cert3 != cert2, "Unexpected cert3\n");
2829 ok(cert3->hCertStore == cert->hCertStore, "Unexpected hCertStore\n");
2830
2831 test_store_is_empty(cert->hCertStore);
2832
2834 ok(res, "CertDeleteCertificateContextFromStore failed\n");
2835 ok(cert3->hCertStore == cert->hCertStore, "Unexpected hCertStore\n");
2836
2838
2840 ok(store != NULL, "CertOpenStore failed\n");
2841
2843 ok(res, "CertAddCertificateContextToStore failed\n");
2844 ok(cert3 && cert3 != cert2, "Unexpected cert3\n");
2845 ok(cert3->hCertStore == store, "Unexpected hCertStore\n");
2846
2848 ok(res, "CertDeleteCertificateContextFromStore failed\n");
2849 ok(cert3->hCertStore == store, "Unexpected hCertStore\n");
2850
2851 CertCloseStore(store, 0);
2853
2855 ok(!res && GetLastError() == E_UNEXPECTED, "CertCloseStore returned: %x(%x)\n", res, GetLastError());
2856
2857 res = CertCloseStore(cert->hCertStore, 0);
2858 ok(!res && GetLastError() == E_UNEXPECTED, "CertCloseStore returned: %x(%x)\n", res, GetLastError());
2859
2861
2863 ok(crl != NULL, "CertCreateCRLContext failed\n");
2864 ok(crl->hCertStore == cert->hCertStore, "unexpected hCertStore\n");
2865
2867
2869 ok(ctl != NULL, "CertCreateCTLContext failed\n");
2870 ok(ctl->hCertStore == cert->hCertStore, "unexpected hCertStore\n");
2871
2872 CertFreeCTLContext(ctl);
2873
2875}
2876
2877static void testCloseStore(void)
2878{
2879 const CERT_CONTEXT *cert;
2880 const CRL_CONTEXT *crl;
2881 const CTL_CONTEXT *ctl;
2882 HCERTSTORE store, store2;
2883 BOOL res;
2884
2886 ok(store != NULL, "CertOpenStore failed\n");
2887
2889 ok(res, "CertCloseStore failed\n");
2890
2892 ok(store != NULL, "CertOpenStore failed\n");
2893
2894 store2 = CertDuplicateStore(store);
2895 ok(store2 != NULL, "CertCloneStore failed\n");
2896 ok(store2 == store, "unexpected store2\n");
2897
2899 ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
2900
2902 ok(res, "CertCloseStore failed\n");
2903
2905 ok(store != NULL, "CertOpenStore failed\n");
2906
2909 ok(res, "CertAddEncodedCertificateToStore failed\n");
2910
2911 /* There is still a reference from cert */
2913 ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
2914
2916 ok(res, "CertFreeCertificateContext failed\n");
2917
2919 ok(store != NULL, "CertOpenStore failed\n");
2920
2923 ok(res, "CertAddEncodedCRLToStore failed\n");
2924
2925 /* There is still a reference from CRL */
2927 ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
2928
2930 ok(res, "CertFreeCRLContext failed\n");
2931
2933 ok(store != NULL, "CertOpenStore failed\n");
2934
2937 ok(res, "CertAddEncodedCTLToStore failed\n");
2938
2939 /* There is still a reference from CTL */
2941 ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore returned: %x(%u)\n", res, GetLastError());
2942
2943 res = CertFreeCTLContext(ctl);
2944 ok(res, "CertFreeCTLContext failed\n");
2945
2946 /* Add all kinds of contexts, then release external references and make sure that store is properly closed. */
2948 ok(store != NULL, "CertOpenStore failed\n");
2949
2952 ok(res, "CertAddEncodedCertificateToStore failed\n");
2953
2956 ok(res, "CertAddEncodedCRLToStore failed\n");
2957
2960 ok(res, "CertAddEncodedCTLToStore failed\n");
2961
2964 CertFreeCTLContext(ctl);
2965
2967 ok(res, "CertCloseStore failed\n");
2968}
2969
2970static void test_I_UpdateStore(void)
2971{
2972 HMODULE lib = GetModuleHandleA("crypt32");
2973 BOOL (WINAPI *pI_CertUpdatestore)(HCERTSTORE, HCERTSTORE, DWORD, DWORD) =
2974 (void *)GetProcAddress(lib, "I_CertUpdateStore");
2975 BOOL ret;
2976 HCERTSTORE store1, store2;
2978 DWORD certs;
2979
2980 if (!pI_CertUpdatestore)
2981 {
2982 win_skip("No I_CertUpdateStore\n");
2983 return;
2984 }
2989
2990 /* Crash
2991 ret = pI_CertUpdatestore(NULL, NULL, 0, 0);
2992 ret = pI_CertUpdatestore(store1, NULL, 0, 0);
2993 ret = pI_CertUpdatestore(NULL, store2, 0, 0);
2994 */
2995 ret = pI_CertUpdatestore(store1, store2, 0, 0);
2996 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError());
2997
3000 /* I_CertUpdateStore adds the contexts from store2 to store1 */
3001 ret = pI_CertUpdatestore(store1, store2, 0, 0);
3002 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError());
3003 certs = countCertsInStore(store1);
3004 ok(certs == 1, "Expected 1 cert, got %d\n", certs);
3005 /* Calling it a second time has no effect */
3006 ret = pI_CertUpdatestore(store1, store2, 0, 0);
3007 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError());
3008 certs = countCertsInStore(store1);
3009 ok(certs == 1, "Expected 1 cert, got %d\n", certs);
3010
3011 /* The last parameters to I_CertUpdateStore appear to be ignored */
3012 ret = pI_CertUpdatestore(store1, store2, 1, 0);
3013 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError());
3014 ret = pI_CertUpdatestore(store1, store2, 0, 1);
3015 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError());
3016
3019
3020 /* I_CertUpdateStore also adds the CRLs from store2 to store1 */
3021 ret = pI_CertUpdatestore(store1, store2, 0, 0);
3022 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError());
3023 certs = countCertsInStore(store1);
3024 ok(certs == 1, "Expected 1 cert, got %d\n", certs);
3025 certs = countCRLsInStore(store1);
3026 ok(certs == 1, "Expected 1 CRL, got %d\n", certs);
3027
3029 /* If a context is deleted from store2, I_CertUpdateStore deletes it
3030 * from store1
3031 */
3032 ret = pI_CertUpdatestore(store1, store2, 0, 0);
3033 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError());
3034 certs = countCertsInStore(store1);
3035 ok(certs == 0, "Expected 0 certs, got %d\n", certs);
3036
3037 CertCloseStore(store1, 0);
3038 CertCloseStore(store2, 0);
3039}
3040
3042{
3043 /* various combinations of CertOpenStore */
3044 testMemStore();
3047
3048 testRegStore();
3050
3053 testFileStore();
3058
3060
3064
3067
3069
3071}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static int state
Definition: maze.c:121
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define msg(x)
Definition: auth_time.c:54
#define ARRAY_SIZE(A)
Definition: main.h:20
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define RegCloseKey(hKey)
Definition: registry.h:49
BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore, HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore, HCERTSTORE hSiblingStore)
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4799
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2504
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3662
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
LONG WINAPI RegCreateKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD Reserved, _In_ LPSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_ LPDWORD lpdwDisposition)
Definition: reg.c:1034
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1224
BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT *ppStoreContext)
Definition: cert.c:286
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded)
Definition: cert.c:316
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFlags, DWORD dwType, const void *pvPara, PCCERT_CONTEXT pPrevCertContext)
Definition: cert.c:1765
BOOL WINAPI CertAddCertificateLinkToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext)
Definition: cert.c:296
BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext)
Definition: cert.c:58
BOOL WINAPI CertSetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, DWORD dwFlags, const void *pvData)
Definition: cert.c:799
BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, void *pvData, DWORD *pcbData)
Definition: cert.c:551
PCCERT_CONTEXT WINAPI CertDuplicateCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:360
BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash)
Definition: cert.c:2187
BOOL WINAPI CertFreeCRLContext(PCCRL_CONTEXT pCrlContext)
Definition: crl.c:386
BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded, DWORD dwAddDisposition, PCCRL_CONTEXT *ppCrlContext)
Definition: crl.c:129
PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded)
Definition: crl.c:85
BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCTLContext)
Definition: ctl.c:499
PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded)
Definition: ctl.c:363
BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded, DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext)
Definition: ctl.c:177
HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType, DWORD dwFlags, DWORD dwMsgType, HCRYPTPROV_LEGACY hCryptProv, PCERT_INFO pRecipientInfo, PCMSG_STREAM_INFO pStreamInfo)
Definition: msg.c:3552
BOOL WINAPI CryptMsgGetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType, DWORD dwIndex, void *pvData, DWORD *pcbData)
Definition: msg.c:3626
BOOL WINAPI CryptMsgUpdate(HCRYPTMSG hCryptMsg, const BYTE *pbData, DWORD cbData, BOOL fFinal)
Definition: msg.c:3616
BOOL WINAPI CryptMsgClose(HCRYPTMSG hCryptMsg)
Definition: msg.c:3597
BOOL WINAPI CertRegisterSystemStore(const void *pvSystemStore, DWORD dwFlags, PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved)
Definition: store.c:1393
HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const void *pvPara)
Definition: store.c:815
BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, DWORD dwFlags, const void *pvData)
Definition: store.c:1236
BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara)
Definition: store.c:1149
HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
Definition: store.c:1116
BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara, void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
Definition: store.c:1321
BOOL WINAPI CertUnregisterSystemStore(const void *pvSystemStore, DWORD dwFlags)
Definition: store.c:1416
PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore, PCCRL_CONTEXT pPrev)
Definition: store.c:1101
PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrev)
Definition: store.c:928
HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv, LPCSTR szSubSystemProtocol)
Definition: store.c:904
BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
Definition: store.c:1127
BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, void *pvData, DWORD *pcbData)
Definition: store.c:1172
BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
Definition: store.c:943
HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv, LPCWSTR szSubSystemProtocol)
Definition: store.c:916
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4243
HRESULT WINAPI SHGetFolderPathW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
Definition: shellpath.c:2589
DWORD WINAPI SHDeleteKeyA(HKEY hKey, LPCSTR lpszSubKey)
Definition: reg.c:1533
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define S_OK
Definition: intsafe.h:52
const char * filename
Definition: ioapi.h:137
char hdr[14]
Definition: iptest.cpp:33
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCW