wined3d: Pass a wined3d_device_context to wined3d_cs_emit_blt_sub_resource().
[wine/zf.git] / dlls / crypt32 / tests / store.c
blob46c9102686d6b5643cedbd60049cc60a54c70eaf
1 /*
2 * crypt32 cert store function tests
4 * Copyright 2005-2006 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdio.h>
22 #include <stdarg.h>
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>
33 #include "wine/test.h"
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
40 struct CertPropIDHeader
42 DWORD propID;
43 DWORD unknown1;
44 DWORD cb;
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 };
99 static const BYTE signedCTLWithCTLInnerContent[] = {
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 };
120 #define test_store_is_empty(store) _test_store_is_empty(__LINE__,store)
121 static void _test_store_is_empty(unsigned line, HCERTSTORE store)
123 const CERT_CONTEXT *cert;
125 cert = CertEnumCertificatesInStore(store, NULL);
126 ok_(__FILE__,line)(!cert && GetLastError() == CRYPT_E_NOT_FOUND, "store is not empty\n");
129 static void testMemStore(void)
131 HCERTSTORE store1, store2;
132 PCCERT_CONTEXT context;
133 BOOL ret;
134 DWORD GLE;
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,
142 CERT_STORE_DELETE_FLAG, NULL);
143 ok(!store1 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
144 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %d\n", GetLastError());
146 /* normal */
147 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
148 CERT_STORE_CREATE_NEW_FLAG, NULL);
149 ok(store1 != NULL, "CertOpenStore failed: %d\n", GetLastError());
150 /* open existing doesn't */
151 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
152 CERT_STORE_OPEN_EXISTING_FLAG, NULL);
153 ok(store2 != NULL, "CertOpenStore failed: %d\n", GetLastError());
154 ok(store1 != store2, "Expected different stores\n");
156 /* add a bogus (empty) cert */
157 context = NULL;
158 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, emptyCert,
159 sizeof(emptyCert), CERT_STORE_ADD_ALWAYS, &context);
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)
164 GLE = GetLastError();
165 ok(!ret && (GLE == CRYPT_E_ASN1_EOD || GLE == CRYPT_E_ASN1_CORRUPT ||
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
172 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
173 signedBigCert, sizeof(signedBigCert), CERT_STORE_ADD_ALWAYS, &context);
174 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
175 ok(context != NULL, "Expected a valid cert context\n");
176 if (context)
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 */
183 ret = CertDeleteCertificateFromStore(context);
184 ok(ret, "CertDeleteCertificateFromStore failed: %08x\n",
185 GetLastError());
187 /* try adding a "signed" CRL as a cert */
188 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
189 signedCRL, sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &context);
190 GLE = GetLastError();
191 ok(!ret && (GLE == CRYPT_E_ASN1_BADTAG || GLE == CRYPT_E_ASN1_CORRUPT ||
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 */
196 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, bigCert,
197 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
198 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
199 ok(context != NULL, "Expected a valid cert context\n");
200 if (context)
202 DWORD size;
203 BYTE *buf;
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");
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);
217 /* apparently flags are ignored */
218 ret = CertSerializeCertificateStoreElement(context, 1, NULL, &size);
219 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
220 GetLastError());
221 buf = HeapAlloc(GetProcessHeap(), 0, size);
222 if (buf)
224 ret = CertSerializeCertificateStoreElement(context, 0, buf, &size);
225 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", GetLastError());
226 ok(size == sizeof(serializedCert), "Wrong size %d\n", size);
227 ok(!memcmp(serializedCert, buf, size),
228 "Unexpected serialized cert\n");
229 HeapFree(GetProcessHeap(), 0, buf);
232 ret = CertFreeCertificateContext(context);
233 ok(ret, "CertFreeCertificateContext failed: %08x\n", GetLastError());
235 /* verify the cert's in store1 */
236 context = CertEnumCertificatesInStore(store1, NULL);
237 ok(context != NULL, "Expected a valid context\n");
238 context = CertEnumCertificatesInStore(store1, context);
239 ok(!context && GetLastError() == CRYPT_E_NOT_FOUND,
240 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
241 /* verify store2 (the "open existing" mem store) is still empty */
242 context = CertEnumCertificatesInStore(store2, NULL);
243 ok(!context, "Expected an empty store\n");
244 /* delete the cert from store1, and check it's empty */
245 context = CertEnumCertificatesInStore(store1, NULL);
246 if (context)
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);
255 PCCERT_CONTEXT copy = CertDuplicateCertificateContext(context);
257 ok(copy != NULL, "CertDuplicateCertificateContext failed: %08x\n",
258 GetLastError());
259 ret = CertDeleteCertificateFromStore(context);
260 ok(ret, "CertDeleteCertificateFromStore failed: %08x\n",
261 GetLastError());
262 /* try deleting a copy */
263 ret = CertDeleteCertificateFromStore(copy);
264 ok(ret, "CertDeleteCertificateFromStore failed: %08x\n",
265 GetLastError());
266 /* check that the store is empty */
267 context = CertEnumCertificatesInStore(store1, NULL);
268 ok(!context, "Expected an empty store\n");
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());
279 /* This seems nonsensical, but you can open a read-only mem store, only
280 * it isn't read-only
282 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
283 CERT_STORE_READONLY_FLAG, NULL);
284 ok(store1 != NULL, "CertOpenStore failed: %d\n", GetLastError());
285 /* yep, this succeeds */
286 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, bigCert,
287 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
288 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
289 ok(context != NULL, "Expected a valid cert context\n");
290 if (context)
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");
297 ret = CertDeleteCertificateFromStore(context);
298 ok(ret, "CertDeleteCertificateFromStore failed: %08x\n",
299 GetLastError());
301 CertCloseStore(store1, 0);
304 static void compareStore(HCERTSTORE store, LPCSTR name, const BYTE *pb,
305 DWORD cb, BOOL todo)
307 BOOL ret;
308 CRYPT_DATA_BLOB blob = { 0, NULL };
310 ret = CertSaveStore(store, X509_ASN_ENCODING, CERT_STORE_SAVE_AS_STORE,
311 CERT_STORE_SAVE_TO_MEMORY, &blob, 0);
312 ok(ret, "CertSaveStore failed: %08x\n", GetLastError());
313 todo_wine_if (todo)
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)
319 ret = CertSaveStore(store, X509_ASN_ENCODING, CERT_STORE_SAVE_AS_STORE,
320 CERT_STORE_SAVE_TO_MEMORY, &blob, 0);
321 ok(ret, "CertSaveStore failed: %08x\n", GetLastError());
322 todo_wine_if (todo)
323 ok(!memcmp(pb, blob.pbData, cb), "%s: unexpected value\n", name);
324 HeapFree(GetProcessHeap(), 0, blob.pbData);
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 };
341 static const struct
343 HKEY key;
344 DWORD cert_store;
345 BOOL appdata_file;
346 WCHAR store_name[16];
347 const WCHAR *base_reg_path;
348 } reg_store_saved_certs[] = {
349 { HKEY_LOCAL_MACHINE, CERT_SYSTEM_STORE_LOCAL_MACHINE, FALSE,
350 {'R','O','O','T',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH },
351 { HKEY_LOCAL_MACHINE, CERT_SYSTEM_STORE_LOCAL_MACHINE, FALSE,
352 {'M','Y',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH },
353 { HKEY_LOCAL_MACHINE, CERT_SYSTEM_STORE_LOCAL_MACHINE, FALSE,
354 {'C','A',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH },
355 /* Adding to HKCU\Root triggers safety warning. */
356 { HKEY_CURRENT_USER, CERT_SYSTEM_STORE_CURRENT_USER, TRUE,
357 {'M','Y',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH },
358 { HKEY_CURRENT_USER, CERT_SYSTEM_STORE_CURRENT_USER, FALSE,
359 {'C','A',0}, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH }
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.
367 static void testRegStoreSavedCerts(void)
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};
379 PCCERT_CONTEXT cert1, cert2;
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;
388 for (i = 0; i < ARRAY_SIZE(reg_store_saved_certs); i++)
390 DWORD err;
392 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
393 reg_store_saved_certs[i].cert_store, reg_store_saved_certs[i].store_name);
395 err = GetLastError();
396 if (!store)
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;
402 ok (store!=NULL, "Failed to open the store at %d, %x\n", i, GetLastError());
403 cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
404 ok (cert1 != NULL, "Create cert context failed at %d, %x\n", i, GetLastError());
405 ret = CertAddCertificateContextToStore(store, cert1, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
406 /* Addittional skip per Win7, it allows opening HKLM store, but disallows adding certs */
407 err = GetLastError();
408 if (!ret)
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;
414 ok (ret, "Adding to the store failed at %d, %x\n", i, err);
415 CertFreeCertificateContext(cert1);
416 CertCloseStore(store, 0);
418 wsprintfW(key_name, fmt, reg_store_saved_certs[i].base_reg_path,
419 reg_store_saved_certs[i].store_name, certs, bigCert_hash);
421 if (!reg_store_saved_certs[i].appdata_file)
423 res = RegOpenKeyExW(reg_store_saved_certs[i].key, key_name, 0, KEY_ALL_ACCESS, &key);
424 ok (!res, "The cert hasn't been saved at %d, %x\n", i, GetLastError());
425 if (!res) RegCloseKey(key);
426 } else
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)
433 PathAppendW(appdata_path, ms_certs);
434 PathAppendW(appdata_path, reg_store_saved_certs[i].store_name);
435 PathAppendW(appdata_path, certs);
436 PathAppendW(appdata_path, bigCert_hash);
438 cert_file = CreateFileW(appdata_path, GENERIC_READ, 0, NULL,
439 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 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);
446 /* deleting cert from store */
447 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
448 reg_store_saved_certs[i].cert_store, reg_store_saved_certs[i].store_name);
449 ok (store!=NULL, "Failed to open the store at %d, %x\n", i, GetLastError());
451 cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
452 ok (cert1 != NULL, "Create cert context failed at %d, %x\n", i, GetLastError());
454 cert2 = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
455 CERT_FIND_EXISTING, cert1, NULL);
456 ok (cert2 != NULL, "Failed to find cert in the store at %d, %x\n", i, GetLastError());
458 ret = CertDeleteCertificateFromStore(cert2);
459 ok (ret, "Failed to delete certificate from store at %d, %x\n", i, GetLastError());
461 CertFreeCertificateContext(cert1);
462 CertFreeCertificateContext(cert2);
463 CertCloseStore(store, 0);
465 res = RegOpenKeyExW(reg_store_saved_certs[i].key, key_name, 0, KEY_ALL_ACCESS, &key);
466 ok (res, "The cert's registry entry should be absent at %i, %x\n", i, GetLastError());
467 if (!res) RegCloseKey(key);
469 if (reg_store_saved_certs[i].appdata_file)
471 cert_file = CreateFileW(appdata_path, GENERIC_READ, 0, NULL,
472 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
473 ok (cert_file == INVALID_HANDLE_VALUE,
474 "Cert should have been absent in AppData %d\n", i);
476 CloseHandle(cert_file);
482 * This test checks that certificate falls into correct store of a collection
483 * depending on the access flags and priorities.
485 static void testStoresInCollection(void)
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;
494 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
495 CERT_STORE_CREATE_NEW_FLAG, NULL);
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*/
498 ro_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0,
499 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRO_W);
500 ok(ro_store != NULL, "Failed to init ro store %x\n", GetLastError());
502 ret = CertAddStoreToCollection(collection, ro_store, 0, 1000);
503 ok (ret, "Failed to add read-only store to collection %x\n", GetLastError());
505 cert1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
506 ok (cert1 != NULL, "Create cert context failed %x\n", GetLastError());
507 ret = CertAddCertificateContextToStore(collection, cert1, CERT_STORE_ADD_ALWAYS, NULL);
508 ok (!ret, "Added cert to collection with single read-only store %x\n", GetLastError());
510 /* Add read-write store to collection with the lowest priority*/
511 rw_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0,
512 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW_W);
513 ok (rw_store != NULL, "Failed to open rw store %x\n", GetLastError());
514 ret = CertAddStoreToCollection(collection, rw_store, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
515 ok (ret, "Failed to add rw store to collection %x\n", GetLastError());
516 /** Adding certificate to collection should fall into rw store,
517 * even though prioirty of the ro_store is higher */
518 ret = CertAddCertificateContextToStore(collection, cert1, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
519 ok (ret, "Failed to add cert to the collection %x\n", GetLastError());
521 tcert1 = CertEnumCertificatesInStore(ro_store, NULL);
522 ok (!tcert1, "Read-only ro_store contains cert\n");
524 tcert1 = CertEnumCertificatesInStore(rw_store, NULL);
525 ok (cert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
526 "Unexpected cert in the rw store\n");
527 CertFreeCertificateContext(tcert1);
529 tcert1 = CertEnumCertificatesInStore(collection, NULL);
530 ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
531 "Unexpected cert in the collection\n");
532 CertFreeCertificateContext(tcert1);
534 /** adding one more rw store with higher priority*/
535 rw_store_2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, 0,
536 CERT_SYSTEM_STORE_CURRENT_USER, WineTestRW2_W);
537 ok (rw_store_2 != NULL, "Failed to init second rw store %x\n", GetLastError());
538 ret = CertAddStoreToCollection(collection, rw_store_2, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 50);
539 ok (ret, "Failed to add rw_store_2 to collection %x\n",GetLastError());
541 cert2 = CertCreateCertificateContext(X509_ASN_ENCODING, signedBigCert, sizeof(signedBigCert));
542 ok (cert2 != NULL, "Failed to create cert context %x\n", GetLastError());
543 ret = CertAddCertificateContextToStore(collection, cert2, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
544 ok (ret, "Failed to add cert2 to the store %x\n",GetLastError());
546 /** checking certificates in the stores */
547 tcert1 = CertEnumCertificatesInStore(ro_store, 0);
548 ok (tcert1 == NULL, "Read-only store not empty\n");
550 tcert1 = CertEnumCertificatesInStore(rw_store, NULL);
551 ok (tcert1 && tcert1->cbCertEncoded == cert1->cbCertEncoded,
552 "Unexpected cert in the rw_store\n");
553 CertFreeCertificateContext(tcert1);
555 tcert1 = CertEnumCertificatesInStore(rw_store_2, NULL);
556 ok (tcert1 && tcert1->cbCertEncoded == cert2->cbCertEncoded,
557 "Unexpected cert in the rw_store_2\n");
558 CertFreeCertificateContext(tcert1);
560 /** checking certificates in the collection */
561 tcert1 = CertEnumCertificatesInStore(collection, NULL);
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());
570 /* checking whether certs had been saved */
571 tstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
572 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, WineTestRW_W);
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");
577 CertFreeCertificateContext(tcert1);
578 CertCloseStore(tstore,0);
580 tstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
581 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, WineTestRW2_W);
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");
586 CertFreeCertificateContext(tcert1);
587 CertCloseStore(tstore,0);
589 CertCloseStore(collection,0);
590 CertCloseStore(ro_store,0);
591 CertCloseStore(rw_store,0);
592 CertCloseStore(rw_store_2,0);
594 /* reopening registry stores to check whether certs had been saved */
595 rw_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
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);
600 CertFreeCertificateContext(tcert1);
601 CertCloseStore(rw_store,0);
603 rw_store_2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
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);
608 CertFreeCertificateContext(tcert1);
609 CertCloseStore(rw_store_2,0);
611 CertFreeCertificateContext(cert1);
612 CertFreeCertificateContext(cert2);
613 CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
614 CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRO_W);
615 CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
616 CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRW_W);
617 CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,0,0,
618 CERT_STORE_DELETE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,WineTestRW2_W);
622 static void testCollectionStore(void)
624 HCERTSTORE store1, store2, collection, collection2;
625 PCCERT_CONTEXT context;
626 BOOL ret;
627 static const WCHAR szPrefix[] = { 'c','e','r',0 };
628 static const WCHAR szDot[] = { '.',0 };
629 WCHAR filename[MAX_PATH];
630 HANDLE file;
632 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
633 CERT_STORE_CREATE_NEW_FLAG, NULL);
635 /* Try adding a cert to any empty collection */
636 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING,
637 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
638 ok(!ret && GetLastError() == E_ACCESSDENIED,
639 "Expected E_ACCESSDENIED, got %08x\n", GetLastError());
641 /* Create and add a cert to a memory store */
642 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
643 CERT_STORE_CREATE_NEW_FLAG, NULL);
644 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
645 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
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 */
651 context = CertEnumCertificatesInStore(collection, NULL);
652 ok(context != NULL, "Expected a valid context\n");
653 if (context)
655 ok(context->hCertStore == collection, "Unexpected store\n");
656 CertFreeCertificateContext(context);
658 /* Check that adding to the collection isn't allowed */
659 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING,
660 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_ALWAYS, NULL);
661 ok(!ret && GetLastError() == E_ACCESSDENIED,
662 "Expected E_ACCESSDENIED, got %08x\n", GetLastError());
664 /* Create a new memory store */
665 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
666 CERT_STORE_CREATE_NEW_FLAG, NULL);
667 /* Try adding a store to a non-collection store */
668 ret = CertAddStoreToCollection(store1, store2,
669 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
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);
677 /* This "succeeds"... */
678 ret = CertAddStoreToCollection(collection, 0,
679 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
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);
686 /* Add it to the collection, this time allowing adding */
687 ret = CertAddStoreToCollection(collection, store2,
688 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
689 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError());
690 /* Check that adding to the collection is allowed */
691 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING,
692 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_ALWAYS, NULL);
693 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
694 /* Now check that it was actually added to store2 */
695 context = CertEnumCertificatesInStore(store2, NULL);
696 ok(context != NULL, "Expected a valid context\n");
697 if (context)
699 ok(context->hCertStore == store2, "Unexpected store\n");
700 CertFreeCertificateContext(context);
702 /* Check that the collection has both bigCert and bigCert2. bigCert comes
703 * first because store1 was added first.
705 context = CertEnumCertificatesInStore(collection, NULL);
706 ok(context != NULL, "Expected a valid context\n");
707 if (context)
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");
714 context = CertEnumCertificatesInStore(collection, context);
715 ok(context != NULL, "Expected a valid context\n");
716 if (context)
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");
723 context = CertEnumCertificatesInStore(collection, context);
724 ok(!context, "Unexpected cert\n");
727 /* close store2, and check that the collection is unmodified */
728 CertCloseStore(store2, 0);
729 context = CertEnumCertificatesInStore(collection, NULL);
730 ok(context != NULL, "Expected a valid context\n");
731 if (context)
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");
738 context = CertEnumCertificatesInStore(collection, context);
739 ok(context != NULL, "Expected a valid context\n");
740 if (context)
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");
747 context = CertEnumCertificatesInStore(collection, context);
748 ok(!context, "Unexpected cert\n");
752 /* Adding a collection to a collection is legal */
753 collection2 = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
754 CERT_STORE_CREATE_NEW_FLAG, NULL);
755 ret = CertAddStoreToCollection(collection2, collection,
756 CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
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)
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");
768 context = CertEnumCertificatesInStore(collection2, context);
769 ok(context != NULL, "Expected a valid context\n");
770 if (context)
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");
777 context = CertEnumCertificatesInStore(collection2, context);
778 ok(!context, "Unexpected cert\n");
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.
793 CertCloseStore(store1, 0);
794 CertCloseStore(collection, 0);
795 CertCloseStore(collection2, 0);
797 /* Add the same cert to two memory stores, then put them in a collection */
798 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
799 CERT_STORE_CREATE_NEW_FLAG, NULL);
800 ok(store1 != 0, "CertOpenStore failed: %08x\n", GetLastError());
801 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
802 CERT_STORE_CREATE_NEW_FLAG, NULL);
803 ok(store2 != 0, "CertOpenStore failed: %08x\n", GetLastError());
805 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
806 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
807 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
808 ret = CertAddEncodedCertificateToStore(store2, X509_ASN_ENCODING,
809 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
810 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
811 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
812 CERT_STORE_CREATE_NEW_FLAG, NULL);
813 ok(collection != 0, "CertOpenStore failed: %08x\n", GetLastError());
815 ret = CertAddStoreToCollection(collection, store1, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
816 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError());
817 ret = CertAddStoreToCollection(collection, store2, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
818 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError());
820 /* Check that the collection has two copies of the same cert */
821 context = CertEnumCertificatesInStore(collection, NULL);
822 ok(context != NULL, "Expected a valid context\n");
823 if (context)
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");
830 context = CertEnumCertificatesInStore(collection, context);
831 ok(context != NULL, "Expected a valid context\n");
832 if (context)
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");
839 context = CertEnumCertificatesInStore(collection, context);
840 ok(context == NULL, "Unexpected cert\n");
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)
854 ret = CertDeleteCertificateFromStore(collection, context);
855 printf("ret is %d, GetLastError is %08x\n", ret, GetLastError());
856 CertFreeCertificateContext(context);
860 /* Now check deleting from the collection. */
861 context = CertEnumCertificatesInStore(collection, NULL);
862 ok(context != NULL, "Expected a valid context\n");
863 if (context)
865 CertDeleteCertificateFromStore(context);
866 /* store1 should now be empty */
867 context = CertEnumCertificatesInStore(store1, NULL);
868 ok(!context, "Unexpected cert\n");
869 /* and there should be one certificate in the collection */
870 context = CertEnumCertificatesInStore(collection, NULL);
871 ok(context != NULL, "Expected a valid cert\n");
872 if (context)
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");
880 context = CertEnumCertificatesInStore(collection, context);
881 ok(context == NULL, "Unexpected cert\n");
884 /* Finally, test removing stores from the collection. No return
885 * value, so it's a bit funny to test.
887 /* This crashes
888 * CertRemoveStoreFromCollection(NULL, NULL);
890 /* This "succeeds," no crash, no last error set */
891 SetLastError(0xdeadbeef);
892 CertRemoveStoreFromCollection(store2, collection);
893 ok(GetLastError() == 0xdeadbeef,
894 "Didn't expect an error to be set: %08x\n", GetLastError());
896 /* After removing store2, the collection should be empty */
897 SetLastError(0xdeadbeef);
898 CertRemoveStoreFromCollection(collection, store2);
899 ok(GetLastError() == 0xdeadbeef,
900 "Didn't expect an error to be set: %08x\n", GetLastError());
901 context = CertEnumCertificatesInStore(collection, NULL);
902 ok(!context, "Unexpected cert\n");
904 CertCloseStore(collection, 0);
905 CertCloseStore(store2, 0);
906 CertCloseStore(store1, 0);
908 /* Test adding certificates to and deleting certificates from collections.
910 store1 = CertOpenSystemStoreA(0, "My");
911 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
912 CERT_STORE_CREATE_NEW_FLAG, NULL);
914 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
915 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
916 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
917 CertDeleteCertificateFromStore(context);
919 CertAddStoreToCollection(collection, store1, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
921 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING,
922 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
923 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
924 CertDeleteCertificateFromStore(context);
926 CertCloseStore(collection, 0);
927 CertCloseStore(store1, 0);
929 /* Test whether a collection store can be committed */
930 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
931 CERT_STORE_CREATE_NEW_FLAG, NULL);
933 SetLastError(0xdeadbeef);
934 ret = CertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL);
935 ok(ret, "CertControlStore failed: %08x\n", GetLastError());
937 /* Adding a mem store that can't be committed prevents a successful commit.
939 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
940 CERT_STORE_CREATE_NEW_FLAG, NULL);
941 CertAddStoreToCollection(collection, store1, 0, 0);
942 SetLastError(0xdeadbeef);
943 ret = CertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL);
944 ok(!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
945 "expected ERROR_CALL_NOT_IMPLEMENTED, got %d\n", GetLastError());
946 CertRemoveStoreFromCollection(collection, store1);
947 CertCloseStore(store1, 0);
949 /* Test adding a cert to a collection with a file store, committing the
950 * change to the collection, and comparing the resulting file.
952 if (!GetTempFileNameW(szDot, szPrefix, 0, filename))
953 return;
955 DeleteFileW(filename);
956 file = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
957 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
958 if (file == INVALID_HANDLE_VALUE)
959 return;
961 store1 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
962 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
963 ok(store1 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
964 CloseHandle(file);
965 CertAddStoreToCollection(collection, store1, CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
966 CertCloseStore(store1, 0);
968 ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING,
969 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
970 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
971 GetLastError());
972 ret = CertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL);
973 ok(ret, "CertControlStore failed: %d\n", ret);
974 compareStore(collection, "serialized store with cert",
975 serializedStoreWithCert, sizeof(serializedStoreWithCert), FALSE);
976 CertCloseStore(collection, 0);
978 DeleteFileW(filename);
981 /* Looks for the property with ID propID in the buffer buf. Returns a pointer
982 * to its header if found, NULL if not.
984 static const struct CertPropIDHeader *findPropID(const BYTE *buf, DWORD size,
985 DWORD propID)
987 const struct CertPropIDHeader *ret = NULL;
988 BOOL failed = FALSE;
990 while (size && !ret && !failed)
992 if (size < sizeof(struct CertPropIDHeader))
993 failed = TRUE;
994 else
996 const struct CertPropIDHeader *hdr =
997 (const struct CertPropIDHeader *)buf;
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
1007 buf += hdr->cb;
1008 size -= hdr->cb;
1012 return ret;
1015 static void testRegStore(void)
1017 static const char tempKey[] = "Software\\Wine\\CryptTemp";
1018 HCERTSTORE store;
1019 LONG rc;
1020 HKEY key = NULL;
1021 DWORD disp, GLE;
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);
1032 /* Opening up any old key works.. */
1033 key = HKEY_CURRENT_USER;
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
1037 todo_wine ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError());
1038 CertCloseStore(store, 0);
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)
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;
1051 PCCERT_CONTEXT context;
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..
1058 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1059 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_ALWAYS, NULL);
1060 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1061 GetLastError());
1062 /* so flush the cache to force a commit.. */
1063 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL);
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)
1079 LPBYTE buf;
1081 size = 0;
1082 RegQueryValueExA(subKey, "Blob", NULL, NULL, NULL, &size);
1083 buf = HeapAlloc(GetProcessHeap(), 0, size);
1084 if (buf)
1086 rc = RegQueryValueExA(subKey, "Blob", NULL, NULL, buf, &size);
1087 ok(!rc, "RegQueryValueExA failed: %d\n", rc);
1088 if (!rc)
1090 const struct CertPropIDHeader *hdr;
1092 /* Both the hash and the cert should be present */
1093 hdr = findPropID(buf, size, CERT_CERT_PROP_ID);
1094 ok(hdr != NULL, "Expected to find a cert property\n");
1095 if (hdr)
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");
1102 hdr = findPropID(buf, size, CERT_HASH_PROP_ID);
1103 ok(hdr != NULL, "Expected to find a hash property\n");
1104 if (hdr)
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");
1112 HeapFree(GetProcessHeap(), 0, buf);
1114 RegCloseKey(subKey);
1117 /* Remove the existing context */
1118 context = CertEnumCertificatesInStore(store, NULL);
1119 ok(context != NULL, "Expected a cert context\n");
1120 if (context)
1121 CertDeleteCertificateFromStore(context);
1122 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL);
1123 ok(ret, "CertControlStore failed: %08x\n", GetLastError());
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)
1136 BYTE buf[sizeof(struct CertPropIDHeader) * 2 + sizeof(hash) +
1137 sizeof(bigCert)], *ptr;
1138 DWORD certCount = 0;
1139 struct CertPropIDHeader *hdr;
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));
1155 rc = RegSetValueExA(subKey, "Blob", 0, REG_BINARY, buf,
1156 sizeof(buf));
1157 ok(!rc, "RegSetValueExA failed: %d\n", rc);
1159 ret = CertControlStore(store, 0, CERT_STORE_CTRL_RESYNC, NULL);
1160 ok(ret, "CertControlStore failed: %08x\n", GetLastError());
1162 /* Make sure the bogus hash cert gets loaded. */
1163 certCount = 0;
1164 context = NULL;
1165 do {
1166 context = CertEnumCertificatesInStore(store, context);
1167 if (context)
1168 certCount++;
1169 } while (context != NULL);
1170 ok(certCount == 1, "Expected 1 certificates, got %d\n", certCount);
1172 RegCloseKey(subKey);
1175 /* Add another serialized cert directly to the registry, this time
1176 * under the correct key name (named with the correct hash value).
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)
1191 BYTE buf[sizeof(struct CertPropIDHeader) * 2 + sizeof(hash) +
1192 sizeof(bigCert2)], *ptr;
1193 DWORD certCount = 0;
1194 PCCERT_CONTEXT context;
1195 struct CertPropIDHeader *hdr;
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));
1212 rc = RegSetValueExA(subKey, "Blob", 0, REG_BINARY, buf,
1213 sizeof(buf));
1214 ok(!rc, "RegSetValueExA failed: %d\n", rc);
1216 ret = CertControlStore(store, 0, CERT_STORE_CTRL_RESYNC, NULL);
1217 ok(ret, "CertControlStore failed: %08x\n", GetLastError());
1219 /* and make sure just one cert still gets loaded. */
1220 certCount = 0;
1221 context = NULL;
1222 do {
1223 context = CertEnumCertificatesInStore(store, context);
1224 if (context)
1225 certCount++;
1226 } while (context != NULL);
1227 ok(certCount == 1, "Expected 1 certificate, got %d\n", certCount);
1229 /* Try again with the correct hash... */
1230 ptr = buf + sizeof(*hdr);
1231 memcpy(ptr, hash, sizeof(hash));
1233 rc = RegSetValueExA(subKey, "Blob", 0, REG_BINARY, buf,
1234 sizeof(buf));
1235 ok(!rc, "RegSetValueExA failed: %d\n", rc);
1237 ret = CertControlStore(store, 0, CERT_STORE_CTRL_RESYNC, NULL);
1238 ok(ret, "CertControlStore failed: %08x\n", GetLastError());
1240 /* and make sure two certs get loaded. */
1241 certCount = 0;
1242 context = NULL;
1243 do {
1244 context = CertEnumCertificatesInStore(store, context);
1245 if (context)
1246 certCount++;
1247 } while (context != NULL);
1248 ok(certCount == 2, "Expected 2 certificates, got %d\n", certCount);
1250 RegCloseKey(subKey);
1252 CertCloseStore(store, 0);
1253 /* Is delete allowed on a reg store? */
1254 store = CertOpenStore(CERT_STORE_PROV_REG, 0, 0,
1255 CERT_STORE_DELETE_FLAG, key);
1256 ok(store == NULL, "Expected NULL return from CERT_STORE_DELETE_FLAG\n");
1257 ok(GetLastError() == 0, "CertOpenStore failed: %08x\n",
1258 GetLastError());
1260 RegCloseKey(key);
1262 /* The CertOpenStore with CERT_STORE_DELETE_FLAG above will delete the
1263 * contents of the key, but not the key itself.
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);
1268 ok(disp == REG_OPENED_EXISTING_KEY,
1269 "Expected REG_OPENED_EXISTING_KEY, got %d\n", disp);
1270 if (!rc)
1272 RegCloseKey(key);
1273 rc = RegDeleteKeyA(HKEY_CURRENT_USER, tempKey);
1274 if (rc)
1276 /* Use shlwapi's SHDeleteKeyA to _really_ blow away the key,
1277 * otherwise subsequent tests will fail.
1279 SHDeleteKeyA(HKEY_CURRENT_USER, tempKey);
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 };
1291 static void testSystemRegStore(void)
1293 HCERTSTORE store, memStore;
1295 /* Check with a UNICODE name */
1296 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
1297 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, MyW);
1298 /* Not all OSes support CERT_STORE_PROV_SYSTEM_REGISTRY, so don't continue
1299 * testing if they don't.
1301 if (!store)
1302 return;
1304 /* Check that it isn't a collection store */
1305 memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1306 CERT_STORE_CREATE_NEW_FLAG, NULL);
1307 if (memStore)
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);
1313 CertCloseStore(store, 0);
1315 /* Check opening a bogus store */
1316 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
1317 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, BogusW);
1318 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1319 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1320 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
1321 CERT_SYSTEM_STORE_CURRENT_USER, BogusW);
1322 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError());
1323 if (store)
1324 CertCloseStore(store, 0);
1325 /* Now check whether deleting is allowed */
1326 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
1327 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, BogusW);
1328 ok(!store, "CertOpenStore failed: %08x\n", GetLastError());
1329 RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW);
1331 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0, 0, NULL);
1332 ok(!store && GetLastError() == E_INVALIDARG,
1333 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1334 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
1335 CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_SYSTEM_STORE_CURRENT_USER, MyA);
1336 ok(!store && GetLastError() == E_INVALIDARG,
1337 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1338 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
1339 CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_SYSTEM_STORE_CURRENT_USER, MyW);
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 */
1343 store = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
1344 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, MyA);
1345 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1346 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1349 static void testSystemStore(void)
1351 static const WCHAR baskslashW[] = { '\\',0 };
1352 HCERTSTORE store;
1353 WCHAR keyName[MAX_PATH];
1354 HKEY key;
1355 LONG rc;
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,
1361 CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_SYSTEM_STORE_CURRENT_USER, MyA);
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,
1365 CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_SYSTEM_STORE_CURRENT_USER, MyW);
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,
1370 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, MyA);
1371 ok(!store && GetLastError() == ERROR_FILE_NOT_FOUND,
1372 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1373 /* Create the expected key */
1374 lstrcpyW(keyName, CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH);
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,
1384 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_CREATE_NEW_FLAG, MyW);
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,
1389 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, MyW);
1390 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError());
1391 if (store)
1393 HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1394 CERT_STORE_CREATE_NEW_FLAG, NULL);
1396 /* Check that it's a collection store */
1397 if (memStore)
1399 BOOL ret = CertAddStoreToCollection(store, memStore, 0, 0);
1400 ok(ret, "CertAddStoreToCollection failed: %08x\n", GetLastError());
1401 CertCloseStore(memStore, 0);
1403 CertCloseStore(store, 0);
1406 /* Check opening a bogus store */
1407 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1408 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, BogusW);
1409 ok(!store, "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1410 store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
1411 CERT_SYSTEM_STORE_CURRENT_USER, BogusW);
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,
1417 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, BogusW);
1418 ok(!store, "Didn't expect a store to be returned when deleting\n");
1419 RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW);
1422 static const BYTE serializedStoreWithCertAndCRL[] = {
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 };
1440 static void testFileStore(void)
1442 static const WCHAR szPrefix[] = { 'c','e','r',0 };
1443 static const WCHAR szDot[] = { '.',0 };
1444 WCHAR filename[MAX_PATH];
1445 HCERTSTORE store;
1446 BOOL ret;
1447 PCCERT_CONTEXT cert;
1448 HANDLE file;
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());
1454 if (!GetTempFileNameW(szDot, szPrefix, 0, filename))
1455 return;
1457 DeleteFileW(filename);
1458 file = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1459 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1460 if (file == INVALID_HANDLE_VALUE)
1461 return;
1463 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, CERT_STORE_DELETE_FLAG,
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,
1468 CERT_FILE_STORE_COMMIT_ENABLE_FLAG | CERT_STORE_READONLY_FLAG, file);
1469 ok(!store && GetLastError() == E_INVALIDARG,
1470 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1472 /* A "read-only" file store.. */
1473 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
1474 CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, file);
1475 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1476 if (store)
1478 DWORD size;
1480 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1481 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1482 /* apparently allows adding certificates.. */
1483 ok(ret, "CertAddEncodedCertificateToStore failed: %d\n", ret);
1484 /* but not commits.. */
1485 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL);
1486 ok(!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
1487 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %08x\n", GetLastError());
1488 /* It still has certs in memory.. */
1489 cert = CertEnumCertificatesInStore(store, NULL);
1490 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
1491 GetLastError());
1492 CertFreeCertificateContext(cert);
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);
1499 /* The create new flag is allowed.. */
1500 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
1501 CERT_STORE_CREATE_NEW_FLAG, file);
1502 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1503 if (store)
1505 /* but without the commit enable flag, commits don't happen. */
1506 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1507 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1508 ok(ret, "CertAddEncodedCertificateToStore failed: %d\n", ret);
1509 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL);
1510 ok(!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
1511 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %08x\n", GetLastError());
1512 CertCloseStore(store, 0);
1514 /* as is the open existing flag. */
1515 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
1516 CERT_STORE_OPEN_EXISTING_FLAG, file);
1517 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1518 if (store)
1520 /* but without the commit enable flag, commits don't happen. */
1521 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1522 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1523 ok(ret, "CertAddEncodedCertificateToStore failed: %d\n", ret);
1524 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL);
1525 ok(!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
1526 "Expected ERROR_CALL_NOT_IMPLEMENTED, got %08x\n", GetLastError());
1527 CertCloseStore(store, 0);
1529 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
1530 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
1531 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1532 if (store)
1534 CloseHandle(file);
1535 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1536 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1537 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1538 GetLastError());
1539 /* with commits enabled, commit is allowed */
1540 ret = CertControlStore(store, 0, CERT_STORE_CTRL_COMMIT, NULL);
1541 ok(ret, "CertControlStore failed: %d\n", ret);
1542 compareStore(store, "serialized store with cert",
1543 serializedStoreWithCert, sizeof(serializedStoreWithCert), FALSE);
1544 CertCloseStore(store, 0);
1546 file = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1547 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1548 if (file == INVALID_HANDLE_VALUE)
1549 return;
1550 store = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
1551 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
1552 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1553 if (store)
1555 CloseHandle(file);
1556 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
1557 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
1558 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
1559 compareStore(store, "serialized store with cert and CRL",
1560 serializedStoreWithCertAndCRL, sizeof(serializedStoreWithCertAndCRL),
1561 FALSE);
1562 CertCloseStore(store, 0);
1565 DeleteFileW(filename);
1568 static BOOL initFileFromData(LPCWSTR filename, const BYTE *pb, DWORD cb)
1570 HANDLE file = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1571 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1572 BOOL ret;
1574 if (file != INVALID_HANDLE_VALUE)
1576 DWORD written;
1578 ret = WriteFile(file, pb, cb, &written, NULL);
1579 CloseHandle(file);
1581 else
1582 ret = FALSE;
1583 return ret;
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 };
1646 static void testFileNameStore(void)
1648 static const WCHAR szPrefix[] = { 'c','e','r',0 };
1649 static const WCHAR spcPrefix[] = { 's','p','c',0 };
1650 static const WCHAR szDot[] = { '.',0 };
1651 WCHAR filename[MAX_PATH];
1652 HCERTSTORE store;
1653 BOOL ret;
1654 DWORD GLE;
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);
1662 if (!GetTempFileNameW(szDot, szPrefix, 0, filename))
1663 return;
1664 DeleteFileW(filename);
1666 /* The two flags are mutually exclusive */
1667 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0,
1668 CERT_FILE_STORE_COMMIT_ENABLE_FLAG | CERT_STORE_READONLY_FLAG, filename);
1669 ok(!store && GetLastError() == E_INVALIDARG,
1670 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1672 /* In all of the following tests, the encoding type seems to be ignored */
1673 if (initFileFromData(filename, bigCert, sizeof(bigCert)))
1675 PCCERT_CONTEXT cert;
1676 PCCRL_CONTEXT crl;
1678 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0,
1679 CERT_STORE_READONLY_FLAG, filename);
1680 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1682 cert = CertEnumCertificatesInStore(store, NULL);
1683 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
1684 GetLastError());
1685 cert = CertEnumCertificatesInStore(store, cert);
1686 ok(!cert, "Expected only one cert\n");
1687 crl = CertEnumCRLsInStore(store, NULL);
1688 ok(!crl, "Expected no CRLs\n");
1690 CertCloseStore(store, 0);
1691 DeleteFileW(filename);
1693 if (initFileFromData(filename, serializedStoreWithCert,
1694 sizeof(serializedStoreWithCert)))
1696 PCCERT_CONTEXT cert;
1697 PCCRL_CONTEXT crl;
1699 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0,
1700 CERT_STORE_READONLY_FLAG, filename);
1701 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1703 cert = CertEnumCertificatesInStore(store, NULL);
1704 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
1705 GetLastError());
1706 cert = CertEnumCertificatesInStore(store, cert);
1707 ok(!cert, "Expected only one cert\n");
1708 crl = CertEnumCRLsInStore(store, NULL);
1709 ok(!crl, "Expected no CRLs\n");
1711 CertCloseStore(store, 0);
1712 DeleteFileW(filename);
1714 if (initFileFromData(filename, serializedStoreWithCertAndCRL,
1715 sizeof(serializedStoreWithCertAndCRL)))
1717 PCCERT_CONTEXT cert;
1718 PCCRL_CONTEXT crl;
1720 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0,
1721 CERT_STORE_READONLY_FLAG, filename);
1722 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1724 cert = CertEnumCertificatesInStore(store, NULL);
1725 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
1726 GetLastError());
1727 cert = CertEnumCertificatesInStore(store, cert);
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");
1734 CertCloseStore(store, 0);
1735 /* Don't delete it this time, the next test uses it */
1737 /* Now that the file exists, we can open it read-only */
1738 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0,
1739 CERT_STORE_READONLY_FLAG, filename);
1740 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1741 CertCloseStore(store, 0);
1742 DeleteFileW(filename);
1744 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0,
1745 CERT_FILE_STORE_COMMIT_ENABLE_FLAG | CERT_STORE_CREATE_NEW_FLAG, filename);
1746 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1747 if (store)
1749 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1750 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1751 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1752 GetLastError());
1753 compareStore(store, "serialized store with cert",
1754 serializedStoreWithCert, sizeof(serializedStoreWithCert), FALSE);
1755 CertCloseStore(store, 0);
1757 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0,
1758 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, filename);
1759 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1760 if (store)
1762 ret = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING,
1763 signedCRL, sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
1764 ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
1765 compareStore(store, "serialized store with cert and CRL",
1766 serializedStoreWithCertAndCRL, sizeof(serializedStoreWithCertAndCRL),
1767 FALSE);
1768 CertCloseStore(store, 0);
1770 DeleteFileW(filename);
1772 if (!GetTempFileNameW(szDot, spcPrefix, 0, filename))
1773 return;
1774 DeleteFileW(filename);
1776 if (initFileFromData(filename, base64SPC, sizeof(base64SPC)))
1778 PCCERT_CONTEXT cert;
1779 PCCRL_CONTEXT crl;
1781 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0,
1782 CERT_STORE_READONLY_FLAG, filename);
1783 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1785 cert = CertEnumCertificatesInStore(store, NULL);
1786 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
1787 GetLastError());
1788 cert = CertEnumCertificatesInStore(store, cert);
1789 ok(!cert, "Expected only one cert\n");
1790 crl = CertEnumCRLsInStore(store, NULL);
1791 ok(!crl, "Expected no CRLs\n");
1793 CertCloseStore(store, 0);
1794 DeleteFileW(filename);
1796 if (initFileFromData(filename, (BYTE *)utf16Base64SPC,
1797 sizeof(utf16Base64SPC)))
1799 PCCERT_CONTEXT cert;
1800 PCCRL_CONTEXT crl;
1802 store = CertOpenStore(CERT_STORE_PROV_FILENAME_W, 0, 0,
1803 CERT_STORE_READONLY_FLAG, filename);
1804 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1806 cert = CertEnumCertificatesInStore(store, NULL);
1807 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
1808 GetLastError());
1809 cert = CertEnumCertificatesInStore(store, cert);
1810 ok(!cert, "Expected only one cert\n");
1811 crl = CertEnumCRLsInStore(store, NULL);
1812 ok(!crl, "Expected no CRLs\n");
1814 CertCloseStore(store, 0);
1815 DeleteFileW(filename);
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 };
1833 static const BYTE signedWithCertAndCrlBareContent[] = {
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 };
1869 static void testMessageStore(void)
1871 HCERTSTORE store;
1872 HCRYPTMSG msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, 0, 0, 0, NULL,
1873 NULL);
1874 CRYPT_DATA_BLOB blob = { sizeof(signedWithCertAndCrlBareContent),
1875 (LPBYTE)signedWithCertAndCrlBareContent };
1876 DWORD count, size;
1877 BOOL ret;
1879 /* Crashes
1880 store = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0, NULL);
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());
1886 CryptMsgUpdate(msg, signedContent, sizeof(signedContent), TRUE);
1887 store = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0, msg);
1888 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1889 if (store)
1891 PCCERT_CONTEXT cert = NULL;
1892 PCCRL_CONTEXT crl = NULL;
1894 count = 0;
1895 do {
1896 cert = CertEnumCertificatesInStore(store, cert);
1897 if (cert)
1898 count++;
1899 } while (cert);
1900 ok(count == 0, "Expected 0 certificates, got %d\n", count);
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);
1910 /* Can add certs to a message store */
1911 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1912 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1913 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1914 GetLastError());
1915 count = 0;
1916 do {
1917 cert = CertEnumCertificatesInStore(store, cert);
1918 if (cert)
1919 count++;
1920 } while (cert);
1921 ok(count == 1, "Expected 1 certificate, got %d\n", count);
1923 CertCloseStore(store, 0);
1925 /* but the added certs weren't actually added to the message */
1926 size = sizeof(count);
1927 ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
1928 ok(ret, "CryptMsgGetParam failed: %08x\n", GetLastError());
1929 ok(count == 0, "Expected 0 certificates, got %d\n", count);
1930 CryptMsgClose(msg);
1932 /* Crashes
1933 store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, NULL);
1935 store = CertOpenStore(CERT_STORE_PROV_PKCS7, 0, 0, 0, &blob);
1936 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1937 if (store)
1939 DWORD count = 0;
1940 PCCERT_CONTEXT cert = NULL;
1941 PCCRL_CONTEXT crl = NULL;
1943 do {
1944 cert = CertEnumCertificatesInStore(store, cert);
1945 if (cert)
1946 count++;
1947 } while (cert);
1948 ok(count == 1, "Expected 1 certificate, got %d\n", count);
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);
1958 CertCloseStore(store, 0);
1960 /* Encoding appears to be ignored */
1961 store = CertOpenStore(CERT_STORE_PROV_PKCS7, X509_ASN_ENCODING, 0, 0,
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());
1981 static void testSerializedStore(void)
1983 HCERTSTORE store;
1984 CRYPT_DATA_BLOB blob;
1986 if (0)
1988 /* Crash */
1989 store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 0, NULL);
1990 store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0,
1991 CERT_STORE_DELETE_FLAG, NULL);
1993 blob.cbData = sizeof(serializedStoreWithCert);
1994 blob.pbData = (BYTE *)serializedStoreWithCert;
1995 store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0,
1996 CERT_STORE_DELETE_FLAG, &blob);
1997 ok(!store && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
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)
2003 PCCERT_CONTEXT cert;
2004 PCCRL_CONTEXT crl;
2006 cert = CertEnumCertificatesInStore(store, NULL);
2007 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
2008 GetLastError());
2009 cert = CertEnumCertificatesInStore(store, cert);
2010 ok(!cert, "Expected only one cert\n");
2011 crl = CertEnumCRLsInStore(store, NULL);
2012 ok(!crl, "Expected no CRLs\n");
2014 CertCloseStore(store, 0);
2016 blob.cbData = sizeof(serializedStoreWithCertAndCRL);
2017 blob.pbData = (BYTE *)serializedStoreWithCertAndCRL;
2018 store = CertOpenStore(CERT_STORE_PROV_SERIALIZED, 0, 0, 0, &blob);
2019 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2020 if (store)
2022 PCCERT_CONTEXT cert;
2023 PCCRL_CONTEXT crl;
2025 cert = CertEnumCertificatesInStore(store, NULL);
2026 ok(cert != NULL, "CertEnumCertificatesInStore failed: %08x\n",
2027 GetLastError());
2028 cert = CertEnumCertificatesInStore(store, cert);
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");
2036 CertCloseStore(store, 0);
2040 static void testCertOpenSystemStore(void)
2042 HCERTSTORE store;
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.)
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 */
2055 CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
2056 CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_DELETE_FLAG, BogusW);
2057 RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW);
2060 static const struct
2062 DWORD cert_store;
2063 BOOL expected;
2064 BOOL todo;
2065 } reg_system_store_test_data[] = {
2066 { CERT_SYSTEM_STORE_CURRENT_USER, TRUE, 0},
2067 /* Following tests could require administrator privileges and thus could be skipped */
2068 { CERT_SYSTEM_STORE_CURRENT_SERVICE, TRUE, 1},
2069 { CERT_SYSTEM_STORE_LOCAL_MACHINE, TRUE, 0},
2070 { CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, TRUE, 0},
2071 { CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, TRUE, 0},
2072 { CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, TRUE, 1}
2075 static void testCertRegisterSystemStore(void)
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;
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)
2089 err = GetLastError();
2090 if (err == ERROR_ACCESS_DENIED)
2092 win_skip("Insufficient privileges for the flag %08x test\n", cur_flag);
2093 continue;
2096 todo_wine_if (reg_system_store_test_data[i].todo)
2097 ok (ret == reg_system_store_test_data[i].expected,
2098 "Store registration (dwFlags=%08x) failed, last error %x\n", cur_flag, err);
2099 if (!ret)
2101 skip("Nothing to test without registered store at %08x\n", cur_flag);
2102 continue;
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());
2108 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
2109 ok (cert != NULL, "Failed creating cert at %08x, last error: %x\n", cur_flag, GetLastError());
2110 if (cert)
2112 ret = CertAddCertificateContextToStore(hstore, cert, CERT_STORE_ADD_NEW, NULL);
2113 ok (ret, "Failed to add cert at %08x, last error: %x\n", cur_flag, GetLastError());
2115 cert2 = CertEnumCertificatesInStore(hstore, NULL);
2116 ok (cert2 != NULL && cert2->cbCertEncoded == cert->cbCertEncoded,
2117 "Unexpected cert encoded size at %08x, last error: %x\n", cur_flag, GetLastError());
2119 ret = CertDeleteCertificateFromStore(cert2);
2120 ok (ret, "Failed to delete certificate from the new store at %08x, last error: %x\n", cur_flag, GetLastError());
2122 CertFreeCertificateContext(cert);
2125 ret = CertCloseStore(hstore, 0);
2126 ok (ret, "CertCloseStore failed at %08x, last error %x\n", cur_flag, GetLastError());
2128 ret = CertUnregisterSystemStore(WineTestW, cur_flag );
2129 todo_wine_if (reg_system_store_test_data[i].todo)
2130 ok( ret == reg_system_store_test_data[i].expected,
2131 "Unregistering failed at %08x, last error %d\n", cur_flag, GetLastError());
2136 struct EnumSystemStoreInfo
2138 BOOL goOn;
2139 DWORD storeCount;
2142 static BOOL CALLBACK enumSystemStoreCB(const void *systemStore, DWORD dwFlags,
2143 PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved, void *pvArg)
2145 struct EnumSystemStoreInfo *info = pvArg;
2147 info->storeCount++;
2148 return info->goOn;
2151 static void testCertEnumSystemStore(void)
2153 BOOL ret;
2154 struct EnumSystemStoreInfo info = { FALSE, 0 };
2156 SetLastError(0xdeadbeef);
2157 ret = CertEnumSystemStore(0, NULL, NULL, NULL);
2158 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2159 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2160 /* Crashes
2161 ret = CertEnumSystemStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, NULL, NULL,
2162 NULL);
2165 SetLastError(0xdeadbeef);
2166 ret = CertEnumSystemStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, NULL, &info,
2167 enumSystemStoreCB);
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");
2173 info.goOn = TRUE;
2174 info.storeCount = 0;
2175 ret = CertEnumSystemStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, NULL, &info,
2176 enumSystemStoreCB);
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");
2183 static void testStoreProperty(void)
2185 HCERTSTORE store;
2186 BOOL ret;
2187 DWORD propID, size = 0, state;
2188 CRYPT_DATA_BLOB blob;
2190 /* Crash
2191 ret = CertGetStoreProperty(NULL, 0, NULL, NULL);
2192 ret = CertGetStoreProperty(NULL, 0, NULL, &size);
2193 ret = CertGetStoreProperty(store, 0, NULL, NULL);
2196 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
2197 CERT_STORE_CREATE_NEW_FLAG, NULL);
2198 /* Check a missing prop ID */
2199 SetLastError(0xdeadbeef);
2200 ret = CertGetStoreProperty(store, 0, NULL, &size);
2201 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
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);
2205 ret = CertGetStoreProperty(store, CERT_ACCESS_STATE_PROP_ID, &state, &size);
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;
2211 ret = CertGetStoreProperty(store, CERT_STORE_LOCALIZED_NAME_PROP_ID, NULL,
2212 &size);
2213 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2214 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2215 /* Delete an arbitrary property on a store */
2216 ret = CertSetStoreProperty(store, CERT_FIRST_USER_PROP_ID, 0, NULL);
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);
2221 ret = CertSetStoreProperty(store, CERT_FIRST_USER_PROP_ID, 0, &blob);
2222 ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError());
2223 /* Get an arbitrary property that's been set */
2224 ret = CertGetStoreProperty(store, CERT_FIRST_USER_PROP_ID, NULL, &size);
2225 ok(ret, "CertGetStoreProperty failed: %08x\n", GetLastError());
2226 ok(size == sizeof(state), "Unexpected data size %d\n", size);
2227 ret = CertGetStoreProperty(store, CERT_FIRST_USER_PROP_ID, &propID, &size);
2228 ok(ret, "CertGetStoreProperty failed: %08x\n", GetLastError());
2229 ok(propID == state, "CertGetStoreProperty got the wrong value\n");
2230 /* Delete it again */
2231 ret = CertSetStoreProperty(store, CERT_FIRST_USER_PROP_ID, 0, NULL);
2232 ok(ret, "CertSetStoreProperty failed: %08x\n", GetLastError());
2233 /* And check that it's missing */
2234 SetLastError(0xdeadbeef);
2235 ret = CertGetStoreProperty(store, CERT_FIRST_USER_PROP_ID, NULL, &size);
2236 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2237 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2238 CertCloseStore(store, 0);
2240 /* Recheck on the My store.. */
2241 store = CertOpenSystemStoreW(0, MyW);
2242 size = sizeof(state);
2243 ret = CertGetStoreProperty(store, CERT_ACCESS_STATE_PROP_ID, &state, &size);
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;
2249 ret = CertGetStoreProperty(store, CERT_STORE_LOCALIZED_NAME_PROP_ID, NULL,
2250 &size);
2251 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2252 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2253 CertCloseStore(store, 0);
2256 static void testAddSerialized(void)
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;
2264 PCCERT_CONTEXT context;
2266 ret = CertAddSerializedElementToStore(0, NULL, 0, 0, 0, 0, NULL, NULL);
2267 ok(!ret && GetLastError() == ERROR_END_OF_MEDIA,
2268 "Expected ERROR_END_OF_MEDIA, got %08x\n", GetLastError());
2270 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
2271 CERT_STORE_CREATE_NEW_FLAG, NULL);
2272 ok(store != 0, "CertOpenStore failed: %08x\n", GetLastError());
2274 ret = CertAddSerializedElementToStore(store, NULL, 0, 0, 0, 0, NULL, NULL);
2275 ok(!ret && GetLastError() == ERROR_END_OF_MEDIA,
2276 "Expected ERROR_END_OF_MEDIA, got %08x\n", GetLastError());
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());
2294 ret = CertAddSerializedElementToStore(store, buf,
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());
2299 ret = CertAddSerializedElementToStore(store, buf,
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());
2310 ret = CertAddSerializedElementToStore(store, buf,
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());
2315 ret = CertAddSerializedElementToStore(store, buf,
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,
2322 CERT_STORE_CRL_CONTEXT_FLAG, NULL, NULL);
2323 ok(!ret && GetLastError() == E_INVALIDARG,
2324 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2325 ret = CertAddSerializedElementToStore(store, buf,
2326 sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0,
2327 CERT_STORE_CRL_CONTEXT_FLAG, NULL, NULL);
2328 ok(!ret && GetLastError() == E_INVALIDARG,
2329 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2330 ret = CertAddSerializedElementToStore(store, buf,
2331 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW,
2332 0, CERT_STORE_CRL_CONTEXT_FLAG, NULL, NULL);
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,
2338 CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
2339 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2340 "Expected ERROR_FILE_NOT_FOUND got %08x\n", GetLastError());
2341 ret = CertAddSerializedElementToStore(store, buf,
2342 sizeof(struct CertPropIDHeader) + sizeof(bigCert), 0, 0,
2343 CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
2344 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2345 "Expected ERROR_FILE_NOT_FOUND got %08x\n", GetLastError());
2346 ret = CertAddSerializedElementToStore(store, buf,
2347 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW,
2348 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
2349 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
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);
2361 /* Everything okay, but buffer's too big */
2362 ret = CertAddSerializedElementToStore(store, buf, sizeof(buf),
2363 CERT_STORE_ADD_NEW, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
2364 ok(ret, "CertAddSerializedElementToStore failed: %08x\n", GetLastError());
2365 /* Everything okay, check it's not re-added */
2366 ret = CertAddSerializedElementToStore(store, buf,
2367 sizeof(struct CertPropIDHeader) + sizeof(bigCert), CERT_STORE_ADD_NEW,
2368 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL, NULL);
2369 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
2370 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
2372 context = CertEnumCertificatesInStore(store, NULL);
2373 ok(context != NULL, "Expected a cert\n");
2374 if (context)
2375 CertDeleteCertificateFromStore(context);
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.
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),
2388 CERT_STORE_ADD_NEW, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, NULL,
2389 (const void **)&context);
2390 ok(ret, "CertAddSerializedElementToStore failed: %08x\n", GetLastError());
2391 if (context)
2393 BYTE hashVal[20], realHash[20];
2394 DWORD size = sizeof(hashVal);
2396 ret = CryptHashCertificate(0, 0, 0, bigCert, sizeof(bigCert),
2397 realHash, &size);
2398 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
2399 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
2400 hashVal, &size);
2401 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2402 GetLastError());
2403 ok(!memcmp(hashVal, realHash, size), "Unexpected hash\n");
2404 CertFreeCertificateContext(context);
2407 CertCloseStore(store, 0);
2410 static const BYTE serializedCertWithFriendlyName[] = {
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 };
2423 static const BYTE serializedStoreWithCertWithFriendlyName[] = {
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 };
2437 static const BYTE serializedStoreWithCertAndHash[] = {
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 };
2452 static void delete_test_key(void)
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;
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))
2466 RegCloseKey(root_key);
2467 return;
2469 RegQueryInfoKeyW(test_key, NULL, NULL, NULL, &num_subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
2470 for (idx = num_subkeys; idx-- > 0;)
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);
2476 RegCloseKey(test_key);
2477 RegDeleteKeyW(root_key, WineTestW);
2478 RegCloseKey(root_key);
2481 static void testAddCertificateLink(void)
2483 BOOL ret;
2484 HCERTSTORE store1, store2;
2485 PCCERT_CONTEXT source, linked;
2486 DWORD size;
2487 LPBYTE buf;
2488 CERT_NAME_BLOB blob;
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;
2495 if (0)
2497 /* Crashes, i.e. the store is dereferenced without checking. */
2498 ret = CertAddCertificateLinkToStore(NULL, NULL, 0, NULL);
2501 /* Adding a certificate link to a store requires a valid add disposition */
2502 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
2503 CERT_STORE_CREATE_NEW_FLAG, NULL);
2504 SetLastError(0xdeadbeef);
2505 ret = CertAddCertificateLinkToStore(store1, NULL, 0, NULL);
2506 ok(!ret && GetLastError() == E_INVALIDARG,
2507 "expected E_INVALIDARG, got %08x\n", GetLastError());
2508 source = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2509 sizeof(bigCert));
2510 SetLastError(0xdeadbeef);
2511 ret = CertAddCertificateLinkToStore(store1, source, 0, NULL);
2512 ok(!ret && GetLastError() == E_INVALIDARG,
2513 "expected E_INVALIDARG, got %08x\n", GetLastError());
2514 ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS,
2515 NULL);
2516 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
2517 if (0)
2519 /* Crashes, i.e. the source certificate is dereferenced without
2520 * checking when a valid add disposition is given.
2522 ret = CertAddCertificateLinkToStore(store1, NULL, CERT_STORE_ADD_ALWAYS,
2523 NULL);
2525 CertCloseStore(store1, 0);
2527 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
2528 CERT_STORE_CREATE_NEW_FLAG, NULL);
2529 ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS,
2530 &linked);
2531 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
2532 if (ret)
2534 ok(linked->hCertStore == store1, "unexpected store\n");
2535 ret = CertSerializeCertificateStoreElement(linked, 0, NULL, &size);
2536 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
2537 GetLastError());
2538 buf = HeapAlloc(GetProcessHeap(), 0, size);
2539 if (buf)
2541 ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size);
2542 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
2543 GetLastError());
2544 /* The serialized linked certificate is identical to the serialized
2545 * original certificate.
2547 ok(size == sizeof(serializedCert), "Wrong size %d\n", size);
2548 ok(!memcmp(serializedCert, buf, size),
2549 "Unexpected serialized cert\n");
2550 HeapFree(GetProcessHeap(), 0, buf);
2552 /* Set a friendly name on the source certificate... */
2553 blob.pbData = (LPBYTE)WineTestW;
2554 blob.cbData = sizeof(WineTestW);
2555 ret = CertSetCertificateContextProperty(source,
2556 CERT_FRIENDLY_NAME_PROP_ID, 0, &blob);
2557 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
2558 GetLastError());
2559 /* and the linked certificate has the same friendly name. */
2560 ret = CertGetCertificateContextProperty(linked,
2561 CERT_FRIENDLY_NAME_PROP_ID, NULL, &size);
2562 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2563 GetLastError());
2564 buf = HeapAlloc(GetProcessHeap(), 0, size);
2565 if (buf)
2567 ret = CertGetCertificateContextProperty(linked,
2568 CERT_FRIENDLY_NAME_PROP_ID, buf, &size);
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);
2575 CertFreeCertificateContext(linked);
2577 CertFreeCertificateContext(source);
2578 CertCloseStore(store1, 0);
2580 /* Test adding a cert to a file store, committing the change to the store,
2581 * and creating a link to the resulting cert.
2583 if (!GetTempFileNameW(szDot, szPrefix, 0, filename1))
2584 return;
2586 DeleteFileW(filename1);
2587 file = CreateFileW(filename1, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2588 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2589 if (file == INVALID_HANDLE_VALUE)
2590 return;
2592 store1 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
2593 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
2594 ok(store1 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2595 CloseHandle(file);
2597 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
2598 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &source);
2599 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
2600 GetLastError());
2602 /* Test adding a link to a memory store. */
2603 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
2604 CERT_STORE_CREATE_NEW_FLAG, NULL);
2605 ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS,
2606 &linked);
2607 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
2608 if (ret)
2610 ok(linked->hCertStore == store2, "unexpected store\n");
2611 ret = CertSerializeCertificateStoreElement(linked, 0, NULL, &size);
2612 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
2613 GetLastError());
2614 buf = HeapAlloc(GetProcessHeap(), 0, size);
2615 if (buf)
2617 ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size);
2618 /* The serialized linked certificate is identical to the serialized
2619 * original certificate.
2621 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n", GetLastError());
2622 ok(size == sizeof(serializedCert), "Wrong size %d\n", size);
2623 ok(!memcmp(serializedCert, buf, size),
2624 "Unexpected serialized cert\n");
2625 HeapFree(GetProcessHeap(), 0, buf);
2627 /* Set a friendly name on the source certificate... */
2628 blob.pbData = (LPBYTE)WineTestW;
2629 blob.cbData = sizeof(WineTestW);
2630 ret = CertSetCertificateContextProperty(source,
2631 CERT_FRIENDLY_NAME_PROP_ID, 0, &blob);
2632 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
2633 GetLastError());
2634 /* and the linked certificate has the same friendly name. */
2635 ret = CertGetCertificateContextProperty(linked,
2636 CERT_FRIENDLY_NAME_PROP_ID, NULL, &size);
2637 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2638 GetLastError());
2639 buf = HeapAlloc(GetProcessHeap(), 0, size);
2640 if (buf)
2642 ret = CertGetCertificateContextProperty(linked,
2643 CERT_FRIENDLY_NAME_PROP_ID, buf, &size);
2644 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
2645 ok(!lstrcmpW((LPCWSTR)buf, WineTestW),
2646 "unexpected friendly name\n");
2647 HeapFree(GetProcessHeap(), 0, buf);
2649 CertFreeCertificateContext(linked);
2651 CertCloseStore(store2, 0);
2653 if (!GetTempFileNameW(szDot, szPrefix, 0, filename2))
2654 return;
2656 DeleteFileW(filename2);
2657 file = CreateFileW(filename2, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2658 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2659 if (file == INVALID_HANDLE_VALUE)
2660 return;
2662 store2 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
2663 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
2664 ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2665 CloseHandle(file);
2666 /* Test adding a link to a file store. */
2667 ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS,
2668 &linked);
2669 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
2670 if (ret)
2672 ok(linked->hCertStore == store2, "unexpected store\n");
2673 ret = CertSerializeCertificateStoreElement(linked, 0, NULL, &size);
2674 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
2675 GetLastError());
2676 buf = HeapAlloc(GetProcessHeap(), 0, size);
2677 if (buf)
2679 ret = CertSerializeCertificateStoreElement(linked, 0, buf, &size);
2680 ok(ret, "CertSerializeCertificateStoreElement failed: %08x\n",
2681 GetLastError());
2682 /* The serialized linked certificate now contains the friendly
2683 * name property.
2685 ok(size == sizeof(serializedCertWithFriendlyName),
2686 "Wrong size %d\n", size);
2687 ok(!memcmp(serializedCertWithFriendlyName, buf, size),
2688 "Unexpected serialized cert\n");
2689 HeapFree(GetProcessHeap(), 0, buf);
2691 CertFreeCertificateContext(linked);
2692 compareStore(store2, "file store -> file store",
2693 serializedStoreWithCertWithFriendlyName,
2694 sizeof(serializedStoreWithCertWithFriendlyName), FALSE);
2696 CertCloseStore(store2, 0);
2697 DeleteFileW(filename2);
2699 CertFreeCertificateContext(source);
2701 CertCloseStore(store1, 0);
2702 DeleteFileW(filename1);
2704 /* Test adding a link to a system store (which is a collection store.) */
2705 store1 = CertOpenSystemStoreA(0, "My");
2706 source = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2707 sizeof(bigCert));
2708 SetLastError(0xdeadbeef);
2709 ret = CertAddCertificateLinkToStore(store1, source, CERT_STORE_ADD_ALWAYS,
2710 &linked);
2711 ok(!ret && GetLastError() == E_INVALIDARG,
2712 "expected E_INVALIDARG, got %08x\n", GetLastError());
2713 CertFreeCertificateContext(source);
2715 /* Test adding a link to a file store, where the linked certificate is
2716 * in a system store.
2718 ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING,
2719 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &source);
2720 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
2721 GetLastError());
2722 if (!GetTempFileNameW(szDot, szPrefix, 0, filename1))
2723 return;
2725 DeleteFileW(filename1);
2726 file = CreateFileW(filename1, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2727 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2728 if (file == INVALID_HANDLE_VALUE)
2729 return;
2731 store2 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0,
2732 CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file);
2733 ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2734 CloseHandle(file);
2736 ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS,
2737 &linked);
2738 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
2739 if (ret)
2741 ok(linked->hCertStore == store2, "unexpected store\n");
2742 ret = CertControlStore(store2, 0, CERT_STORE_CTRL_COMMIT, NULL);
2743 ok(ret, "CertControlStore failed: %d\n", ret);
2744 compareStore(store2, "file store -> system store",
2745 serializedStoreWithCertAndHash,
2746 sizeof(serializedStoreWithCertAndHash), TRUE);
2747 CertFreeCertificateContext(linked);
2750 CertCloseStore(store2, 0);
2751 DeleteFileW(filename1);
2753 /* Test adding a link to a registry store, where the linked certificate is
2754 * in a system store.
2756 store2 = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY, 0, 0,
2757 CERT_SYSTEM_STORE_CURRENT_USER, WineTestW);
2758 ok(store2 != NULL, "CertOpenStore failed: %08x\n", GetLastError());
2759 ret = CertAddCertificateLinkToStore(store2, source, CERT_STORE_ADD_ALWAYS,
2760 &linked);
2761 ok(ret, "CertAddCertificateLinkToStore failed: %08x\n", GetLastError());
2762 if (ret)
2764 ok(linked->hCertStore == store2, "unexpected store\n");
2765 CertDeleteCertificateFromStore(linked);
2767 CertCloseStore(store2, 0);
2769 CertFreeCertificateContext(source);
2770 CertCloseStore(store1, 0);
2772 delete_test_key();
2775 static DWORD countCertsInStore(HCERTSTORE store)
2777 PCCERT_CONTEXT cert = NULL;
2778 DWORD certs = 0;
2780 do {
2781 cert = CertEnumCertificatesInStore(store, cert);
2782 if (cert)
2783 certs++;
2784 } while (cert);
2785 return certs;
2788 static DWORD countCRLsInStore(HCERTSTORE store)
2790 PCCRL_CONTEXT crl = NULL;
2791 DWORD crls = 0;
2793 do {
2794 crl = CertEnumCRLsInStore(store, crl);
2795 if (crl)
2796 crls++;
2797 } while (crl);
2798 return crls;
2801 static void testEmptyStore(void)
2803 const CERT_CONTEXT *cert, *cert2, *cert3;
2804 const CRL_CONTEXT *crl;
2805 const CTL_CONTEXT *ctl;
2806 HCERTSTORE store;
2807 BOOL res;
2809 cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
2810 ok(cert != NULL, "CertCreateCertificateContext failed\n");
2811 ok(cert->hCertStore != NULL, "cert->hCertStore == NULL\n");
2812 if(!cert->hCertStore) {
2813 CertFreeCertificateContext(cert);
2814 return;
2817 test_store_is_empty(cert->hCertStore);
2819 cert2 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2, sizeof(bigCert2));
2820 ok(cert2 != NULL, "CertCreateCertificateContext failed\n");
2821 ok(cert2->hCertStore == cert->hCertStore, "Unexpected hCertStore\n");
2823 test_store_is_empty(cert2->hCertStore);
2825 res = CertAddCertificateContextToStore(cert->hCertStore, cert2, CERT_STORE_ADD_NEW, &cert3);
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");
2831 test_store_is_empty(cert->hCertStore);
2833 res = CertDeleteCertificateFromStore(cert3);
2834 ok(res, "CertDeleteCertificateContextFromStore failed\n");
2835 ok(cert3->hCertStore == cert->hCertStore, "Unexpected hCertStore\n");
2837 CertFreeCertificateContext(cert3);
2839 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
2840 ok(store != NULL, "CertOpenStore failed\n");
2842 res = CertAddCertificateContextToStore(store, cert2, CERT_STORE_ADD_NEW, &cert3);
2843 ok(res, "CertAddCertificateContextToStore failed\n");
2844 ok(cert3 && cert3 != cert2, "Unexpected cert3\n");
2845 ok(cert3->hCertStore == store, "Unexpected hCertStore\n");
2847 res = CertDeleteCertificateFromStore(cert3);
2848 ok(res, "CertDeleteCertificateContextFromStore failed\n");
2849 ok(cert3->hCertStore == store, "Unexpected hCertStore\n");
2851 CertCloseStore(store, 0);
2852 CertFreeCertificateContext(cert3);
2854 res = CertCloseStore(cert->hCertStore, CERT_CLOSE_STORE_CHECK_FLAG);
2855 ok(!res && GetLastError() == E_UNEXPECTED, "CertCloseStore returned: %x(%x)\n", res, GetLastError());
2857 res = CertCloseStore(cert->hCertStore, 0);
2858 ok(!res && GetLastError() == E_UNEXPECTED, "CertCloseStore returned: %x(%x)\n", res, GetLastError());
2860 CertFreeCertificateContext(cert2);
2862 crl = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL, sizeof(signedCRL));
2863 ok(crl != NULL, "CertCreateCRLContext failed\n");
2864 ok(crl->hCertStore == cert->hCertStore, "unexpected hCertStore\n");
2866 CertFreeCRLContext(crl);
2868 ctl = CertCreateCTLContext(X509_ASN_ENCODING, signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent));
2869 ok(ctl != NULL, "CertCreateCTLContext failed\n");
2870 ok(ctl->hCertStore == cert->hCertStore, "unexpected hCertStore\n");
2872 CertFreeCTLContext(ctl);
2874 CertFreeCertificateContext(cert);
2877 static void testCloseStore(void)
2879 const CERT_CONTEXT *cert;
2880 const CRL_CONTEXT *crl;
2881 const CTL_CONTEXT *ctl;
2882 HCERTSTORE store, store2;
2883 BOOL res;
2885 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
2886 ok(store != NULL, "CertOpenStore failed\n");
2888 res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
2889 ok(res, "CertCloseStore failed\n");
2891 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
2892 ok(store != NULL, "CertOpenStore failed\n");
2894 store2 = CertDuplicateStore(store);
2895 ok(store2 != NULL, "CertCloneStore failed\n");
2896 ok(store2 == store, "unexpected store2\n");
2898 res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
2899 ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
2901 res = CertCloseStore(store2, CERT_CLOSE_STORE_CHECK_FLAG);
2902 ok(res, "CertCloseStore failed\n");
2904 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
2905 ok(store != NULL, "CertOpenStore failed\n");
2907 res = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, bigCert,
2908 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert);
2909 ok(res, "CertAddEncodedCertificateToStore failed\n");
2911 /* There is still a reference from cert */
2912 res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
2913 ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
2915 res = CertFreeCertificateContext(cert);
2916 ok(res, "CertFreeCertificateContext failed\n");
2918 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
2919 ok(store != NULL, "CertOpenStore failed\n");
2921 res = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
2922 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &crl);
2923 ok(res, "CertAddEncodedCRLToStore failed\n");
2925 /* There is still a reference from CRL */
2926 res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
2927 ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
2929 res = CertFreeCRLContext(crl);
2930 ok(res, "CertFreeCRLContext failed\n");
2932 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
2933 ok(store != NULL, "CertOpenStore failed\n");
2935 res = CertAddEncodedCTLToStore(store, X509_ASN_ENCODING, signedCTLWithCTLInnerContent,
2936 sizeof(signedCTLWithCTLInnerContent), CERT_STORE_ADD_ALWAYS, &ctl);
2937 ok(res, "CertAddEncodedCTLToStore failed\n");
2939 /* There is still a reference from CTL */
2940 res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
2941 ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore returned: %x(%u)\n", res, GetLastError());
2943 res = CertFreeCTLContext(ctl);
2944 ok(res, "CertFreeCTLContext failed\n");
2946 /* Add all kinds of contexts, then release external references and make sure that store is properly closed. */
2947 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
2948 ok(store != NULL, "CertOpenStore failed\n");
2950 res = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, bigCert,
2951 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert);
2952 ok(res, "CertAddEncodedCertificateToStore failed\n");
2954 res = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
2955 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &crl);
2956 ok(res, "CertAddEncodedCRLToStore failed\n");
2958 res = CertAddEncodedCTLToStore(store, X509_ASN_ENCODING, signedCTLWithCTLInnerContent,
2959 sizeof(signedCTLWithCTLInnerContent), CERT_STORE_ADD_ALWAYS, &ctl);
2960 ok(res, "CertAddEncodedCTLToStore failed\n");
2962 CertFreeCertificateContext(cert);
2963 CertFreeCRLContext(crl);
2964 CertFreeCTLContext(ctl);
2966 res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
2967 ok(res, "CertCloseStore failed\n");
2970 static void test_I_UpdateStore(void)
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;
2977 PCCERT_CONTEXT cert;
2978 DWORD certs;
2980 if (!pI_CertUpdatestore)
2982 win_skip("No I_CertUpdateStore\n");
2983 return;
2985 store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
2986 CERT_STORE_CREATE_NEW_FLAG, NULL);
2987 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
2988 CERT_STORE_CREATE_NEW_FLAG, NULL);
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);
2995 ret = pI_CertUpdatestore(store1, store2, 0, 0);
2996 ok(ret, "I_CertUpdateStore failed: %08x\n", GetLastError());
2998 CertAddEncodedCertificateToStore(store2, X509_ASN_ENCODING, bigCert,
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);
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());
3017 CertAddEncodedCRLToStore(store2, X509_ASN_ENCODING, signedCRL,
3018 sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
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);
3028 CertDeleteCertificateFromStore(cert);
3029 /* If a context is deleted from store2, I_CertUpdateStore deletes it
3030 * from store1
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);
3037 CertCloseStore(store1, 0);
3038 CertCloseStore(store2, 0);
3041 const BYTE pfxdata[] =
3043 0x30, 0x82, 0x0b, 0x1d, 0x02, 0x01, 0x03, 0x30, 0x82, 0x0a, 0xe3, 0x06,
3044 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82,
3045 0x0a, 0xd4, 0x04, 0x82, 0x0a, 0xd0, 0x30, 0x82, 0x0a, 0xcc, 0x30, 0x82,
3046 0x05, 0x07, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
3047 0x06, 0xa0, 0x82, 0x04, 0xf8, 0x30, 0x82, 0x04, 0xf4, 0x02, 0x01, 0x00,
3048 0x30, 0x82, 0x04, 0xed, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
3049 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3050 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xac, 0x3e, 0x35,
3051 0xa8, 0xed, 0x0d, 0x50, 0x07, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x04,
3052 0xc0, 0x5a, 0x62, 0x55, 0x25, 0xf6, 0x2c, 0xf1, 0x78, 0x6c, 0x63, 0x96,
3053 0x8a, 0xea, 0x04, 0x64, 0xb3, 0x99, 0x3b, 0x80, 0x50, 0x05, 0x37, 0x55,
3054 0xa3, 0x5e, 0x9f, 0x35, 0xc3, 0x3c, 0xdc, 0xf6, 0xc4, 0xc1, 0x39, 0xa2,
3055 0xd7, 0x50, 0xad, 0xf9, 0x29, 0x3c, 0x51, 0xea, 0x15, 0x20, 0x25, 0xd3,
3056 0x4d, 0x69, 0xdf, 0x10, 0xd8, 0x9d, 0x60, 0x78, 0x8a, 0x70, 0x44, 0x7f,
3057 0x01, 0x4f, 0x4a, 0xfa, 0xab, 0xfd, 0x46, 0x48, 0x96, 0x2b, 0x69, 0xfc,
3058 0x11, 0xf8, 0x3f, 0xd3, 0x79, 0x09, 0x75, 0x81, 0x47, 0xdf, 0xce, 0xfe,
3059 0x07, 0x2f, 0x0a, 0xd8, 0xac, 0x87, 0x14, 0x1f, 0x7b, 0x95, 0x70, 0xee,
3060 0x7e, 0x52, 0x90, 0x11, 0xd6, 0x69, 0xf4, 0xd5, 0x38, 0x85, 0xc9, 0xc1,
3061 0x07, 0x01, 0xe8, 0xbb, 0xfb, 0xe2, 0x08, 0xa8, 0xfa, 0xbf, 0xf0, 0x92,
3062 0x63, 0x1d, 0xbb, 0x2b, 0x45, 0x6f, 0xce, 0x97, 0x01, 0xd7, 0x95, 0xf0,
3063 0x9c, 0x9a, 0x6b, 0x73, 0x01, 0xbf, 0xf9, 0x3d, 0xc8, 0x2b, 0x86, 0x7a,
3064 0xd5, 0x65, 0x84, 0xd7, 0xff, 0xb2, 0xf9, 0x20, 0x52, 0x35, 0xc5, 0x60,
3065 0x33, 0x70, 0x1d, 0x2f, 0x26, 0x09, 0x1c, 0x22, 0x17, 0xd8, 0x08, 0x4e,
3066 0x69, 0x20, 0xe2, 0x71, 0xe4, 0x07, 0xb1, 0x48, 0x5f, 0x20, 0x08, 0x7a,
3067 0xbf, 0x65, 0x53, 0x23, 0x07, 0xf9, 0x6c, 0xde, 0x3e, 0x29, 0xbf, 0x6b,
3068 0xef, 0xbb, 0x6a, 0x5f, 0x79, 0xa1, 0x72, 0xa1, 0x10, 0x24, 0x80, 0xb4,
3069 0x44, 0xb8, 0xc9, 0xfc, 0xa3, 0x36, 0x7e, 0x23, 0x37, 0x58, 0xc6, 0x1e,
3070 0xe8, 0x42, 0x4d, 0xb5, 0xf5, 0x58, 0x93, 0x21, 0x38, 0xa2, 0xc4, 0xa9,
3071 0x01, 0x96, 0xf9, 0x61, 0xac, 0x55, 0xb3, 0x3d, 0xe4, 0x54, 0x8b, 0x6c,
3072 0xc3, 0x83, 0xff, 0x50, 0x87, 0x94, 0xe8, 0x35, 0x3c, 0x26, 0x0d, 0x20,
3073 0x8a, 0x25, 0x0e, 0xb6, 0x67, 0x78, 0x29, 0xc7, 0xbf, 0x76, 0x8e, 0x62,
3074 0x62, 0xc4, 0x50, 0xd6, 0xc5, 0x3c, 0xb4, 0x7a, 0x35, 0xbe, 0x53, 0x52,
3075 0xc4, 0xe4, 0x10, 0xb3, 0xe0, 0x73, 0xb0, 0xd1, 0xc1, 0x5a, 0x4f, 0x4e,
3076 0x64, 0x0d, 0x92, 0x51, 0x2d, 0x4d, 0xec, 0xb0, 0xc6, 0x40, 0x1b, 0x03,
3077 0x89, 0x7f, 0xc2, 0x2c, 0xe3, 0x2c, 0xbd, 0x8c, 0x9c, 0xd9, 0xe0, 0x08,
3078 0x59, 0xd3, 0xaf, 0x48, 0x56, 0x89, 0x60, 0x85, 0x76, 0xe0, 0xd8, 0x7c,
3079 0xcf, 0x02, 0x8f, 0xfd, 0xb2, 0x8f, 0x2b, 0x61, 0xcf, 0x28, 0x56, 0x8b,
3080 0x6b, 0x03, 0x2b, 0x2f, 0x83, 0x31, 0xa0, 0x1c, 0xd1, 0x6c, 0x87, 0x49,
3081 0xc4, 0x77, 0x55, 0x1f, 0x61, 0x45, 0x58, 0x88, 0x9f, 0x01, 0xc3, 0x63,
3082 0x62, 0x30, 0x35, 0xdf, 0x61, 0x74, 0x55, 0x63, 0x3f, 0xae, 0x41, 0xc1,
3083 0xb8, 0xf0, 0x9f, 0xab, 0x25, 0xad, 0x41, 0x5c, 0x1f, 0x00, 0x0d, 0xef,
3084 0xf0, 0xcf, 0xaf, 0x41, 0x23, 0xca, 0x8c, 0x38, 0xea, 0x5a, 0xe4, 0x8b,
3085 0xb4, 0x89, 0xd0, 0x76, 0x7f, 0x2b, 0x77, 0x8f, 0xe4, 0x44, 0xd5, 0x37,
3086 0xac, 0xc2, 0x09, 0x7e, 0x7e, 0x7e, 0x02, 0x5c, 0x27, 0x01, 0xcb, 0x4d,
3087 0xea, 0xb3, 0x97, 0x36, 0x35, 0xd2, 0x05, 0x3c, 0x4e, 0xb8, 0x04, 0x5c,
3088 0xb8, 0x95, 0x3f, 0xc6, 0xbf, 0xd4, 0x20, 0x01, 0xfb, 0xed, 0x37, 0x5a,
3089 0xad, 0x4c, 0x61, 0x93, 0xfe, 0x95, 0x7c, 0x34, 0x11, 0x15, 0x9d, 0x00,
3090 0x0b, 0x99, 0x69, 0xcb, 0x7e, 0xb9, 0x53, 0x46, 0x57, 0x39, 0x3f, 0x59,
3091 0x4b, 0x30, 0x8d, 0xfb, 0x84, 0x66, 0x2d, 0x06, 0xc9, 0x88, 0xa6, 0x18,
3092 0xd7, 0x36, 0xc6, 0xf6, 0xf7, 0x47, 0x85, 0x38, 0xc8, 0x3d, 0x37, 0xea,
3093 0x57, 0x4c, 0xb0, 0x7c, 0x95, 0x29, 0x84, 0xab, 0xbb, 0x19, 0x86, 0xc2,
3094 0xc5, 0x99, 0x01, 0x38, 0x6b, 0xf1, 0xd3, 0x1d, 0xa8, 0x02, 0xf9, 0x6f,
3095 0xaa, 0xf1, 0x57, 0xd0, 0x88, 0x68, 0x62, 0x5f, 0x9f, 0x7a, 0x63, 0xba,
3096 0x3a, 0xc9, 0x95, 0x11, 0x3c, 0xf9, 0xa1, 0xc1, 0x35, 0xfe, 0xd5, 0x12,
3097 0x49, 0x88, 0x0d, 0x5c, 0xe2, 0xd1, 0x15, 0x18, 0xfb, 0xd5, 0x7f, 0x19,
3098 0x3f, 0xaf, 0xa0, 0xcb, 0x31, 0x20, 0x9e, 0x03, 0x93, 0xa4, 0x66, 0xbd,
3099 0x83, 0xe8, 0x60, 0x34, 0x55, 0x0d, 0x97, 0x10, 0x23, 0x24, 0x7a, 0x45,
3100 0x36, 0xb4, 0xc4, 0xee, 0x60, 0x6f, 0xd8, 0x46, 0xc5, 0xac, 0x2b, 0xa9,
3101 0x18, 0x74, 0x83, 0x1e, 0xdf, 0x7c, 0x1a, 0x5a, 0xe8, 0x5f, 0x8b, 0x4f,
3102 0x9f, 0x40, 0x3e, 0x5e, 0xfb, 0xd3, 0x68, 0xac, 0x34, 0x62, 0x30, 0x23,
3103 0xb6, 0xbc, 0xdf, 0xbc, 0xc7, 0x25, 0xd2, 0x1b, 0x57, 0x33, 0xfb, 0x78,
3104 0x22, 0x21, 0x1e, 0x3a, 0xf6, 0x44, 0x18, 0x7e, 0x12, 0x36, 0x47, 0x58,
3105 0xd0, 0x59, 0x26, 0x98, 0x98, 0x95, 0xf4, 0xd1, 0xaa, 0x45, 0xaa, 0xe7,
3106 0xd1, 0xe6, 0x2d, 0x78, 0xf0, 0x8b, 0x1c, 0xfd, 0xf8, 0x50, 0x60, 0xa2,
3107 0x1e, 0x7f, 0xe3, 0x31, 0x77, 0x31, 0x58, 0x99, 0x0f, 0xda, 0x0e, 0xa3,
3108 0xc6, 0x7a, 0x30, 0x45, 0x55, 0x11, 0x91, 0x77, 0x41, 0x79, 0xd3, 0x56,
3109 0xb2, 0x07, 0x00, 0x61, 0xab, 0xec, 0x27, 0xc7, 0x9f, 0xfa, 0x89, 0x08,
3110 0xc2, 0x87, 0xcf, 0xe9, 0xdc, 0x9e, 0x29, 0x22, 0xfb, 0x23, 0x7f, 0x9d,
3111 0x89, 0xd5, 0x6e, 0x75, 0x20, 0xd8, 0x00, 0x5b, 0xc4, 0x94, 0xbb, 0xc5,
3112 0xb2, 0xba, 0x77, 0x2b, 0xf6, 0x3c, 0x88, 0xb0, 0x4c, 0x38, 0x46, 0x55,
3113 0xee, 0x8b, 0x03, 0x15, 0xbc, 0x0a, 0x1d, 0x47, 0x87, 0x44, 0xaf, 0xb1,
3114 0x2a, 0xa7, 0x4d, 0x08, 0xdf, 0x3b, 0x2d, 0x70, 0xa1, 0x67, 0x31, 0x76,
3115 0x6e, 0x6f, 0x40, 0x3b, 0x3b, 0xe8, 0xf9, 0xdf, 0x90, 0xa4, 0xce, 0x7f,
3116 0xb8, 0x2d, 0x69, 0xcb, 0x1c, 0x1e, 0x94, 0xcd, 0xb1, 0xd8, 0x43, 0x22,
3117 0xb8, 0x4f, 0x98, 0x92, 0x74, 0xb3, 0xde, 0xeb, 0x7a, 0xcb, 0xfa, 0xd0,
3118 0x36, 0xe4, 0x5d, 0xfa, 0xd3, 0xce, 0xf9, 0xba, 0x3e, 0x0f, 0x6c, 0xc3,
3119 0x5b, 0xb3, 0x81, 0x84, 0x6e, 0x5d, 0xc1, 0x21, 0x89, 0xec, 0x67, 0x9a,
3120 0xfd, 0x55, 0x20, 0xb0, 0x71, 0x53, 0xae, 0xf8, 0xa4, 0x8d, 0xd5, 0xe5,
3121 0x2d, 0x3a, 0xce, 0x89, 0x55, 0x8c, 0x4f, 0x3b, 0x37, 0x95, 0x4e, 0x15,
3122 0xbe, 0xe7, 0xd1, 0x7a, 0x36, 0x82, 0x45, 0x69, 0x7c, 0x27, 0x4f, 0xb9,
3123 0x4b, 0x7d, 0xcd, 0x59, 0xc8, 0xf4, 0x8b, 0x0f, 0x4f, 0x75, 0x23, 0xd3,
3124 0xd0, 0xc7, 0x10, 0x79, 0xc0, 0xf1, 0xac, 0x14, 0xf7, 0x0d, 0xc8, 0x5e,
3125 0xfc, 0xff, 0x1a, 0x2b, 0x10, 0x88, 0x7e, 0x7e, 0x2f, 0xfa, 0x7b, 0x9f,
3126 0x47, 0x23, 0x34, 0xfc, 0xf5, 0xde, 0xd9, 0xa3, 0x05, 0x99, 0x2a, 0x96,
3127 0x83, 0x3d, 0xa4, 0x7f, 0x6a, 0x66, 0x9b, 0xe7, 0xf1, 0x00, 0x4e, 0x9a,
3128 0xfc, 0x68, 0xd2, 0x74, 0x17, 0xba, 0xc9, 0xc8, 0x20, 0x39, 0xa1, 0xa8,
3129 0x85, 0xc6, 0x10, 0x2b, 0xab, 0x97, 0x34, 0x2d, 0x49, 0x68, 0x57, 0xb0,
3130 0x43, 0xee, 0x25, 0xbb, 0x35, 0x1b, 0x03, 0x99, 0xa3, 0x21, 0x68, 0x66,
3131 0x86, 0x3f, 0xc6, 0xfc, 0x49, 0xf0, 0xba, 0x5f, 0x00, 0xc6, 0xe3, 0x1c,
3132 0xb2, 0x9f, 0x16, 0x7f, 0xc7, 0x40, 0x4a, 0x9a, 0x39, 0xc1, 0x95, 0x69,
3133 0xa2, 0x87, 0xba, 0x58, 0xc6, 0xf2, 0xd6, 0x66, 0xa6, 0x4c, 0x6d, 0x29,
3134 0x9c, 0xa8, 0x6e, 0xa9, 0xd2, 0xe4, 0x54, 0x17, 0x89, 0xe2, 0x43, 0xf0,
3135 0xe1, 0x8b, 0x57, 0x84, 0x6c, 0x87, 0x63, 0x17, 0xbb, 0xf6, 0x33, 0x1b,
3136 0xe4, 0x34, 0x6a, 0x80, 0x70, 0x7b, 0x1b, 0xfd, 0xf8, 0x79, 0x28, 0xc8,
3137 0x3c, 0x8e, 0xa4, 0xd5, 0xb8, 0x96, 0x54, 0xd4, 0xec, 0x72, 0xe5, 0x40,
3138 0x8f, 0x56, 0xde, 0x82, 0x15, 0x72, 0x4d, 0xd8, 0x0c, 0x07, 0xea, 0xe6,
3139 0x44, 0xcd, 0x94, 0x73, 0x5c, 0x04, 0xe8, 0x8e, 0xb7, 0xc7, 0xc9, 0x29,
3140 0xdc, 0x04, 0xef, 0x7c, 0x31, 0x9b, 0x50, 0xbc, 0xea, 0x71, 0x1f, 0x28,
3141 0x22, 0xb6, 0x04, 0x53, 0x2e, 0x71, 0xc4, 0xf6, 0xbb, 0x88, 0x51, 0xee,
3142 0x3e, 0x76, 0x65, 0xb4, 0x4b, 0x1b, 0xa3, 0xec, 0x7b, 0xa7, 0x9d, 0x31,
3143 0x5d, 0xb8, 0x9f, 0xab, 0x6b, 0x54, 0x7d, 0xbd, 0xc1, 0x2c, 0x55, 0xb0,
3144 0x23, 0x8c, 0x06, 0x60, 0x01, 0x4f, 0x60, 0x85, 0x56, 0x7f, 0xfb, 0x99,
3145 0x0c, 0xdc, 0x8c, 0x09, 0x37, 0x46, 0x5b, 0x97, 0x5d, 0xe8, 0x31, 0x00,
3146 0x1b, 0x30, 0x9b, 0x02, 0x92, 0x29, 0xb5, 0x20, 0xce, 0x4b, 0x90, 0xfb,
3147 0x91, 0x07, 0x5a, 0xd3, 0xf5, 0xa0, 0xe6, 0x8f, 0xf8, 0x73, 0xc5, 0x4b,
3148 0xbb, 0xad, 0x2a, 0xeb, 0xa8, 0xb7, 0x68, 0x34, 0x36, 0x47, 0xd5, 0x4b,
3149 0x61, 0x89, 0x53, 0xe6, 0xb6, 0xb1, 0x07, 0xe4, 0x08, 0x2e, 0xed, 0x50,
3150 0xd4, 0x1e, 0xed, 0x7f, 0xbf, 0x35, 0x68, 0x04, 0x45, 0x72, 0x86, 0x71,
3151 0x15, 0x55, 0xdf, 0xe6, 0x30, 0xc0, 0x8b, 0x8a, 0xb0, 0x6c, 0xd0, 0x35,
3152 0x57, 0x8f, 0x04, 0x37, 0xbc, 0xe1, 0xb8, 0xbf, 0x27, 0x37, 0x3d, 0xd0,
3153 0xc8, 0x46, 0x67, 0x42, 0x51, 0x30, 0x82, 0x05, 0xbd, 0x06, 0x09, 0x2a,
3154 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0xae,
3155 0x04, 0x82, 0x05, 0xaa, 0x30, 0x82, 0x05, 0xa6, 0x30, 0x82, 0x05, 0xa2,
3156 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01,
3157 0x02, 0xa0, 0x82, 0x04, 0xee, 0x30, 0x82, 0x04, 0xea, 0x30, 0x1c, 0x06,
3158 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30,
3159 0x0e, 0x04, 0x08, 0x9f, 0xa4, 0x72, 0x2b, 0x6b, 0x0e, 0xcb, 0x9f, 0x02,
3160 0x02, 0x08, 0x00, 0x04, 0x82, 0x04, 0xc8, 0xe5, 0x35, 0xb9, 0x72, 0x28,
3161 0x20, 0x28, 0xad, 0xe3, 0x01, 0xd7, 0x0b, 0xe0, 0x4e, 0x36, 0xc3, 0x73,
3162 0x06, 0xd5, 0xf6, 0x75, 0x1a, 0x78, 0xb2, 0xd8, 0xf6, 0x5a, 0x85, 0x8e,
3163 0x50, 0xa3, 0x05, 0x49, 0x02, 0x2d, 0xf8, 0xa3, 0x2f, 0xe6, 0x02, 0x7a,
3164 0xd5, 0x0b, 0x1d, 0xf1, 0xd1, 0xe4, 0x16, 0xaa, 0x70, 0x2e, 0x34, 0xdb,
3165 0x56, 0xd9, 0x33, 0x94, 0x11, 0xaa, 0x60, 0xd4, 0xfa, 0x5b, 0xd1, 0xb3,
3166 0x2e, 0x86, 0x6a, 0x5a, 0x69, 0xdf, 0x11, 0x91, 0xb0, 0xca, 0x82, 0xff,
3167 0x63, 0xad, 0x6a, 0x0b, 0x90, 0xa6, 0xc7, 0x9b, 0xef, 0x9a, 0xf8, 0x96,
3168 0xec, 0xe4, 0xc4, 0xdf, 0x55, 0x4c, 0x12, 0x07, 0xab, 0x7c, 0x5c, 0x68,
3169 0x47, 0xf2, 0x92, 0xfb, 0x94, 0xab, 0xc3, 0x64, 0xd3, 0xfe, 0xb2, 0x16,
3170 0xb4, 0x78, 0x80, 0x52, 0xe9, 0x32, 0x39, 0x3b, 0x8d, 0x12, 0x91, 0x36,
3171 0xfd, 0xa1, 0x97, 0xc2, 0x0a, 0x4a, 0xf1, 0xb3, 0x8a, 0xe4, 0x01, 0xed,
3172 0x0a, 0xda, 0x2e, 0xa0, 0x38, 0xa9, 0x47, 0x3d, 0x3a, 0x64, 0x87, 0x06,
3173 0xc3, 0x83, 0x60, 0xaf, 0x84, 0xdb, 0x87, 0xff, 0x70, 0x61, 0x43, 0x7d,
3174 0x2d, 0x61, 0x9a, 0xf7, 0x0d, 0xca, 0x0c, 0x0f, 0xbe, 0x43, 0x5b, 0x99,
3175 0xe1, 0x90, 0x64, 0x1f, 0xa7, 0x1b, 0xa6, 0xa6, 0x5c, 0x13, 0x70, 0xa3,
3176 0xdb, 0xd7, 0xf0, 0xe8, 0x7a, 0xb0, 0xd1, 0x9b, 0x52, 0xa6, 0x4f, 0xd6,
3177 0xff, 0x54, 0x4d, 0xa6, 0x15, 0x05, 0x5c, 0xe9, 0x04, 0x6a, 0xc3, 0x49,
3178 0x12, 0x2f, 0x24, 0x03, 0xc3, 0x80, 0x06, 0xa6, 0x07, 0x8b, 0x96, 0xe7,
3179 0x39, 0x31, 0x6d, 0xd3, 0x1b, 0xa5, 0x45, 0x58, 0x04, 0xe7, 0x87, 0xdf,
3180 0x26, 0xfb, 0x1b, 0x9f, 0x92, 0x93, 0x32, 0x12, 0x9a, 0xc9, 0xe6, 0xcb,
3181 0x88, 0x14, 0x9f, 0x23, 0x0b, 0x52, 0xa2, 0xb8, 0x32, 0x6c, 0xa9, 0x33,
3182 0xa1, 0x17, 0xe8, 0x4a, 0xd4, 0x5c, 0x7d, 0xb3, 0xa3, 0x64, 0x86, 0x03,
3183 0x7c, 0x7c, 0x3f, 0x99, 0xdc, 0x21, 0x9f, 0x93, 0xc6, 0xb9, 0x1d, 0xe0,
3184 0x21, 0x79, 0x78, 0x35, 0xdc, 0x1e, 0x27, 0x3c, 0x73, 0x7f, 0x0f, 0xd6,
3185 0x4f, 0xde, 0xe9, 0xb4, 0xb7, 0xe3, 0xf5, 0x72, 0xce, 0x42, 0xf3, 0x91,
3186 0x5b, 0x84, 0xba, 0xbb, 0xae, 0xf0, 0x87, 0x0f, 0x50, 0xa4, 0x5e, 0x80,
3187 0x23, 0x57, 0x2b, 0xa0, 0xa3, 0xc3, 0x8a, 0x2f, 0xa8, 0x7a, 0x1a, 0x65,
3188 0x8f, 0x62, 0xf8, 0x3e, 0xe2, 0xcd, 0xbc, 0x63, 0x56, 0x8e, 0x77, 0xf3,
3189 0xf9, 0x69, 0x10, 0x57, 0xa8, 0xaf, 0x67, 0x2a, 0x9f, 0x7f, 0x7e, 0xeb,
3190 0x1d, 0x99, 0xa6, 0x67, 0xcd, 0x9e, 0x42, 0x2e, 0x5e, 0x4e, 0x61, 0x24,
3191 0xfa, 0xca, 0x2a, 0xeb, 0x62, 0x1f, 0xa3, 0x14, 0x0a, 0x06, 0x4b, 0x77,
3192 0x78, 0x77, 0x9b, 0xf1, 0x03, 0xcc, 0xb5, 0xfe, 0xfb, 0x7a, 0x77, 0xa6,
3193 0x82, 0x9f, 0xe5, 0xde, 0x9d, 0x0d, 0x4d, 0x37, 0xc6, 0x12, 0x73, 0x6d,
3194 0xea, 0xbb, 0x48, 0xf0, 0xd2, 0x81, 0xcc, 0x1a, 0x47, 0xfa, 0xa4, 0xd2,
3195 0xb2, 0x27, 0xa0, 0xfc, 0x30, 0x04, 0xdb, 0x05, 0xd3, 0x0b, 0xbc, 0x4d,
3196 0x7a, 0x99, 0xef, 0x7f, 0x26, 0x01, 0xd4, 0x07, 0x0b, 0x1e, 0x99, 0x06,
3197 0x3c, 0xde, 0x3d, 0x1c, 0x21, 0x82, 0x68, 0x46, 0x35, 0x38, 0x61, 0xea,
3198 0xd4, 0xc2, 0x65, 0x09, 0x39, 0x87, 0xb4, 0xd3, 0x5d, 0x3c, 0xa3, 0x79,
3199 0xe4, 0x01, 0x4e, 0xbf, 0x18, 0xba, 0x57, 0x3f, 0xdd, 0xea, 0x0a, 0x6b,
3200 0x99, 0xfb, 0x93, 0xfa, 0xab, 0xee, 0x08, 0xdf, 0x38, 0x23, 0xae, 0x8d,
3201 0xa8, 0x03, 0x13, 0xfe, 0x83, 0x88, 0xb0, 0xc2, 0xf9, 0x90, 0xa5, 0x1c,
3202 0x01, 0x6f, 0x71, 0x91, 0x42, 0x35, 0x81, 0x74, 0x71, 0x6c, 0xba, 0x86,
3203 0x48, 0xfe, 0x96, 0xd2, 0x88, 0x12, 0x36, 0x4e, 0xa6, 0x2f, 0xd1, 0xdb,
3204 0xfa, 0xbf, 0xdb, 0x84, 0x01, 0xfc, 0x7d, 0x7a, 0xac, 0x20, 0xae, 0xf5,
3205 0x95, 0xc9, 0xdc, 0x10, 0x5f, 0x4c, 0xae, 0x85, 0x01, 0x8b, 0xfe, 0x77,
3206 0x13, 0x01, 0xae, 0x39, 0x59, 0x7e, 0xbc, 0xfd, 0xc9, 0x42, 0xe4, 0x13,
3207 0x07, 0x3f, 0xa9, 0x74, 0xd9, 0xd5, 0xfc, 0xb9, 0x78, 0xbe, 0x97, 0xf5,
3208 0xe7, 0x36, 0x7f, 0xfa, 0x23, 0x30, 0xeb, 0xab, 0x92, 0xd3, 0xdc, 0x3f,
3209 0x7f, 0xc0, 0x77, 0x93, 0xf9, 0x88, 0xe3, 0x4e, 0x13, 0x53, 0x6d, 0x71,
3210 0x87, 0xe9, 0x24, 0x2b, 0xae, 0x26, 0xbf, 0x62, 0x51, 0x04, 0x42, 0xe1,
3211 0x13, 0x9d, 0xd8, 0x9f, 0x59, 0x87, 0x3f, 0xfc, 0x94, 0xff, 0xcf, 0x88,
3212 0x88, 0xe6, 0xeb, 0x6e, 0xc1, 0x96, 0x04, 0x27, 0xc8, 0xda, 0xfa, 0xe8,
3213 0x2e, 0xbb, 0x2c, 0x6e, 0xf4, 0xb4, 0x00, 0x7d, 0x8d, 0x3b, 0xef, 0x8b,
3214 0x18, 0xa9, 0x5f, 0x32, 0xa9, 0xf2, 0x3a, 0x7e, 0x65, 0x2d, 0x6e, 0x8d,
3215 0x75, 0x77, 0xf6, 0xa6, 0xd8, 0xf9, 0x6b, 0x51, 0xe6, 0x66, 0x52, 0x59,
3216 0x39, 0x97, 0x22, 0xda, 0xb2, 0xd6, 0x82, 0x5a, 0x6e, 0x61, 0x60, 0x16,
3217 0x48, 0x7b, 0xf1, 0xc3, 0x4d, 0x7f, 0x50, 0xfa, 0x4d, 0x58, 0x27, 0x30,
3218 0xc8, 0x96, 0xe0, 0x41, 0x4f, 0x6b, 0xeb, 0x88, 0xa2, 0x7a, 0xef, 0x8a,
3219 0x88, 0xc8, 0x50, 0x4b, 0x55, 0x66, 0xee, 0xbf, 0xc4, 0x01, 0x82, 0x4c,
3220 0xec, 0xde, 0x37, 0x64, 0xd6, 0x1e, 0xcf, 0x3e, 0x2e, 0xfe, 0x84, 0x68,
3221 0xbf, 0xa3, 0x68, 0x77, 0xa9, 0x03, 0xe4, 0xf8, 0xd7, 0xb2, 0x6e, 0xa3,
3222 0xc4, 0xc3, 0x36, 0x53, 0xf3, 0xdd, 0x7e, 0x4c, 0xf0, 0xe9, 0xb2, 0x44,
3223 0xe6, 0x60, 0x3d, 0x00, 0x9a, 0x08, 0xc3, 0x21, 0x17, 0x49, 0xda, 0x49,
3224 0xfb, 0x4c, 0x8b, 0xe9, 0x10, 0x66, 0xfe, 0xb7, 0xe0, 0xf9, 0xdd, 0xbf,
3225 0x41, 0xfe, 0x04, 0x9b, 0x7f, 0xe8, 0xd6, 0x2e, 0x4d, 0x0f, 0x7b, 0x10,
3226 0x73, 0x4c, 0xa1, 0x3e, 0x43, 0xb7, 0xcf, 0x94, 0x97, 0x7e, 0x24, 0xbb,
3227 0x87, 0xbf, 0x22, 0xb8, 0x3e, 0xeb, 0x9a, 0x3f, 0xe3, 0x86, 0xee, 0x21,
3228 0xbc, 0xf5, 0x44, 0xeb, 0x60, 0x2e, 0xe7, 0x8f, 0x89, 0xa4, 0x91, 0x61,
3229 0x28, 0x90, 0x85, 0x68, 0xe0, 0xa9, 0x62, 0x93, 0x86, 0x5a, 0x15, 0xbe,
3230 0xb2, 0x76, 0x83, 0xf2, 0x0f, 0x00, 0xc7, 0xb6, 0x57, 0xe9, 0x1f, 0x92,
3231 0x49, 0xfe, 0x50, 0x85, 0xbf, 0x39, 0x3d, 0xe4, 0x8b, 0x72, 0x2d, 0x49,
3232 0xbe, 0x05, 0x0a, 0x34, 0x56, 0x80, 0xc6, 0x1f, 0x46, 0x59, 0xc9, 0xfe,
3233 0x40, 0xfb, 0x78, 0x6d, 0x7a, 0xe5, 0x30, 0xe9, 0x81, 0x55, 0x75, 0x05,
3234 0x63, 0xd2, 0x22, 0xee, 0x2e, 0x6e, 0xb9, 0x18, 0xe5, 0x8a, 0x5a, 0x66,
3235 0xbd, 0x74, 0x30, 0xe3, 0x8b, 0x76, 0x22, 0x18, 0x1e, 0xef, 0x69, 0xe8,
3236 0x9d, 0x07, 0xa7, 0x9a, 0x87, 0x6c, 0x04, 0x4b, 0x74, 0x2b, 0xbe, 0x37,
3237 0x2f, 0x29, 0x9b, 0x60, 0x9d, 0x8b, 0x57, 0x55, 0x34, 0xca, 0x41, 0x25,
3238 0xae, 0x56, 0x92, 0x34, 0x1b, 0x9e, 0xbd, 0xfe, 0x74, 0xbd, 0x4e, 0x29,
3239 0xf0, 0x5e, 0x27, 0x94, 0xb0, 0x9e, 0x23, 0x9f, 0x4a, 0x0f, 0xa1, 0xdf,
3240 0xe7, 0xc4, 0xdb, 0xbe, 0x0f, 0x1a, 0x0b, 0x6c, 0xb0, 0xe1, 0x06, 0x7c,
3241 0x5a, 0x5b, 0x81, 0x1c, 0xb6, 0x12, 0xec, 0x6f, 0x3b, 0xbb, 0x84, 0x36,
3242 0xd5, 0x28, 0x16, 0xea, 0x51, 0xa8, 0x99, 0x24, 0x8f, 0xe7, 0xf8, 0xe9,
3243 0xce, 0xa1, 0x65, 0x96, 0x6f, 0x4e, 0x2f, 0xb7, 0x6f, 0x65, 0x39, 0xad,
3244 0xfd, 0x2e, 0xa0, 0x37, 0x32, 0x2f, 0xf3, 0x95, 0xa1, 0x3a, 0xa1, 0x9d,
3245 0x2c, 0x9e, 0xa1, 0x4b, 0x7e, 0xc9, 0x7e, 0x86, 0xaa, 0x16, 0x00, 0x82,
3246 0x1d, 0x36, 0xbf, 0x98, 0x0a, 0x82, 0x5b, 0xcc, 0xc4, 0x6a, 0xad, 0xa0,
3247 0x1f, 0x47, 0x98, 0xde, 0x8d, 0x68, 0x38, 0x3f, 0x33, 0xe2, 0x08, 0x3b,
3248 0x2a, 0x65, 0xd9, 0x2f, 0x53, 0x68, 0xb8, 0x78, 0xd0, 0x1d, 0xbb, 0x2a,
3249 0x73, 0x19, 0xba, 0x58, 0xea, 0xf1, 0x0a, 0xaa, 0xa6, 0xbe, 0x27, 0xd6,
3250 0x00, 0x6b, 0x4e, 0x43, 0x8e, 0x5b, 0x19, 0xc1, 0x37, 0x0f, 0xfb, 0x81,
3251 0x72, 0x10, 0xb6, 0x20, 0x32, 0xcd, 0xa2, 0x7c, 0x90, 0xd4, 0xf5, 0xcf,
3252 0x1c, 0xcb, 0x14, 0x24, 0x7a, 0x4d, 0xf5, 0xd5, 0xd9, 0xce, 0x6a, 0x64,
3253 0xc9, 0xd3, 0xa7, 0x36, 0x6f, 0x1d, 0xf1, 0xe9, 0x71, 0x6c, 0x3d, 0x02,
3254 0xa4, 0x62, 0xb1, 0x82, 0x5c, 0x13, 0x4b, 0x6b, 0x68, 0xe2, 0x31, 0xef,
3255 0xe4, 0x46, 0xfd, 0xe5, 0xa8, 0x29, 0xe9, 0x1e, 0xad, 0xff, 0x33, 0xdb,
3256 0x0b, 0xc0, 0x92, 0xb1, 0xef, 0xeb, 0xb3, 0x6f, 0x96, 0x7b, 0xdf, 0xcd,
3257 0x07, 0x19, 0x86, 0x60, 0x98, 0xcf, 0x95, 0xfe, 0x98, 0xdd, 0x29, 0xa6,
3258 0x35, 0x7b, 0x46, 0x13, 0x03, 0xa8, 0xd9, 0x7c, 0xb3, 0xdf, 0x9f, 0x14,
3259 0xb7, 0x34, 0x5a, 0xc4, 0x12, 0x81, 0xc5, 0x98, 0x25, 0x8d, 0x3e, 0xe3,
3260 0xd8, 0x2d, 0xe4, 0x54, 0xab, 0xb0, 0x13, 0xfd, 0xd1, 0x3f, 0x3b, 0xbf,
3261 0xa9, 0x45, 0x28, 0x8a, 0x2f, 0x9c, 0x1e, 0x2d, 0xe5, 0xab, 0x13, 0x95,
3262 0x97, 0xc3, 0x34, 0x37, 0x8d, 0x93, 0x66, 0x31, 0x81, 0xa0, 0x30, 0x23,
3263 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31,
3264 0x16, 0x04, 0x14, 0xa5, 0x23, 0x9b, 0x7e, 0xe6, 0x45, 0x71, 0xbf, 0x48,
3265 0xc6, 0x27, 0x3c, 0x96, 0x87, 0x63, 0xbd, 0x1f, 0xde, 0x72, 0x12, 0x30,
3266 0x79, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x11, 0x01,
3267 0x31, 0x6c, 0x1e, 0x6a, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72,
3268 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20,
3269 0x00, 0x45, 0x00, 0x6e, 0x00, 0x68, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63,
3270 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x52, 0x00, 0x53, 0x00, 0x41,
3271 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x41,
3272 0x00, 0x45, 0x00, 0x53, 0x00, 0x20, 0x00, 0x43, 0x00, 0x72, 0x00, 0x79,
3273 0x00, 0x70, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x67, 0x00, 0x72, 0x00, 0x61,
3274 0x00, 0x70, 0x00, 0x68, 0x00, 0x69, 0x00, 0x63, 0x00, 0x20, 0x00, 0x50,
3275 0x00, 0x72, 0x00, 0x6f, 0x00, 0x76, 0x00, 0x69, 0x00, 0x64, 0x00, 0x65,
3276 0x00, 0x72, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
3277 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x93, 0xa8, 0xb2, 0x7e, 0xb7,
3278 0xab, 0xf1, 0x1c, 0x3c, 0x36, 0x58, 0xdc, 0x67, 0x6d, 0x42, 0xa6, 0xfc,
3279 0x53, 0x01, 0xe6, 0x04, 0x08, 0x77, 0x57, 0x22, 0xa1, 0x7d, 0xb9, 0xa2,
3280 0x69, 0x02, 0x02, 0x08, 0x00
3283 static void test_PFXImportCertStore(void)
3285 HCERTSTORE store;
3286 CRYPT_DATA_BLOB pfx;
3287 const CERT_CONTEXT *cert;
3288 CERT_KEY_CONTEXT key;
3289 char buf[512];
3290 CRYPT_KEY_PROV_INFO *keyprov = (CRYPT_KEY_PROV_INFO *)buf;
3291 CERT_INFO *info;
3292 DWORD count, size;
3293 BOOL ret;
3295 SetLastError( 0xdeadbeef );
3296 store = PFXImportCertStore( NULL, NULL, 0 );
3297 ok( store == NULL, "got %p\n", store );
3298 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError() );
3300 pfx.pbData = (BYTE *)pfxdata;
3301 pfx.cbData = sizeof(pfxdata);
3302 store = PFXImportCertStore( &pfx, NULL, CRYPT_EXPORTABLE|CRYPT_USER_KEYSET|PKCS12_NO_PERSIST_KEY );
3303 ok( store != NULL || broken(store == NULL) /* winxp */, "got %u\n", GetLastError() );
3304 if (!store) return;
3305 count = countCertsInStore( store );
3306 ok( count == 1, "got %u\n", count );
3308 cert = CertFindCertificateInStore( store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL );
3309 ok( cert != NULL, "got %u\n", GetLastError() );
3310 ok( cert->dwCertEncodingType == X509_ASN_ENCODING, "got %u\n", cert->dwCertEncodingType );
3311 ok( cert->pbCertEncoded != NULL, "pbCertEncoded not set\n" );
3312 ok( cert->cbCertEncoded == 1123, "got %u\n", cert->cbCertEncoded );
3313 ok( cert->pCertInfo != NULL, "pCertInfo not set\n" );
3314 ok( cert->hCertStore == store, "got %p\n", cert->hCertStore );
3316 info = cert->pCertInfo;
3317 ok( info->dwVersion == CERT_V1, "got %u\n", info->dwVersion );
3318 ok( !strcmp(info->SignatureAlgorithm.pszObjId, szOID_RSA_SHA256RSA),
3319 "got \"%s\"\n", info->SignatureAlgorithm.pszObjId );
3321 size = sizeof(key);
3322 ret = CertGetCertificateContextProperty( cert, CERT_KEY_CONTEXT_PROP_ID, &key, &size );
3323 ok( ret, "got %08x\n", GetLastError() );
3324 ok( key.cbSize == sizeof(key), "got %u\n", key.cbSize );
3325 ok( key.hCryptProv, "hCryptProv not set\n" );
3326 ok( key.dwKeySpec == AT_KEYEXCHANGE, "got %u\n", key.dwKeySpec );
3328 size = sizeof(buf);
3329 SetLastError( 0xdeadbeef );
3330 ret = CertGetCertificateContextProperty( cert, CERT_KEY_PROV_INFO_PROP_ID, keyprov, &size );
3331 ok( !ret && GetLastError() == CRYPT_E_NOT_FOUND, "got %08x\n", GetLastError() );
3332 CertFreeCertificateContext( cert );
3333 CertCloseStore( store, 0 );
3335 /* without PKCS12_NO_PERSIST_KEY */
3336 store = PFXImportCertStore( &pfx, NULL, CRYPT_EXPORTABLE|CRYPT_USER_KEYSET );
3337 ok( store != NULL, "got %u\n", GetLastError() );
3339 cert = CertFindCertificateInStore( store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL );
3340 ok( cert != NULL, "got %08x\n", GetLastError() );
3342 size = sizeof(key);
3343 ret = CertGetCertificateContextProperty( cert, CERT_KEY_CONTEXT_PROP_ID, &key, &size );
3344 ok( !ret && GetLastError() == CRYPT_E_NOT_FOUND, "got %08x\n", GetLastError() );
3346 size = sizeof(buf);
3347 ret = CertGetCertificateContextProperty( cert, CERT_KEY_PROV_INFO_PROP_ID, buf, &size );
3348 ok(ret, "got %u\n", GetLastError());
3349 CertFreeCertificateContext( cert );
3350 CertCloseStore( store, 0 );
3352 /* CRYPT_MACHINE_KEYSET */
3353 store = PFXImportCertStore( &pfx, NULL, CRYPT_MACHINE_KEYSET );
3354 ok( store != NULL, "got %u\n", GetLastError() );
3356 cert = CertFindCertificateInStore( store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL );
3357 ok( cert != NULL, "got %08x\n", GetLastError() );
3359 CertFreeCertificateContext( cert );
3360 CertCloseStore( store, 0 );
3363 static void test_CryptQueryObject(void)
3365 CRYPT_DATA_BLOB pfx;
3366 DWORD encoding_type, content_type, format_type;
3367 HCERTSTORE store;
3368 HCRYPTMSG msg;
3369 const void *ctx;
3370 BOOL ret;
3372 SetLastError( 0xdeadbeef );
3373 ret = CryptQueryObject( CERT_QUERY_OBJECT_BLOB, NULL, CERT_QUERY_CONTENT_FLAG_ALL,
3374 CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, NULL, NULL, NULL );
3375 ok( !ret, "success\n" );
3376 ok( GetLastError() == E_INVALIDARG, "got %u\n", GetLastError() );
3378 pfx.pbData = (BYTE *)pfxdata;
3379 pfx.cbData = sizeof(pfxdata);
3380 encoding_type = content_type = format_type = 0xdeadbeef;
3381 store = (HCERTSTORE *)0xdeadbeef;
3382 msg = (HCRYPTMSG *)0xdeadbeef;
3383 ctx = (void *)0xdeadbeef;
3384 ret = CryptQueryObject( CERT_QUERY_OBJECT_BLOB, &pfx, CERT_QUERY_CONTENT_FLAG_ALL,
3385 CERT_QUERY_FORMAT_FLAG_BINARY, 0, &encoding_type, &content_type, &format_type,
3386 &store, &msg, &ctx );
3387 ok( ret, "got %u\n", GetLastError() );
3388 ok( encoding_type == X509_ASN_ENCODING, "got %08x\n", encoding_type );
3389 ok( content_type == CERT_QUERY_CONTENT_PFX, "got %08x\n", content_type );
3390 ok( format_type == CERT_QUERY_FORMAT_BINARY, "got %08x\n", format_type );
3391 ok( store == NULL, "got %p\n", store );
3392 ok( msg == NULL, "got %p\n", msg );
3393 ok( ctx == NULL, "got %p\n", ctx );
3396 START_TEST(store)
3398 /* various combinations of CertOpenStore */
3399 testMemStore();
3400 testCollectionStore();
3401 testStoresInCollection();
3403 testRegStore();
3404 testRegStoreSavedCerts();
3406 testSystemRegStore();
3407 testSystemStore();
3408 testFileStore();
3409 testFileNameStore();
3410 testMessageStore();
3411 testSerializedStore();
3412 testCloseStore();
3414 testCertRegisterSystemStore();
3416 testCertOpenSystemStore();
3417 testCertEnumSystemStore();
3418 testStoreProperty();
3420 testAddSerialized();
3421 testAddCertificateLink();
3423 testEmptyStore();
3425 test_I_UpdateStore();
3426 test_PFXImportCertStore();
3427 test_CryptQueryObject();