ReactOS  0.4.13-dev-455-g28ed234
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 
47 static const BYTE emptyCert[] = { 0x30, 0x00 };
48 static 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 };
58 static 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 };
71 static 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 };
83 static 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 };
89 static 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 };
100 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
101 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
102 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
103 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
104 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
105 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
106 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
107 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
108 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
109 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
110 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
111 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
112 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
113 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
114 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
115 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
116 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
117 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
118 0x57,0x6c,0x0b,0x47,0xb8 };
119 
120 #define test_store_is_empty(store) _test_store_is_empty(__LINE__,store)
121 static 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 
129 static 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 */
141  store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
144  "Expected ERROR_CALL_NOT_IMPLEMENTED, got %d\n", GetLastError());
145 
146  /* normal */
147  store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
149  ok(store1 != NULL, "CertOpenStore failed: %d\n", GetLastError());
150  /* open existing doesn't */
151  store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
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();
166  GLE == OSS_DATA_ERROR),
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();
192  GLE == OSS_DATA_ERROR),
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());
221  buf = HeapAlloc(GetProcessHeap(), 0, size);
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");
229  HeapFree(GetProcessHeap(), 0, buf);
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  */
282  store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
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 
304 static 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 
328 static const BYTE serializedStoreWithCert[] = {
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 
341 static const struct
342 {
348 } reg_store_saved_certs[] = {
350  {'R','O','O','T',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH },
355  /* Adding to HKCU\Root triggers safety warning. */
360 };
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  */
367 static 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 
485 static 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);
575  todo_wine
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);
584  todo_wine
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 
622 static 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 */
642  store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
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 */
665  store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
667  /* Try adding a store to a non-collection store */
668  ret = CertAddStoreToCollection(store1, store2,
670  ok(!ret && GetLastError() == E_INVALIDARG,
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,
755  ret = CertAddStoreToCollection(collection2, collection,
757  ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError());
758  /* check the contents of collection2 */
759  context = CertEnumCertificatesInStore(collection2, NULL);
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 */
798  store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
800  ok(store1 != 0, "CertOpenStore failed: %08x\n", GetLastError());
801  store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
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  */
939  store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
941  CertAddStoreToCollection(collection, store1, 0, 0);
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 
958  if (file == INVALID_HANDLE_VALUE)
959  return;
960 
961  store1 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
963  ok(store1 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
964  CloseHandle(file);
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  */
984 static const struct CertPropIDHeader *findPropID(const BYTE *buf, DWORD size,
985  DWORD propID)
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 
1015 static 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 
1040  rc = RegCreateKeyExA(HKEY_CURRENT_USER, tempKey, 0, NULL, 0, KEY_ALL_ACCESS,
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);
1083  buf = HeapAlloc(GetProcessHeap(), 0, 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  }
1112  HeapFree(GetProcessHeap(), 0, buf);
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);
1179  ret = CryptHashCertificate(0, 0, 0, bigCert2,
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 
1260  RegCloseKey(key);
1261  }
1262  /* The CertOpenStore with CERT_STORE_DELETE_FLAG above will delete the
1263  * contents of the key, but not the key itself.
1264  */
1265  rc = RegCreateKeyExA(HKEY_CURRENT_USER, tempKey, 0, NULL, 0, KEY_ALL_ACCESS,
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  {
1272  RegCloseKey(key);
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  */
1279  SHDeleteKeyA(HKEY_CURRENT_USER, tempKey);
1280  }
1281  }
1282 }
1283 
1284 static const char MyA[] = { 'M','y',0,0 };
1285 static const WCHAR MyW[] = { 'M','y',0 };
1286 static const WCHAR BogusW[] = { 'B','o','g','u','s',0 };
1287 static 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 
1291 static 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 
1349 static 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());
1360  store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1362  ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1363  "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1364  store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
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 */
1369  store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
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)
1381  RegCloseKey(key);
1382  /* Check opening with a UNICODE name, specifying the create new flag */
1383  store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
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 */
1388  store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
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 */
1407  store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1409  ok(!store, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1410  store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1412  ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError());
1413  if (store)
1414  CertCloseStore(store, 0);
1415  /* Now check whether deleting is allowed */
1416  store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
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 
1440 static 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 
1460  if (file == INVALID_HANDLE_VALUE)
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. */
1494  size = GetFileSize(file, NULL);
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  {
1534  CloseHandle(file);
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  }
1548  if (file == INVALID_HANDLE_VALUE)
1549  return;
1550  store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
1552  ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1553  if (store)
1554  {
1555  CloseHandle(file);
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 
1574  if (file != INVALID_HANDLE_VALUE)
1575  {
1576  DWORD written;
1577 
1578  ret = WriteFile(file, pb, cb, &written, NULL);
1579  CloseHandle(file);
1580  }
1581  else
1582  ret = FALSE;
1583  return ret;
1584 }
1585 
1586 static 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 */
1600 static 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 
1646 static 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 
1656  store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0, 0, NULL);
1657  GLE = GetLastError();
1658  ok(!store && (GLE == ERROR_PATH_NOT_FOUND || GLE == ERROR_INVALID_PARAMETER),
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 */
1673  if (initFileFromData(filename, bigCert, sizeof(bigCert)))
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 
1819 static const BYTE signedContent[] = {
1820 0x30,0x81,0xb2,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
1821 0x81,0xa4,0x30,0x81,0xa1,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
1822 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,
1823 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,
1824 0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,
1825 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1826 0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1827 0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,
1828 0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,
1829 0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,
1830 0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,
1831 0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,
1832 0x0d };
1834 0x30,0x82,0x01,0x4f,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,
1835 0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,
1836 0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0xa0,
1837 0x7c,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
1838 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
1839 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
1840 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
1841 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
1842 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
1843 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,
1844 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
1845 0x01,0xff,0x02,0x01,0x01,0xa1,0x2e,0x30,0x2c,0x30,0x02,0x06,0x00,0x30,0x15,
1846 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
1847 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
1848 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x31,0x77,0x30,0x75,0x02,0x01,0x01,
1849 0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,
1850 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,
1851 0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,
1852 0x00,0x05,0x00,0x04,0x40,0x81,0xa6,0x70,0xb3,0xef,0x59,0xd1,0x66,0xd1,0x9b,
1853 0xc0,0x9a,0xb6,0x9a,0x5e,0x6d,0x6f,0x6d,0x0d,0x59,0xa9,0xaa,0x6e,0xe9,0x2c,
1854 0xa0,0x1e,0xee,0xc2,0x60,0xbc,0x59,0xbe,0x3f,0x63,0x06,0x8d,0xc9,0x11,0x1d,
1855 0x23,0x64,0x92,0xef,0x2e,0xfc,0x57,0x29,0xa4,0xaf,0xe0,0xee,0x93,0x19,0x39,
1856 0x51,0xe4,0x44,0xb8,0x0b,0x28,0xf4,0xa8,0x0d };
1857 static const BYTE hashContent[] = {
1858 0x30,0x47,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x05,0xa0,0x3a,
1859 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1860 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1861 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
1862 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1863 static const BYTE hashBareContent[] = {
1864 0x30,0x38,0x02,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1865 0x02,0x05,0x05,0x00,0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
1866 0x07,0x01,0xa0,0x06,0x04,0x04,0x01,0x02,0x03,0x04,0x04,0x10,0x08,0xd6,0xc0,
1867 0x5a,0x21,0x51,0x2a,0x79,0xa1,0xdf,0xeb,0x9d,0x2a,0x8f,0x26,0x2f };
1868 
1869 static 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);
1884  ok(!store && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
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);
1930  CryptMsgClose(msg);
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);
1971  ok(!store && GetLastError() == CRYPT_E_INVALID_MSG_TYPE,
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 
1981 static void testSerializedStore(void)
1982 {
1983  HCERTSTORE store;
1985 
1986  if (0)
1987  {
1988  /* Crash */
1989  store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 0, NULL);
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 
2040 static void testCertOpenSystemStore(void)
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 
2060 static const struct
2061 {
2062  DWORD cert_store;
2067  /* Following tests could require administrator privileges and thus could be skipped */
2073 };
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 
2142 static 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 
2151 static void testCertEnumSystemStore(void)
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 
2183 static 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 
2196  store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
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 
2256 static 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 
2270  store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
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);
2285  ok(!ret && GetLastError() == E_INVALIDARG,
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);
2292  ok(!ret && GetLastError() == E_INVALIDARG,
2293  "Expected E_INVALIDARG, got %08x\n", GetLastError());
2295  sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0, 0, NULL,
2296  NULL);
2297  ok(!ret && GetLastError() == E_INVALIDARG,
2298  "Expected E_INVALIDARG, got %08x\n", GetLastError());
2300  sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW,
2301  0, 0, NULL, NULL);
2302  ok(!ret && GetLastError() == E_INVALIDARG,
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);
2308  ok(!ret && GetLastError() == E_INVALIDARG,
2309  "Expected E_INVALIDARG, got %08x\n", GetLastError());
2311  sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0, 0, NULL,
2312  NULL);
2313  ok(!ret && GetLastError() == E_INVALIDARG,
2314  "Expected E_INVALIDARG, got %08x\n", GetLastError());
2316  sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW,
2317  0, 0, NULL, NULL);
2318  ok(!ret && GetLastError() == E_INVALIDARG,
2319  "Expected E_INVALIDARG, got %08x\n", GetLastError());
2320  /* With a bad context type */
2321  ret = CertAddSerializedElementToStore(store, buf, sizeof(buf), 0, 0,
2323  ok(!ret && GetLastError() == E_INVALIDARG,
2324  "Expected E_INVALIDARG, got %08x\n", GetLastError());
2326  sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0,
2328  ok(!ret && GetLastError() == E_INVALIDARG,
2329  "Expected E_INVALIDARG, got %08x\n", GetLastError());
2331  sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW,
2333  ok(!ret && GetLastError() == E_INVALIDARG,
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,
2369  ok(!ret && GetLastError() == CRYPT_E_EXISTS,
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 
2411 0x0b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x57,0x00,0x69,
2412 0x00,0x6e,0x00,0x65,0x00,0x54,0x00,0x65,0x00,0x73,0x00,0x74,0x00,0x00,0x00,
2413 0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,
2414 0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
2415 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
2416 0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
2417 0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
2418 0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
2419 0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,
2420 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,
2421 0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,
2422 0x01 };
2424 0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x0b,0x00,0x00,0x00,0x01,0x00,0x00,
2425 0x00,0x12,0x00,0x00,0x00,0x57,0x00,0x69,0x00,0x6e,0x00,0x65,0x00,0x54,0x00,
2426 0x65,0x00,0x73,0x00,0x74,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x01,0x00,0x00,
2427 0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,
2428 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
2429 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,
2430 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,
2431 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,
2432 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
2433 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,
2434 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,
2435 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
2436 0x00,0x00,0x00,0x00,0x00,0x00 };
2438 0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x03,0x00,0x00,0x00,0x01,0x00,0x00,
2439 0x00,0x14,0x00,0x00,0x00,0x6e,0x30,0x90,0x71,0x5f,0xd9,0x23,0x56,0xeb,0xae,
2440 0x25,0x40,0xe6,0x22,0xda,0x19,0x26,0x02,0xa6,0x08,0x20,0x00,0x00,0x00,0x01,
2441 0x00,0x00,0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,
2442 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
2443 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
2444 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
2445 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
2446 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
2447 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,
2448 0x01,0x00,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2449 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,
2450 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
2451 
2452 static 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  {
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);
2479 }
2480 
2481 static 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 */
2502  store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
2504  SetLastError(0xdeadbeef);
2505  ret = CertAddCertificateLinkToStore(store1, NULL, 0, NULL);
2506  ok(!ret && GetLastError() == E_INVALIDARG,
2507  "expected E_INVALIDARG, got %08x\n", GetLastError());
2509  sizeof(bigCert));
2510  SetLastError(0xdeadbeef);
2512  ok(!ret && GetLastError() == E_INVALIDARG,
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 
2527  store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
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());
2538  buf = HeapAlloc(GetProcessHeap(), 0, size);
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");
2550  HeapFree(GetProcessHeap(), 0, buf);
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());
2564  buf = HeapAlloc(GetProcessHeap(), 0, size);
2565  if (buf)
2566  {
2569  ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2570  GetLastError());
2571  ok(!lstrcmpW((LPCWSTR)buf, WineTestW),
2572  "unexpected friendly name\n");
2573  HeapFree(GetProcessHeap(), 0, buf);
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,
2589  if (file == INVALID_HANDLE_VALUE)
2590  return;
2591 
2592  store1 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
2594  ok(store1 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2595  CloseHandle(file);
2596 
2599  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
2600  GetLastError());
2601 
2602  /* Test adding a link to a memory store. */
2603  store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
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());
2614  buf = HeapAlloc(GetProcessHeap(), 0, size);
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");
2625  HeapFree(GetProcessHeap(), 0, buf);
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());
2639  buf = HeapAlloc(GetProcessHeap(), 0, size);
2640  if (buf)
2641  {
2644  ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
2645  ok(!lstrcmpW((LPCWSTR)buf, WineTestW),
2646  "unexpected friendly name\n");
2647  HeapFree(GetProcessHeap(), 0, buf);
2648  }
2650  }
2651  CertCloseStore(store2, 0);
2652 
2653  if (!GetTempFileNameW(szDot, szPrefix, 0, filename2))
2654  return;
2655 
2659  if (file == INVALID_HANDLE_VALUE)
2660  return;
2661 
2662  store2 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
2664  ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2665  CloseHandle(file);
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());
2676  buf = HeapAlloc(GetProcessHeap(), 0, size);
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");
2689  HeapFree(GetProcessHeap(), 0, buf);
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);
2711  ok(!ret && GetLastError() == E_INVALIDARG,
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,
2728  if (file == INVALID_HANDLE_VALUE)
2729  return;
2730 
2731  store2 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
2733  ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2734  CloseHandle(file);
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  */
2757  CERT_SYSTEM_STORE_CURRENT_USER, WineTestW);
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 
2772  delete_test_key();
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 
2801 static 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 
2877 static 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 
2908  sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert);
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 
2922  sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &crl);
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 
2951  sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert);
2952  ok(res, "CertAddEncodedCertificateToStore failed\n");
2953 
2955  sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &crl);
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 
2970 static 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  }
2985  store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
2987  store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
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 
2999  sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert);
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 
3052  testSystemStore();
3053  testFileStore();
3055  testMessageStore();
3057  testCloseStore();
3058 
3060 
3064 
3067 
3068  testEmptyStore();
3069 
3071 }
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
#define CERT_STORE_DELETE_FLAG
Definition: wincrypt.h:2455
#define CRYPT_E_ASN1_BADTAG
Definition: winerror.h:3095
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFlags, DWORD dwType, const void *pvPara, PCCERT_CONTEXT pPrevCertContext)
Definition: cert.c:1765
static void testCloseStore(void)
Definition: store.c:2877
START_TEST(store)
Definition: store.c:3041
#define CERT_SYSTEM_STORE_CURRENT_SERVICE
Definition: wincrypt.h:2328
static const BYTE signedBigCert[]
Definition: store.c:58
static void test_I_UpdateStore(void)
Definition: store.c:2970
disp
Definition: i386-dis.c:3181
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
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:4023
static void testEmptyStore(void)
Definition: store.c:2801
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
#define E_ACCESSDENIED
Definition: winerror.h:2849
#define CRYPT_E_ASN1_CORRUPT
Definition: winerror.h:3087
static const WCHAR BogusW[]
Definition: store.c:1286
static const BYTE serializedCertWithFriendlyName[]
Definition: store.c:2410
#define TRUE
Definition: types.h:120
static void testAddSerialized(void)
Definition: store.c:2256
BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, void *pvData, DWORD *pcbData)
Definition: store.c:1172
#define CloseHandle
Definition: compat.h:398
char hdr[14]
Definition: iptest.cpp:33
static const BYTE crl[]
Definition: message.c:864
static const BYTE serializedStoreWithCertAndCRL[]
Definition: store.c:1422
static const WCHAR MyW[]
Definition: store.c:1285
#define CERT_STORE_CTRL_RESYNC
Definition: wincrypt.h:2820
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define CRYPT_E_NOT_FOUND
Definition: winerror.h:3007
PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore, PCCRL_CONTEXT pPrev)
Definition: store.c:1101
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define CERT_STORE_PROV_SYSTEM_REGISTRY_W
Definition: wincrypt.h:2263
Definition: image.c:133
static const BYTE bigCert[]
Definition: store.c:48
#define ok_(x1, x2)
static const struct @1587 reg_system_store_test_data[]
Definition: http.c:6587
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_READ
Definition: nt_native.h:1023
BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT *ppStoreContext)
Definition: cert.c:286
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define HKEY_CURRENT_USER
Definition: winreg.h:11
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
#define CERT_STORE_PROV_MSG
Definition: wincrypt.h:2250
static const BYTE hashBareContent[]
Definition: store.c:1863
#define CERT_STORE_CERTIFICATE_CONTEXT_FLAG
Definition: wincrypt.h:2978
BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext)
Definition: cert.c:58
#define CALLBACK
Definition: compat.h:27
#define CERT_STORE_OPEN_EXISTING_FLAG
Definition: wincrypt.h:2465
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1237
#define test_store_is_empty(store)
Definition: store.c:120
HCERTSTORE hCertStore
Definition: wincrypt.h:483
static void testCertOpenSystemStore(void)
Definition: store.c:2040
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define CERT_STORE_LOCALIZED_NAME_PROP_ID
Definition: wincrypt.h:2830
static const BYTE hashVal[]
Definition: message.c:650
#define CRYPT_E_EXISTS
Definition: winerror.h:3008
#define PKCS_7_ASN_ENCODING
Definition: wincrypt.h:2299
static void testSerializedStore(void)
Definition: store.c:1981
DWORD propID
Definition: store.c:42
HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv, LPCWSTR szSubSystemProtocol)
Definition: store.c:916
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
#define CERT_STORE_ADD_NEW
Definition: wincrypt.h:2482
BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore, HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
#define CERT_FIRST_USER_PROP_ID
Definition: wincrypt.h:2748
static const BYTE cert1[]
Definition: message.c:828
const char * filename
Definition: ioapi.h:135
BOOL WINAPI CertRegisterSystemStore(const void *pvSystemStore, DWORD dwFlags, PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved)
Definition: store.c:1393
#define CERT_STORE_CTRL_COMMIT
Definition: wincrypt.h:2822
#define BOOL
Definition: nt_native.h:43
#define CERT_STORE_PROV_FILENAME_W
Definition: wincrypt.h:2257
#define DWORD
Definition: nt_native.h:44
BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded, DWORD dwAddDisposition, PCCRL_CONTEXT *ppCrlContext)
Definition: crl.c:129
#define CERT_STORE_PROV_COLLECTION
Definition: wincrypt.h:2261
#define CERT_FILE_STORE_COMMIT_ENABLE_FLAG
Definition: wincrypt.h:2475
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:1091
#define CERT_SYSTEM_STORE_LOCAL_MACHINE
Definition: wincrypt.h:2326
BOOL WINAPI PathAppendW(LPWSTR lpszPath, LPCWSTR lpszAppend)
Definition: path.c:121
HCRYPTMSG WINAPI CryptMsgOpenToDecode(DWORD dwMsgEncodingType, DWORD dwFlags, DWORD dwMsgType, HCRYPTPROV_LEGACY hCryptProv, PCERT_INFO pRecipientInfo, PCMSG_STREAM_INFO pStreamInfo)
Definition: msg.c:3553
static void compareStore(HCERTSTORE store, LPCSTR name, const BYTE *pb, DWORD cb, BOOL todo)
Definition: store.c:304
static const WCHAR CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH[]
Definition: wincrypt.h:2356
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static void testStoresInCollection(void)
Definition: store.c:485
#define X509_ASN_ENCODING
Definition: wincrypt.h:2297
#define CERT_ACCESS_STATE_PROP_ID
Definition: wincrypt.h:2700
PCCTL_CONTEXT WINAPI CertCreateCTLContext(DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded)
Definition: ctl.c:363
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
static void testAddCertificateLink(void)
Definition: store.c:2481
BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, void *pvData, DWORD *pcbData)
Definition: cert.c:551
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
#define CERT_STORE_CREATE_NEW_FLAG
Definition: wincrypt.h:2464
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
int hash
Definition: main.c:58
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
DWORD unknown1
Definition: store.c:43
#define GENERIC_WRITE
Definition: nt_native.h:90
static PVOID ptr
Definition: dispmode.c:27
static void testSystemStore(void)
Definition: store.c:1349
#define ok(value,...)
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
Definition: store.c:943
unsigned int idx
Definition: utils.c:41
#define E_INVALIDARG
Definition: ddrawi.h:101
#define CERT_STORE_PROV_MEMORY
Definition: wincrypt.h:2251
struct reiserfs_key root_key
smooth NULL
Definition: ftsmooth.c:416
static char filename2[]
Definition: lzexpand_main.c:51
#define CRYPT_E_INVALID_MSG_TYPE
Definition: winerror.h:2988
BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
Definition: store.c:1127
static void testCertEnumSystemStore(void)
Definition: store.c:2151
BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara)
Definition: store.c:1149
#define CERT_STORE_ADD_REPLACE_EXISTING
Definition: wincrypt.h:2484
Definition: parser.c:48
static BYTE cert[]
Definition: msg.c:1437
#define CERT_FRIENDLY_NAME_PROP_ID
Definition: wincrypt.h:2697
static BOOL CALLBACK enumSystemStoreCB(const void *systemStore, DWORD dwFlags, PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved, void *pvArg)
Definition: store.c:2142
const char * LPCSTR
Definition: xmlstorage.h:183
DWORD cbCertEncoded
Definition: wincrypt.h:481
static void testRegStore(void)
Definition: store.c:1015
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static const BYTE signedCRL[]
Definition: store.c:83
static const BYTE serializedCert[]
Definition: store.c:71
#define OPEN_EXISTING
Definition: compat.h:426
BOOL appdata_file
Definition: store.c:345
static const char MyA[]
Definition: store.c:1284
HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
Definition: store.c:1116
#define todo_wine_if(is_todo)
Definition: test.h:155
static const BYTE signedCTLWithCTLInnerContent[]
Definition: store.c:99
GLsizeiptr size
Definition: glext.h:5919
static const BYTE signedWithCertAndCrlBareContent[]
Definition: store.c:1833
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static void testFileStore(void)
Definition: store.c:1440
#define CRYPT_E_ASN1_EOD
Definition: winerror.h:3086
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
static const BYTE serializedStoreWithCertWithFriendlyName[]
Definition: store.c:2423
static LPCSTR DWORD void * pvReserved
Definition: str.c:196
PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded)
Definition: crl.c:85
static void testRegStoreSavedCerts(void)
Definition: store.c:367
#define CSIDL_APPDATA
Definition: shlobj.h:2028
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
const char file[]
Definition: icontest.c:11
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
#define CERT_CERT_PROP_ID
Definition: store.c:36
unsigned long DWORD
Definition: ntddk_ex.h:95
#define CERT_STORE_SAVE_AS_STORE
Definition: wincrypt.h:2646
#define CERT_STORE_PROV_SYSTEM_REGISTRY
Definition: wincrypt.h:2264
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
#define SetLastError(x)
Definition: compat.h:409
#define CMSG_CERT_COUNT_PARAM
Definition: wincrypt.h:3935
static const BYTE cert2[]
Definition: message.c:844
BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara, void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
Definition: store.c:1321
#define CERT_HASH_PROP_ID
Definition: wincrypt.h:2688
static DWORD cb
Definition: integrity.c:41
void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore, HCERTSTORE hSiblingStore)
HKEY key
Definition: store.c:343
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:3686
#define CERT_STORE_READONLY_FLAG
Definition: wincrypt.h:2466
HCERTSTORE hCertStore
Definition: wincrypt.h:748
BOOL WINAPI CertAddEncodedCTLToStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded, DWORD dwAddDisposition, PCCTL_CONTEXT *ppCtlContext)
Definition: ctl.c:177
static void testCollectionStore(void)
Definition: store.c:622
static const BYTE base64SPC[]
Definition: store.c:1586
WCHAR store_name[16]
Definition: store.c:346
int ret
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#define ERROR_BADKEY
Definition: winerror.h:589
#define todo_wine
Definition: test.h:154
static void testCertRegisterSystemStore(void)
Definition: store.c:2075
PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded)
Definition: cert.c:316
BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore, const BYTE *pbElement, DWORD cbElement, DWORD dwAddDisposition, DWORD dwFlags, DWORD dwContextTypeFlags, DWORD *pdwContentType, const void **ppvContext)
Definition: serialize.c:953
#define OSS_DATA_ERROR
Definition: winerror.h:3042
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static const BYTE emptyCert[]
Definition: store.c:47
static int state
Definition: maze.c:121
static const WCHAR szDot[]
Definition: msipriv.h:1113
BOOL WINAPI CertUnregisterSystemStore(const void *pvSystemStore, DWORD dwFlags)
Definition: store.c:1416
static void _test_store_is_empty(unsigned line, HCERTSTORE store)
Definition: store.c:121
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv, LPCSTR szSubSystemProtocol)
Definition: store.c:904
static const BYTE bigCert2[]
Definition: store.c:89
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
unsigned char BYTE
Definition: mem.h:68
#define GENERIC_READ
Definition: compat.h:124
#define CRYPT_E_PENDING_CLOSE
Definition: winerror.h:3018
#define err(...)
#define CERT_FIND_EXISTING
Definition: wincrypt.h:2905
BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCTLContext)
Definition: ctl.c:499
static const BYTE serializedStoreWithCertAndHash[]
Definition: store.c:2437
DWORD cert_store
Definition: store.c:344
PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrev)
Definition: store.c:928
BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId, DWORD dwFlags, const void *pvData)
Definition: store.c:1236
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1222
static BOOL initFileFromData(LPCWSTR filename, const BYTE *pb, DWORD cb)
Definition: store.c:1568
#define CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
Definition: wincrypt.h:2338
#define S_OK
Definition: intsafe.h:59
#define CREATE_ALWAYS
Definition: disk.h:72
DWORD WINAPI SHDeleteKeyA(HKEY hKey, LPCSTR lpszSubKey)
Definition: reg.c:1533
BOOL todo
Definition: store.c:2064
BOOL WINAPI CertSaveStore(HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType, DWORD dwSaveAs, DWORD dwSaveTo, void *pvSaveToPara, DWORD dwFlags)
Definition: serialize.c:895
#define CERT_STORE_PROV_SYSTEM_W
Definition: wincrypt.h:2259
#define CERT_STORE_CRL_CONTEXT_FLAG
Definition: wincrypt.h:2980
#define CERT_STORE_SAVE_TO_MEMORY
Definition: wincrypt.h:2650
#define CERT_STORE_PROV_PKCS7
Definition: wincrypt.h:2254
static const struct @1586 reg_store_saved_certs[]
#define lstrcpyW
Definition: compat.h:406
#define ERROR_END_OF_MEDIA
Definition: winerror.h:636
static void testFileNameStore(void)
Definition: store.c:1646
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
static ICollection collection
Definition: typelib.c:184
#define ARRAY_SIZE(a)
Definition: main.h:24
#define CERT_SYSTEM_STORE_CURRENT_USER
Definition: wincrypt.h:2324
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define CERT_STORE_PROV_REG
Definition: wincrypt.h:2253
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define CERT_STORE_PROV_SERIALIZED
Definition: wincrypt.h:2255
DWORD cb
Definition: store.c:44
#define CERT_STORE_PROV_FILE
Definition: wincrypt.h:2252
static const BYTE hashContent[]
Definition: store.c:1857
PCCERT_CONTEXT WINAPI CertDuplicateCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:360
static DWORD countCertsInStore(HCERTSTORE store)
Definition: store.c:2775
HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider, DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const void *pvPara)
Definition: store.c:815
BOOL WINAPI CertSerializeCertificateStoreElement(PCCERT_CONTEXT pCertContext, DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
Definition: serialize.c:144
static void delete_test_key(void)
Definition: store.c:2452
#define E_UNEXPECTED
Definition: winerror.h:2456
#define CreateFileW
Definition: compat.h:400
#define skip(...)
static DWORD countCRLsInStore(HCERTSTORE store)
Definition: store.c:2788
BOOL WINAPI CryptMsgClose(HCRYPTMSG hCryptMsg)
Definition: msg.c:3598
#define msg(x)
Definition: auth_time.c:54
static void testSystemRegStore(void)
Definition: store.c:1291
HRESULT WINAPI SHGetFolderPathW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
Definition: shellpath.c:2085
Definition: name.c:36
BOOL WINAPI CryptMsgUpdate(HCRYPTMSG hCryptMsg, const BYTE *pbData, DWORD cbData, BOOL fFinal)
Definition: msg.c:3617
GLuint res
Definition: glext.h:9613
BOOL WINAPI CertAddCertificateLinkToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext)
Definition: cert.c:296
static const BYTE serializedStoreWithCert[]
Definition: store.c:328
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
static void testStoreProperty(void)
Definition: store.c:2183