[CRYPT32_WINETEST] Sync with Wine Staging 2.9. CORE-13362
[reactos.git] / rostests / winetests / crypt32 / cert.c
1 /*
2 * crypt32 cert functions tests
3 *
4 * Copyright 2005-2006 Juan Lang
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 //#include <stdio.h>
22 #include <stdarg.h>
23
24 #include <windef.h>
25 #include <winbase.h>
26 //#include <winreg.h>
27 //#include <winerror.h>
28 #include <wincrypt.h>
29
30 #include <wine/test.h>
31
32 static PCCERT_CONTEXT (WINAPI *pCertCreateSelfSignCertificate)(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE,PCERT_NAME_BLOB,DWORD,PCRYPT_KEY_PROV_INFO,PCRYPT_ALGORITHM_IDENTIFIER,PSYSTEMTIME,PSYSTEMTIME,PCERT_EXTENSIONS);
33 static BOOL (WINAPI *pCertGetValidUsages)(DWORD,PCCERT_CONTEXT*,int*,LPSTR*,DWORD*);
34 static BOOL (WINAPI *pCryptAcquireCertificatePrivateKey)(PCCERT_CONTEXT,DWORD,void*,HCRYPTPROV_OR_NCRYPT_KEY_HANDLE*,DWORD*,BOOL*);
35 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*);
36 static BOOL (WINAPI * pCryptVerifyCertificateSignatureEx)
37 (HCRYPTPROV, DWORD, DWORD, void *, DWORD, void *, DWORD, void *);
38
39 static BOOL (WINAPI * pCryptAcquireContextA)
40 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
41
42 static void init_function_pointers(void)
43 {
44 HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll");
45 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
46
47 #define GET_PROC(dll, func) \
48 p ## func = (void *)GetProcAddress(dll, #func); \
49 if(!p ## func) \
50 trace("GetProcAddress(%s) failed\n", #func);
51
52 GET_PROC(hCrypt32, CertCreateSelfSignCertificate)
53 GET_PROC(hCrypt32, CertGetValidUsages)
54 GET_PROC(hCrypt32, CryptAcquireCertificatePrivateKey)
55 GET_PROC(hCrypt32, CryptEncodeObjectEx)
56 GET_PROC(hCrypt32, CryptVerifyCertificateSignatureEx)
57
58 GET_PROC(hAdvapi32, CryptAcquireContextA)
59
60 #undef GET_PROC
61 }
62
63 static BYTE subjectName[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
64 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
65 0x6e, 0x67, 0x00 };
66 static BYTE serialNum[] = { 1 };
67 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
68 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
69 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
70 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
71 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
72 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
73 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
74 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
75 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
76 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
77 static BYTE bigCertHash[] = { 0x6e, 0x30, 0x90, 0x71, 0x5f, 0xd9, 0x23,
78 0x56, 0xeb, 0xae, 0x25, 0x40, 0xe6, 0x22, 0xda, 0x19, 0x26, 0x02, 0xa6, 0x08 };
79
80 static const BYTE bigCertWithDifferentSubject[] = { 0x30, 0x7a, 0x02, 0x01, 0x02,
81 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
82 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67,
83 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31,
84 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
85 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15,
86 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c,
87 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06,
88 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
89 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
90 0x01, 0x01 };
91 static const BYTE bigCertWithDifferentIssuer[] = { 0x30, 0x7a, 0x02, 0x01,
92 0x01, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
93 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
94 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
95 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
96 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
97 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
98 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
99 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
100 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
101 0x02, 0x01, 0x01 };
102
103 static BYTE subjectName2[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
104 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61,
105 0x6e, 0x67, 0x00 };
106 static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
107 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
108 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
109 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
110 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
111 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
112 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20,
113 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
114 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
115 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
116 static const BYTE bigCert2WithDifferentSerial[] = { 0x30, 0x7a, 0x02, 0x01,
117 0x02, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
118 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
119 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
120 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
121 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
122 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41,
123 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
124 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
125 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
126 0x02, 0x01, 0x01 };
127 static BYTE bigCert2Hash[] = { 0x4a, 0x7f, 0x32, 0x1f, 0xcf, 0x3b, 0xc0,
128 0x87, 0x48, 0x2b, 0xa1, 0x86, 0x54, 0x18, 0xe4, 0x3a, 0x0e, 0x53, 0x7e, 0x2b };
129
130 static const BYTE certWithUsage[] = { 0x30, 0x81, 0x93, 0x02, 0x01, 0x01, 0x30,
131 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
132 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00,
133 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
134 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
135 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31,
136 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61,
137 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00,
138 0x03, 0x01, 0x00, 0xa3, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x1d,
139 0x25, 0x01, 0x01, 0xff, 0x04, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01,
140 0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
141 0x03, 0x02, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
142
143 static void testAddCert(void)
144 {
145 HCERTSTORE store;
146 HCERTSTORE collection;
147 PCCERT_CONTEXT context;
148 PCCERT_CONTEXT copyContext;
149 BOOL ret;
150
151 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
152 CERT_STORE_CREATE_NEW_FLAG, NULL);
153 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
154 if (!store)
155 return;
156
157 /* Weird--bad add disposition leads to an access violation in Windows.
158 * Both tests crash on some win9x boxes.
159 */
160 if (0)
161 {
162 ret = CertAddEncodedCertificateToStore(0, X509_ASN_ENCODING, bigCert,
163 sizeof(bigCert), 0, NULL);
164 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
165 GetLastError() == E_INVALIDARG),
166 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n",
167 GetLastError());
168 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
169 bigCert, sizeof(bigCert), 0, NULL);
170 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
171 GetLastError() == E_INVALIDARG),
172 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n",
173 GetLastError());
174 }
175
176 /* Weird--can add a cert to the NULL store (does this have special
177 * meaning?)
178 */
179 context = NULL;
180 ret = CertAddEncodedCertificateToStore(0, X509_ASN_ENCODING, bigCert,
181 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
182 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win98 */),
183 "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
184 if (context)
185 CertFreeCertificateContext(context);
186 if (!ret && GetLastError() == OSS_DATA_ERROR)
187 {
188 skip("bigCert can't be decoded, skipping tests\n");
189 return;
190 }
191
192 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
193 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
194 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
195 GetLastError());
196 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
197 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
198 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
199 GetLastError());
200 /* This has the same name as bigCert, so finding isn't done by name */
201 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
202 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, &context);
203 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
204 GetLastError());
205 ok(context != NULL, "Expected a context\n");
206 if (context)
207 {
208 CRYPT_DATA_BLOB hash = { sizeof(bigCert2Hash), bigCert2Hash };
209
210 /* Duplicate (AddRef) the context so we can still use it after
211 * deleting it from the store.
212 */
213 CertDuplicateCertificateContext(context);
214 CertDeleteCertificateFromStore(context);
215 /* Set the same hash as bigCert2, and try to readd it */
216 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID,
217 0, &hash);
218 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
219 GetLastError());
220 ret = CertAddCertificateContextToStore(store, context,
221 CERT_STORE_ADD_NEW, NULL);
222 /* The failure is a bit odd (CRYPT_E_ASN1_BADTAG), so just check
223 * that it fails.
224 */
225 ok(!ret, "Expected failure\n");
226 CertFreeCertificateContext(context);
227 }
228 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
229 sizeof(bigCert2));
230 ok(context != NULL, "Expected a context\n");
231 if (context)
232 {
233 /* Try to readd bigCert2 to the store */
234 ret = CertAddCertificateContextToStore(store, context,
235 CERT_STORE_ADD_NEW, NULL);
236 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
237 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
238 CertFreeCertificateContext(context);
239 }
240
241 /* Adding a cert with the same issuer name and serial number (but
242 * different subject) as an existing cert succeeds.
243 */
244 context = NULL;
245 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
246 bigCert2WithDifferentSerial, sizeof(bigCert2WithDifferentSerial),
247 CERT_STORE_ADD_NEW, &context);
248 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
249 GetLastError());
250 if (context)
251 CertDeleteCertificateFromStore(context);
252
253 /* Adding a cert with the same subject name and serial number (but
254 * different issuer) as an existing cert succeeds.
255 */
256 context = NULL;
257 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
258 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject),
259 CERT_STORE_ADD_NEW, &context);
260 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
261 GetLastError());
262 if (context)
263 CertDeleteCertificateFromStore(context);
264
265 /* Adding a cert with the same issuer name and serial number (but
266 * different otherwise) as an existing cert succeeds.
267 */
268 context = NULL;
269 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
270 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer),
271 CERT_STORE_ADD_NEW, &context);
272 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
273 GetLastError());
274 if (context)
275 CertDeleteCertificateFromStore(context);
276
277 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
278 CERT_STORE_CREATE_NEW_FLAG, NULL);
279 ok(collection != NULL, "CertOpenStore failed: %08x\n", GetLastError());
280 if (collection)
281 {
282 /* Add store to the collection, but disable updates */
283 CertAddStoreToCollection(collection, store, 0, 0);
284
285 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
286 sizeof(bigCert2));
287 ok(context != NULL, "Expected a context\n");
288 if (context)
289 {
290 /* Try to readd bigCert2 to the collection */
291 ret = CertAddCertificateContextToStore(collection, context,
292 CERT_STORE_ADD_NEW, NULL);
293 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
294 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
295 /* Replacing an existing certificate context is allowed, even
296 * though updates to the collection aren't..
297 */
298 ret = CertAddCertificateContextToStore(collection, context,
299 CERT_STORE_ADD_REPLACE_EXISTING, NULL);
300 ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
301 GetLastError());
302 /* use the existing certificate and ask for a copy of the context*/
303 copyContext = NULL;
304 ret = CertAddCertificateContextToStore(collection, context,
305 CERT_STORE_ADD_USE_EXISTING, &copyContext);
306 ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
307 GetLastError());
308 ok(copyContext != NULL, "Expected on output a non NULL copyContext\n");
309 if (copyContext)
310 CertFreeCertificateContext(copyContext);
311 /* but adding a new certificate isn't allowed. */
312 ret = CertAddCertificateContextToStore(collection, context,
313 CERT_STORE_ADD_ALWAYS, NULL);
314 ok(!ret && GetLastError() == E_ACCESSDENIED,
315 "Expected E_ACCESSDENIED, got %08x\n", GetLastError());
316 CertFreeCertificateContext(context);
317 }
318
319 CertCloseStore(collection, 0);
320 }
321
322 CertCloseStore(store, 0);
323 }
324
325 static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
326 PCCERT_CONTEXT context, DWORD propID)
327 {
328 BYTE hash[20] = { 0 }, hashProperty[20];
329 BOOL ret;
330 DWORD size;
331 DWORD dwSizeWithNull;
332
333 memset(hash, 0, sizeof(hash));
334 memset(hashProperty, 0, sizeof(hashProperty));
335 size = sizeof(hash);
336 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
337 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
338 ret = CertGetCertificateContextProperty(context, propID, NULL,
339 &dwSizeWithNull);
340 ok(ret, "algID %08x, propID %d: CertGetCertificateContextProperty failed: %08x\n",
341 algID, propID, GetLastError());
342 ret = CertGetCertificateContextProperty(context, propID, hashProperty,
343 &size);
344 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
345 GetLastError());
346 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
347 propID);
348 ok(size == dwSizeWithNull, "Unexpected length of hash for property: received %d instead of %d\n",
349 dwSizeWithNull,size);
350 }
351
352 static const CHAR cspNameA[] = "WineCryptTemp";
353 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e','m','p',0 };
354 static const BYTE v1CertWithPubKey[] = {
355 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
356 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
357 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
358 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
359 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
360 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
361 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
362 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
363 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
364 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
365 0x01,0x01 };
366 static const BYTE v1CertWithSubjectKeyId[] = {
367 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
368 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
369 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
370 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
371 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
372 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
373 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
374 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
375 0x4c,0x61,0x6e,0x67,0x00 };
376 static const BYTE subjectKeyId[] = {
377 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
378 static const BYTE selfSignedCert[] = {
379 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
380 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
381 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
382 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
383 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
384 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
385 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
386 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
387 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
388 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
389 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
390 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
391 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
392 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
393 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
394 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
395 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
396 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
397 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
398 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
399 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
400 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
401 0xa8, 0x76, 0x57, 0x92, 0x36 };
402 static const BYTE selfSignedSignatureHash[] = { 0x07,0x5a,0x3e,0xfd,0x0d,0xf6,
403 0x88,0xeb,0x00,0x64,0xbd,0xc9,0xd6,0xea,0x0a,0x7c,0xcc,0x24,0xdb,0x5d };
404
405 static void testCertProperties(void)
406 {
407 PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
408 bigCert, sizeof(bigCert));
409 DWORD propID, numProps, access, size;
410 BOOL ret;
411 BYTE hash[20] = { 0 }, hashProperty[20];
412 CRYPT_DATA_BLOB blob;
413 CERT_KEY_CONTEXT keyContext;
414
415 ok(context != NULL || broken(GetLastError() == OSS_DATA_ERROR /* win98 */),
416 "CertCreateCertificateContext failed: %08x\n", GetLastError());
417 if (!context)
418 return;
419
420 /* This crashes
421 propID = CertEnumCertificateContextProperties(NULL, 0);
422 */
423
424 propID = 0;
425 numProps = 0;
426 do {
427 propID = CertEnumCertificateContextProperties(context, propID);
428 if (propID)
429 numProps++;
430 } while (propID != 0);
431 ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
432
433 /* Tests with a NULL cert context. Prop ID 0 fails.. */
434 ret = CertSetCertificateContextProperty(NULL, 0, 0, NULL);
435 ok(!ret && GetLastError() == E_INVALIDARG,
436 "Expected E_INVALIDARG, got %08x\n", GetLastError());
437 /* while this just crashes.
438 ret = CertSetCertificateContextProperty(NULL,
439 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
440 */
441
442 ret = CertSetCertificateContextProperty(context, 0, 0, NULL);
443 ok(!ret && GetLastError() == E_INVALIDARG,
444 "Expected E_INVALIDARG, got %08x\n", GetLastError());
445 /* Can't set the cert property directly, this crashes.
446 ret = CertSetCertificateContextProperty(context,
447 CERT_CERT_PROP_ID, 0, bigCert2);
448 */
449
450 /* These all crash.
451 ret = CertGetCertificateContextProperty(context,
452 CERT_ACCESS_STATE_PROP_ID, 0, NULL);
453 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
454 NULL, NULL);
455 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
456 hashProperty, NULL);
457 */
458 /* A missing prop */
459 size = 0;
460 ret = CertGetCertificateContextProperty(context,
461 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
462 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
463 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
464 /* And, an implicit property */
465 size = sizeof(access);
466 ret = CertGetCertificateContextProperty(context,
467 CERT_ACCESS_STATE_PROP_ID, &access, &size);
468 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
469 GetLastError());
470 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
471 "Didn't expect a persisted cert\n");
472 /* Trying to set this "read only" property crashes.
473 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
474 ret = CertSetCertificateContextProperty(context,
475 CERT_ACCESS_STATE_PROP_ID, 0, &access);
476 */
477
478 /* Can I set the hash to an invalid hash? */
479 blob.pbData = hash;
480 blob.cbData = sizeof(hash);
481 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
482 &blob);
483 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
484 GetLastError());
485 size = sizeof(hashProperty);
486 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
487 hashProperty, &size);
488 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
489 GetLastError());
490 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
491 /* Delete the (bogus) hash, and get the real one */
492 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
493 NULL);
494 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
495 GetLastError());
496 checkHash(bigCert, sizeof(bigCert), CALG_SHA1, context,
497 CERT_HASH_PROP_ID);
498
499 /* Now that the hash property is set, we should get one property when
500 * enumerating.
501 */
502 propID = 0;
503 numProps = 0;
504 do {
505 propID = CertEnumCertificateContextProperties(context, propID);
506 if (propID)
507 numProps++;
508 } while (propID != 0);
509 ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
510
511 /* Check a few other implicit properties */
512 checkHash(bigCert, sizeof(bigCert), CALG_MD5, context,
513 CERT_MD5_HASH_PROP_ID);
514
515 /* Getting the signature hash fails with this bogus certificate */
516 size = 0;
517 ret = CertGetCertificateContextProperty(context,
518 CERT_SIGNATURE_HASH_PROP_ID, NULL, &size);
519 ok(!ret &&
520 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
521 GetLastError() == CRYPT_E_NOT_FOUND ||
522 GetLastError() == OSS_DATA_ERROR), /* win9x */
523 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
524
525 /* Test key contexts and handles and such */
526 size = 0;
527 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
528 NULL, &size);
529 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
530 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
531 size = sizeof(CERT_KEY_CONTEXT);
532 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
533 NULL, &size);
534 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
535 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
536 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
537 &keyContext, &size);
538 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
539 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
540 /* Key context with an invalid size */
541 keyContext.cbSize = 0;
542 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
543 0, &keyContext);
544 ok(!ret && GetLastError() == E_INVALIDARG,
545 "Expected E_INVALIDARG, got %08x\n", GetLastError());
546 size = sizeof(keyContext);
547 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
548 &keyContext, &size);
549 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
550 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
551 keyContext.cbSize = sizeof(keyContext);
552 keyContext.hCryptProv = 0;
553 keyContext.dwKeySpec = AT_SIGNATURE;
554 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
555 0, &keyContext);
556 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
557 /* Now that that's set, the key prov handle property is also gettable.
558 */
559 size = sizeof(keyContext.hCryptProv);
560 ret = CertGetCertificateContextProperty(context,
561 CERT_KEY_PROV_HANDLE_PROP_ID, &keyContext.hCryptProv, &size);
562 ok(ret, "Expected to get the CERT_KEY_PROV_HANDLE_PROP_ID, got %08x\n",
563 GetLastError());
564 /* Remove the key prov handle property.. */
565 ret = CertSetCertificateContextProperty(context,
566 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
567 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
568 GetLastError());
569 /* and the key context's CSP is set to NULL. */
570 size = sizeof(keyContext);
571 ret = CertGetCertificateContextProperty(context,
572 CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
573 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
574 GetLastError());
575 ok(keyContext.hCryptProv == 0, "Expected no hCryptProv\n");
576
577 /* According to MSDN the subject key id can be stored as a property,
578 * as a subject key extension, or as the SHA1 hash of the public key,
579 * but this cert has none of them:
580 */
581 ret = CertGetCertificateContextProperty(context,
582 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
583 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
584 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
585 CertFreeCertificateContext(context);
586 /* This cert does have a public key, but its subject key identifier still
587 * isn't available: */
588 context = CertCreateCertificateContext(X509_ASN_ENCODING,
589 v1CertWithPubKey, sizeof(v1CertWithPubKey));
590 ret = CertGetCertificateContextProperty(context,
591 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
592 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
593 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
594 CertFreeCertificateContext(context);
595 /* This cert with a subject key extension can have its key identifier
596 * property retrieved:
597 */
598 context = CertCreateCertificateContext(X509_ASN_ENCODING,
599 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId));
600 ret = CertGetCertificateContextProperty(context,
601 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
602 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
603 if (ret)
604 {
605 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
606
607 if (buf)
608 {
609 ret = CertGetCertificateContextProperty(context,
610 CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
611 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
612 GetLastError());
613 ok(!memcmp(buf, subjectKeyId, size), "Unexpected subject key id\n");
614 HeapFree(GetProcessHeap(), 0, buf);
615 }
616 }
617 CertFreeCertificateContext(context);
618
619 context = CertCreateCertificateContext(X509_ASN_ENCODING,
620 selfSignedCert, sizeof(selfSignedCert));
621 /* Getting the signature hash of a valid (self-signed) cert succeeds */
622 size = 0;
623 ret = CertGetCertificateContextProperty(context,
624 CERT_SIGNATURE_HASH_PROP_ID, NULL, &size);
625 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
626 ok(size == sizeof(selfSignedSignatureHash), "unexpected size %d\n", size);
627 ret = CertGetCertificateContextProperty(context,
628 CERT_SIGNATURE_HASH_PROP_ID, hashProperty, &size);
629 if (ret)
630 ok(!memcmp(hashProperty, selfSignedSignatureHash, size),
631 "unexpected value\n");
632 CertFreeCertificateContext(context);
633 }
634
635 static void testCreateCert(void)
636 {
637 PCCERT_CONTEXT cert, enumCert;
638 DWORD count, size;
639 BOOL ret;
640
641 SetLastError(0xdeadbeef);
642 cert = CertCreateCertificateContext(0, NULL, 0);
643 ok(!cert && GetLastError() == E_INVALIDARG,
644 "expected E_INVALIDARG, got %08x\n", GetLastError());
645 SetLastError(0xdeadbeef);
646 cert = CertCreateCertificateContext(0, selfSignedCert,
647 sizeof(selfSignedCert));
648 ok(!cert && GetLastError() == E_INVALIDARG,
649 "expected E_INVALIDARG, got %08x\n", GetLastError());
650 SetLastError(0xdeadbeef);
651 cert = CertCreateCertificateContext(X509_ASN_ENCODING, NULL, 0);
652 ok(!cert &&
653 (GetLastError() == CRYPT_E_ASN1_EOD ||
654 broken(GetLastError() == OSS_MORE_INPUT /* NT4 */)),
655 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
656
657 cert = CertCreateCertificateContext(X509_ASN_ENCODING,
658 selfSignedCert, sizeof(selfSignedCert));
659 ok(cert != NULL, "creating cert failed: %08x\n", GetLastError());
660 /* Even in-memory certs are expected to have a store associated with them */
661 ok(cert->hCertStore != NULL, "expected created cert to have a store\n");
662 /* The cert doesn't have the archived property set (which would imply it
663 * doesn't show up in enumerations.)
664 */
665 size = 0;
666 ret = CertGetCertificateContextProperty(cert, CERT_ARCHIVED_PROP_ID,
667 NULL, &size);
668 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
669 "expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
670 /* Strangely, enumerating the certs in the store finds none. */
671 enumCert = NULL;
672 count = 0;
673 while ((enumCert = CertEnumCertificatesInStore(cert->hCertStore, enumCert)))
674 count++;
675 ok(!count, "expected 0, got %d\n", count);
676 CertFreeCertificateContext(cert);
677 }
678
679 static void testDupCert(void)
680 {
681 PCCERT_CONTEXT context, dupContext, storeContext, storeContext2, context2;
682 HCERTSTORE store, store2;
683 BOOL ret;
684
685 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
686 CERT_STORE_CREATE_NEW_FLAG, NULL);
687 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
688 if (!store)
689 return;
690
691 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
692 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
693 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win98 */),
694 "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
695 if (!ret && GetLastError() == OSS_DATA_ERROR)
696 {
697 skip("bigCert can't be decoded, skipping tests\n");
698 return;
699 }
700 ok(context != NULL, "Expected a valid cert context\n");
701 if (context)
702 {
703 ok(context->cbCertEncoded == sizeof(bigCert),
704 "Wrong cert size %d\n", context->cbCertEncoded);
705 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)),
706 "Unexpected encoded cert in context\n");
707 ok(context->hCertStore == store, "Unexpected store\n");
708
709 dupContext = CertDuplicateCertificateContext(context);
710 ok(dupContext != NULL, "Expected valid duplicate\n");
711 /* Not only is it a duplicate, it's identical: the address is the
712 * same.
713 */
714 ok(dupContext == context, "Expected identical context addresses\n");
715 CertFreeCertificateContext(dupContext);
716 CertFreeCertificateContext(context);
717 }
718 CertCloseStore(store, 0);
719
720 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
721 ok(context != NULL, "CertCreateCertificateContext failed\n");
722
723 dupContext = CertDuplicateCertificateContext(context);
724 ok(dupContext == context, "context != dupContext\n");
725
726 ret = CertFreeCertificateContext(dupContext);
727 ok(ret, "CertFreeCertificateContext failed\n");
728
729 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
730 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
731
732 ret = CertAddCertificateContextToStore(store, context, CERT_STORE_ADD_NEW, &storeContext);
733 ok(ret, "CertAddCertificateContextToStore failed\n");
734 ok(storeContext != NULL && storeContext != context, "unexpected storeContext\n");
735 ok(storeContext->hCertStore == store, "unexpected hCertStore\n");
736
737 ok(storeContext->pbCertEncoded != context->pbCertEncoded, "unexpected pbCertEncoded\n");
738 ok(storeContext->cbCertEncoded == context->cbCertEncoded, "unexpected cbCertEncoded\n");
739 ok(storeContext->pCertInfo != context->pCertInfo, "unexpected pCertInfo\n");
740
741 store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
742 ok(store2 != NULL, "CertOpenStore failed: %d\n", GetLastError());
743
744 ret = CertAddCertificateContextToStore(store2, storeContext, CERT_STORE_ADD_NEW, &storeContext2);
745 ok(ret, "CertAddCertificateContextToStore failed\n");
746 ok(storeContext2 != NULL && storeContext2 != storeContext, "unexpected storeContext\n");
747 ok(storeContext2->hCertStore == store2, "unexpected hCertStore\n");
748
749 ok(storeContext2->pbCertEncoded != storeContext->pbCertEncoded, "unexpected pbCertEncoded\n");
750 ok(storeContext2->cbCertEncoded == storeContext->cbCertEncoded, "unexpected cbCertEncoded\n");
751 ok(storeContext2->pCertInfo != storeContext->pCertInfo, "unexpected pCertInfo\n");
752
753 CertFreeCertificateContext(storeContext2);
754 CertFreeCertificateContext(storeContext);
755
756 context2 = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage, sizeof(certWithUsage));
757 ok(context2 != NULL, "CertCreateCertificateContext failed\n");
758
759 ok(context2->hCertStore == context->hCertStore, "Unexpected hCertStore\n");
760
761 CertFreeCertificateContext(context2);
762 ret = CertFreeCertificateContext(context);
763 ok(ret, "CertFreeCertificateContext failed\n");
764
765 CertCloseStore(store, 0);
766 CertCloseStore(store2, 0);
767
768 SetLastError(0xdeadbeef);
769 context = CertDuplicateCertificateContext(NULL);
770 ok(context == NULL, "Expected context to be NULL\n");
771
772 ret = CertFreeCertificateContext(NULL);
773 ok(ret, "CertFreeCertificateContext failed\n");
774 }
775
776 static void testLinkCert(void)
777 {
778 const CERT_CONTEXT *context, *link;
779 HCERTSTORE store;
780 BOOL ret;
781
782 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
783 ok(context != NULL, "CertCreateCertificateContext failed\n");
784
785 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
786 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
787
788 ret = CertAddCertificateLinkToStore(store, context, CERT_STORE_ADD_NEW, &link);
789 ok(ret, "CertAddCertificateContextToStore failed\n");
790 ok(link != NULL && link != context, "unexpected storeContext\n");
791 ok(link->hCertStore == store, "unexpected hCertStore\n");
792
793 ok(link->pbCertEncoded == context->pbCertEncoded, "unexpected pbCertEncoded\n");
794 ok(link->cbCertEncoded == context->cbCertEncoded, "unexpected cbCertEncoded\n");
795 ok(link->pCertInfo == context->pCertInfo, "unexpected pCertInfo\n");
796
797 CertFreeCertificateContext(link);
798 CertFreeCertificateContext(context);
799 CertCloseStore(store, 0);
800 }
801
802 static BYTE subjectName3[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
803 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x52, 0x6f, 0x62, 0x20, 0x20, 0x4c, 0x61,
804 0x6e, 0x67, 0x00 };
805 static const BYTE iTunesCert0[] = {
806 0x30,0x82,0x03,0xc4,0x30,0x82,0x03,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
807 0x47,0xbf,0x19,0x95,0xdf,0x8d,0x52,0x46,0x43,0xf7,0xdb,0x6d,0x48,0x0d,0x31,
808 0xa4,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
809 0x00,0x30,0x81,0x8b,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
810 0x5a,0x41,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0c,0x57,0x65,
811 0x73,0x74,0x65,0x72,0x6e,0x20,0x43,0x61,0x70,0x65,0x31,0x14,0x30,0x12,0x06,
812 0x03,0x55,0x04,0x07,0x13,0x0b,0x44,0x75,0x72,0x62,0x61,0x6e,0x76,0x69,0x6c,
813 0x6c,0x65,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x0a,0x13,0x06,0x54,0x68,
814 0x61,0x77,0x74,0x65,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14,
815 0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
816 0x61,0x74,0x69,0x6f,0x6e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13,
817 0x16,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
818 0x6d,0x70,0x69,0x6e,0x67,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x33,0x31,
819 0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x33,0x31,
820 0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x53,0x31,0x0b,0x30,
821 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,
822 0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
823 0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,
824 0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,0x6d,0x65,0x20,
825 0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,0x76,0x69,0x63,
826 0x65,0x73,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,
827 0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,
828 0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa9,0xca,0xb2,0xa4,0xcc,0xcd,0x20,
829 0xaf,0x0a,0x7d,0x89,0xac,0x87,0x75,0xf0,0xb4,0x4e,0xf1,0xdf,0xc1,0x0f,0xbf,
830 0x67,0x61,0xbd,0xa3,0x64,0x1c,0xda,0xbb,0xf9,0xca,0x33,0xab,0x84,0x30,0x89,
831 0x58,0x7e,0x8c,0xdb,0x6b,0xdd,0x36,0x9e,0x0f,0xbf,0xd1,0xec,0x78,0xf2,0x77,
832 0xa6,0x7e,0x6f,0x3c,0xbf,0x93,0xaf,0x0d,0xba,0x68,0xf4,0x6c,0x94,0xca,0xbd,
833 0x52,0x2d,0xab,0x48,0x3d,0xf5,0xb6,0xd5,0x5d,0x5f,0x1b,0x02,0x9f,0xfa,0x2f,
834 0x6b,0x1e,0xa4,0xf7,0xa3,0x9a,0xa6,0x1a,0xc8,0x02,0xe1,0x7f,0x4c,0x52,0xe3,
835 0x0e,0x60,0xec,0x40,0x1c,0x7e,0xb9,0x0d,0xde,0x3f,0xc7,0xb4,0xdf,0x87,0xbd,
836 0x5f,0x7a,0x6a,0x31,0x2e,0x03,0x99,0x81,0x13,0xa8,0x47,0x20,0xce,0x31,0x73,
837 0x0d,0x57,0x2d,0xcd,0x78,0x34,0x33,0x95,0x12,0x99,0x12,0xb9,0xde,0x68,0x2f,
838 0xaa,0xe6,0xe3,0xc2,0x8a,0x8c,0x2a,0xc3,0x8b,0x21,0x87,0x66,0xbd,0x83,0x58,
839 0x57,0x6f,0x75,0xbf,0x3c,0xaa,0x26,0x87,0x5d,0xca,0x10,0x15,0x3c,0x9f,0x84,
840 0xea,0x54,0xc1,0x0a,0x6e,0xc4,0xfe,0xc5,0x4a,0xdd,0xb9,0x07,0x11,0x97,0x22,
841 0x7c,0xdb,0x3e,0x27,0xd1,0x1e,0x78,0xec,0x9f,0x31,0xc9,0xf1,0xe6,0x22,0x19,
842 0xdb,0xc4,0xb3,0x47,0x43,0x9a,0x1a,0x5f,0xa0,0x1e,0x90,0xe4,0x5e,0xf5,0xee,
843 0x7c,0xf1,0x7d,0xab,0x62,0x01,0x8f,0xf5,0x4d,0x0b,0xde,0xd0,0x22,0x56,0xa8,
844 0x95,0xcd,0xae,0x88,0x76,0xae,0xee,0xba,0x0d,0xf3,0xe4,0x4d,0xd9,0xa0,0xfb,
845 0x68,0xa0,0xae,0x14,0x3b,0xb3,0x87,0xc1,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,
846 0x81,0xdb,0x30,0x81,0xd8,0x30,0x34,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
847 0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
848 0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,
849 0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,
850 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
851 0xff,0x02,0x01,0x00,0x30,0x41,0x06,0x03,0x55,0x1d,0x1f,0x04,0x3a,0x30,0x38,
852 0x30,0x36,0xa0,0x34,0xa0,0x32,0x86,0x30,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
853 0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,
854 0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
855 0x6d,0x70,0x69,0x6e,0x67,0x43,0x41,0x2e,0x63,0x72,0x6c,0x30,0x13,0x06,0x03,
856 0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
857 0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,
858 0x02,0x01,0x06,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,0x04,0x1d,0x30,0x1b,0xa4,
859 0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0c,0x54,
860 0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,0x33,0x30,0x0d,0x06,0x09,
861 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,
862 0x4a,0x6b,0xf9,0xea,0x58,0xc2,0x44,0x1c,0x31,0x89,0x79,0x99,0x2b,0x96,0xbf,
863 0x82,0xac,0x01,0xd6,0x1c,0x4c,0xcd,0xb0,0x8a,0x58,0x6e,0xdf,0x08,0x29,0xa3,
864 0x5e,0xc8,0xca,0x93,0x13,0xe7,0x04,0x52,0x0d,0xef,0x47,0x27,0x2f,0x00,0x38,
865 0xb0,0xe4,0xc9,0x93,0x4e,0x9a,0xd4,0x22,0x62,0x15,0xf7,0x3f,0x37,0x21,0x4f,
866 0x70,0x31,0x80,0xf1,0x8b,0x38,0x87,0xb3,0xe8,0xe8,0x97,0x00,0xfe,0xcf,0x55,
867 0x96,0x4e,0x24,0xd2,0xa9,0x27,0x4e,0x7a,0xae,0xb7,0x61,0x41,0xf3,0x2a,0xce,
868 0xe7,0xc9,0xd9,0x5e,0xdd,0xbb,0x2b,0x85,0x3e,0xb5,0x9d,0xb5,0xd9,0xe1,0x57,
869 0xff,0xbe,0xb4,0xc5,0x7e,0xf5,0xcf,0x0c,0x9e,0xf0,0x97,0xfe,0x2b,0xd3,0x3b,
870 0x52,0x1b,0x1b,0x38,0x27,0xf7,0x3f,0x4a };
871 static const BYTE iTunesCert1[] = {
872 0x30,0x82,0x03,0xff,0x30,0x82,0x02,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
873 0x0d,0xe9,0x2b,0xf0,0xd4,0xd8,0x29,0x88,0x18,0x32,0x05,0x09,0x5e,0x9a,0x76,
874 0x88,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
875 0x00,0x30,0x53,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
876 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
877 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,
878 0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
879 0x20,0x54,0x69,0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,
880 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,
881 0x30,0x33,0x31,0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
882 0x30,0x38,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x57,
883 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,
884 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,
885 0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2f,0x30,0x2d,0x06,0x03,0x55,
886 0x04,0x03,0x13,0x26,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,
887 0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,
888 0x76,0x69,0x63,0x65,0x73,0x20,0x53,0x69,0x67,0x6e,0x65,0x72,0x30,0x82,0x01,
889 0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
890 0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,
891 0xb2,0x50,0x28,0x48,0xdd,0xd3,0x68,0x7a,0x84,0x18,0x44,0x66,0x75,0x5d,0x7e,
892 0xc4,0xb8,0x9f,0x63,0x26,0xff,0x3d,0x43,0x9c,0x7c,0x11,0x38,0x10,0x25,0x55,
893 0x73,0xd9,0x75,0x27,0x69,0xfd,0x4e,0xb9,0x20,0x5c,0xd3,0x0a,0xf9,0xa0,0x1b,
894 0x2a,0xed,0x55,0x56,0x21,0x61,0xd8,0x1e,0xdb,0xe4,0xbc,0x33,0x6b,0xc7,0xef,
895 0xdd,0xa3,0x37,0x65,0x8e,0x1b,0x93,0x0c,0xb6,0x53,0x1e,0x5c,0x7c,0x66,0x35,
896 0x5f,0x05,0x8a,0x45,0xfe,0x76,0x4e,0xdf,0x53,0x80,0xa2,0x81,0x20,0x9d,0xae,
897 0x88,0x5c,0xa2,0x08,0xf7,0xe5,0x30,0xf9,0xee,0x22,0x37,0x4c,0x42,0x0a,0xce,
898 0xdf,0xc6,0x1f,0xc4,0xd6,0x55,0xe9,0x81,0x3f,0xb5,0x52,0xa3,0x2c,0xaa,0x01,
899 0x7a,0xf2,0xa2,0xaa,0x8d,0x35,0xfe,0x9f,0xe6,0x5d,0x6a,0x05,0x9f,0x3d,0x6b,
900 0xe3,0xbf,0x96,0xc0,0xfe,0xcc,0x60,0xf9,0x40,0xe7,0x07,0xa0,0x44,0xeb,0x81,
901 0x51,0x6e,0xa5,0x2a,0xf2,0xb6,0x8a,0x10,0x28,0xed,0x8f,0xdc,0x06,0xa0,0x86,
902 0x50,0x9a,0x7b,0x4a,0x08,0x0d,0x30,0x1d,0xca,0x10,0x9e,0x6b,0xf7,0xe9,0x58,
903 0xae,0x04,0xa9,0x40,0x99,0xb2,0x28,0xe8,0x8f,0x16,0xac,0x3c,0xe3,0x53,0x6f,
904 0x4b,0xd3,0x35,0x9d,0xb5,0x6f,0x64,0x1d,0xb3,0x96,0x2c,0xbb,0x3d,0xe7,0x79,
905 0xeb,0x6d,0x7a,0xf9,0x16,0xe6,0x26,0xad,0xaf,0xef,0x99,0x53,0xb7,0x40,0x2c,
906 0x95,0xb8,0x79,0xaa,0xfe,0xd4,0x52,0xab,0x29,0x74,0x7e,0x42,0xec,0x39,0x1e,
907 0xa2,0x6a,0x16,0xe6,0x59,0xbb,0x24,0x68,0xd8,0x00,0x80,0x43,0x10,0x87,0x80,
908 0x6b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xca,0x30,0x81,0xc7,0x30,0x34,0x06,
909 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,
910 0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,
911 0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
912 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
913 0xff,0x04,0x02,0x30,0x00,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30,
914 0x2a,0x30,0x28,0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,
915 0x2f,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,
916 0x6f,0x6d,0x2f,0x74,0x73,0x73,0x2d,0x63,0x61,0x2e,0x63,0x72,0x6c,0x30,0x16,
917 0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,
918 0x06,0x01,0x05,0x05,0x07,0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
919 0x01,0xff,0x04,0x04,0x03,0x02,0x06,0xc0,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,
920 0x04,0x1d,0x30,0x1b,0xa4,0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,
921 0x04,0x03,0x13,0x0c,0x54,0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,
922 0x34,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
923 0x00,0x03,0x82,0x01,0x01,0x00,0x87,0x78,0x70,0xda,0x4e,0x52,0x01,0x20,0x5b,
924 0xe0,0x79,0xc9,0x82,0x30,0xc4,0xfd,0xb9,0x19,0x96,0xbd,0x91,0x00,0xc3,0xbd,
925 0xcd,0xcd,0xc6,0xf4,0x0e,0xd8,0xff,0xf9,0x4d,0xc0,0x33,0x62,0x30,0x11,0xc5,
926 0xf5,0x74,0x1b,0xd4,0x92,0xde,0x5f,0x9c,0x20,0x13,0xb1,0x7c,0x45,0xbe,0x50,
927 0xcd,0x83,0xe7,0x80,0x17,0x83,0xa7,0x27,0x93,0x67,0x13,0x46,0xfb,0xca,0xb8,
928 0x98,0x41,0x03,0xcc,0x9b,0x51,0x5b,0x05,0x8b,0x7f,0xa8,0x6f,0xf3,0x1b,0x50,
929 0x1b,0x24,0x2e,0xf2,0x69,0x8d,0x6c,0x22,0xf7,0xbb,0xca,0x16,0x95,0xed,0x0c,
930 0x74,0xc0,0x68,0x77,0xd9,0xeb,0x99,0x62,0x87,0xc1,0x73,0x90,0xf8,0x89,0x74,
931 0x7a,0x23,0xab,0xa3,0x98,0x7b,0x97,0xb1,0xf7,0x8f,0x29,0x71,0x4d,0x2e,0x75,
932 0x1b,0x48,0x41,0xda,0xf0,0xb5,0x0d,0x20,0x54,0xd6,0x77,0xa0,0x97,0x82,0x63,
933 0x69,0xfd,0x09,0xcf,0x8a,0xf0,0x75,0xbb,0x09,0x9b,0xd9,0xf9,0x11,0x55,0x26,
934 0x9a,0x61,0x32,0xbe,0x7a,0x02,0xb0,0x7b,0x86,0xbe,0xa2,0xc3,0x8b,0x22,0x2c,
935 0x78,0xd1,0x35,0x76,0xbc,0x92,0x73,0x5c,0xf9,0xb9,0xe6,0x4c,0x15,0x0a,0x23,
936 0xcc,0xe4,0xd2,0xd4,0x34,0x2e,0x49,0x40,0x15,0x3c,0x0f,0x60,0x7a,0x24,0xc6,
937 0xa5,0x66,0xef,0x96,0xcf,0x70,0xeb,0x3e,0xe7,0xf4,0x0d,0x7e,0xdc,0xd1,0x7c,
938 0xa3,0x76,0x71,0x69,0xc1,0x9c,0x4f,0x47,0x30,0x35,0x21,0xb1,0xa2,0xaf,0x1a,
939 0x62,0x3c,0x2b,0xd9,0x8e,0xaa,0x2a,0x07,0x7b,0xd8,0x18,0xb3,0x5c,0x7b,0xe2,
940 0x9d,0xa5,0x6f,0xfe,0x3c,0x89,0xad };
941 static const BYTE iTunesCert2[] = {
942 0x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
943 0x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75,
944 0xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
945 0x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
946 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
947 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,
948 0x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,
949 0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,
950 0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,
951 0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x34,0x30,
952 0x37,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30,
953 0x37,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,
954 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,
955 0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
956 0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b,
957 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,
958 0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,
959 0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,
960 0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,
961 0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,
962 0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,
963 0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,
964 0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,0x53,0x69,
965 0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,0x20,0x43,0x41,0x30,0x82,
966 0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,
967 0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,
968 0x00,0xbe,0xbc,0xee,0xbc,0x7e,0xef,0x83,0xeb,0xe0,0x37,0x4f,0xfb,0x03,0x10,
969 0x38,0xbe,0x08,0xd2,0x8c,0x7d,0x9d,0xfa,0x92,0x7f,0x19,0x0c,0xc2,0x6b,0xee,
970 0x42,0x52,0x8c,0xde,0xd3,0x1c,0x48,0x13,0x25,0xea,0xc1,0x63,0x7a,0xf9,0x51,
971 0x65,0xee,0xd3,0xaa,0x3b,0xf5,0xf0,0x94,0x9c,0x2b,0xfb,0xf2,0x66,0xd4,0x24,
972 0xda,0xf7,0xf5,0x9f,0x6e,0x19,0x39,0x36,0xbc,0xd0,0xa3,0x76,0x08,0x1e,0x22,
973 0x27,0x24,0x6c,0x38,0x91,0x27,0xe2,0x84,0x49,0xae,0x1b,0x8a,0xa1,0xfd,0x25,
974 0x82,0x2c,0x10,0x30,0xe8,0x71,0xab,0x28,0xe8,0x77,0x4a,0x51,0xf1,0xec,0xcd,
975 0xf8,0xf0,0x54,0xd4,0x6f,0xc0,0xe3,0x6d,0x0a,0x8f,0xd9,0xd8,0x64,0x8d,0x63,
976 0xb2,0x2d,0x4e,0x27,0xf6,0x85,0x0e,0xfe,0x6d,0xe3,0x29,0x99,0xe2,0x85,0x47,
977 0x7c,0x2d,0x86,0x7f,0xe8,0x57,0x8f,0xad,0x67,0xc2,0x33,0x32,0x91,0x13,0x20,
978 0xfc,0xa9,0x23,0x14,0x9a,0x6d,0xc2,0x84,0x4b,0x76,0x68,0x04,0xd5,0x71,0x2c,
979 0x5d,0x21,0xfa,0x88,0x0d,0x26,0xfd,0x1f,0x2d,0x91,0x2b,0xe7,0x01,0x55,0x4d,
980 0xf2,0x6d,0x35,0x28,0x82,0xdf,0xd9,0x6b,0x5c,0xb6,0xd6,0xd9,0xaa,0x81,0xfd,
981 0x5f,0xcd,0x83,0xba,0x63,0x9d,0xd0,0x22,0xfc,0xa9,0x3b,0x42,0x69,0xb2,0x8e,
982 0x3a,0xb5,0xbc,0xb4,0x9e,0x0f,0x5e,0xc4,0xea,0x2c,0x82,0x8b,0x28,0xfd,0x53,
983 0x08,0x96,0xdd,0xb5,0x01,0x20,0xd1,0xf9,0xa5,0x18,0xe7,0xc0,0xee,0x51,0x70,
984 0x37,0xe1,0xb6,0x05,0x48,0x52,0x48,0x6f,0x38,0xea,0xc3,0xe8,0x6c,0x7b,0x44,
985 0x84,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xa0,0x30,0x82,0x01,0x9c,
986 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
987 0x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,
988 0x3b,0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,
989 0x03,0x30,0x2a,0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
990 0x16,0x1c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,
991 0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,
992 0x30,0x31,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24,
993 0xa0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,
994 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63,
995 0x61,0x33,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16,
996 0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2b,
997 0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
998 0x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48,
999 0x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x01,0x30,0x29,0x06,
1000 0x03,0x55,0x1d,0x11,0x04,0x22,0x30,0x20,0xa4,0x1e,0x30,0x1c,0x31,0x1a,0x30,
1001 0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6c,0x61,0x73,0x73,0x33,0x43,
1002 0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x34,0x33,0x30,0x1d,0x06,0x03,0x55,
1003 0x1d,0x0e,0x04,0x16,0x04,0x14,0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,
1004 0x36,0x7c,0x68,0xcf,0x5b,0x78,0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x81,0x80,0x06,
1005 0x03,0x55,0x1d,0x23,0x04,0x79,0x30,0x77,0xa1,0x63,0xa4,0x61,0x30,0x5f,0x31,
1006 0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,
1007 0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
1008 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,
1009 0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6c,
1010 0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,
1011 0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,
1012 0x72,0x69,0x74,0x79,0x82,0x10,0x70,0xba,0xe4,0x1d,0x10,0xd9,0x29,0x34,0xb6,
1013 0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
1014 0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xae,0x3a,0x17,0xb8,
1015 0x4a,0x7b,0x55,0xfa,0x64,0x55,0xec,0x40,0xa4,0xed,0x49,0x41,0x90,0x99,0x9c,
1016 0x89,0xbc,0xaf,0x2e,0x1d,0xca,0x78,0x23,0xf9,0x1c,0x19,0x0f,0x7f,0xeb,0x68,
1017 0xbc,0x32,0xd9,0x88,0x38,0xde,0xdc,0x3f,0xd3,0x89,0xb4,0x3f,0xb1,0x82,0x96,
1018 0xf1,0xa4,0x5a,0xba,0xed,0x2e,0x26,0xd3,0xde,0x7c,0x01,0x6e,0x00,0x0a,0x00,
1019 0xa4,0x06,0x92,0x11,0x48,0x09,0x40,0xf9,0x1c,0x18,0x79,0x67,0x23,0x24,0xe0,
1020 0xbb,0xd5,0xe1,0x50,0xae,0x1b,0xf5,0x0e,0xdd,0xe0,0x2e,0x81,0xcd,0x80,0xa3,
1021 0x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88,
1022 0x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f,
1023 0x5e,0xf6,0x7a,0xb5 };
1024 static const BYTE iTunesCert3[] = {
1025 0x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1026 0x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6,
1027 0x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
1028 0x00,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
1029 0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,
1030 0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,
1031 0x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
1032 0x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,
1033 0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,
1034 0x73,0x20,0x6f,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,
1035 0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
1036 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,
1037 0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,
1038 0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,
1039 0x6f,0x64,0x65,0x20,0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,
1040 0x34,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x31,0x37,0x30,
1041 0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x38,0x30,0x31,0x32,0x32,0x32,
1042 0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,
1043 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
1044 0x08,0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x12,
1045 0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,
1046 0x69,0x6e,0x6f,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0a,0x14,0x14,0x41,
1047 0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x2c,0x20,
1048 0x49,0x6e,0x63,0x2e,0x31,0x3e,0x30,0x3c,0x06,0x03,0x55,0x04,0x0b,0x13,0x35,
1049 0x44,0x69,0x67,0x69,0x74,0x61,0x6c,0x20,0x49,0x44,0x20,0x43,0x6c,0x61,0x73,
1050 0x73,0x20,0x33,0x20,0x2d,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
1051 0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x56,0x61,0x6c,0x69,0x64,
1052 0x61,0x74,0x69,0x6f,0x6e,0x20,0x76,0x32,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,
1053 0x04,0x03,0x14,0x14,0x41,0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,
1054 0x74,0x65,0x72,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x30,0x81,0x9f,0x30,0x0d,0x06,
1055 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,
1056 0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xd3,0xab,0x3b,0x7f,0xec,0x48,0x84,
1057 0xce,0xa8,0x1a,0x12,0xf3,0x3c,0x87,0xcb,0x24,0x58,0x96,0x02,0x87,0x66,0x49,
1058 0xeb,0x89,0xee,0x79,0x44,0x70,0x8d,0xe7,0xd4,0x1f,0x30,0x92,0xc0,0x9c,0x35,
1059 0x78,0xc0,0xaf,0x1c,0xb6,0x28,0xd3,0xe0,0xe0,0x9d,0xd3,0x49,0x76,0x73,0x57,
1060 0x19,0x4d,0x8d,0x70,0x85,0x64,0x4d,0x1d,0xc6,0x02,0x3e,0xe5,0x2c,0x66,0x07,
1061 0xd2,0x27,0x4b,0xd6,0xc8,0x3c,0x93,0xb6,0x15,0x0c,0xde,0x5b,0xd7,0x93,0xdd,
1062 0xbe,0x85,0x62,0x34,0x17,0x8a,0x05,0x60,0xf0,0x8a,0x1c,0x5a,0x40,0x21,0x8d,
1063 0x51,0x6c,0xb0,0x62,0xd8,0xb5,0xd4,0xf9,0xb1,0xd0,0x58,0x7a,0x7a,0x82,0x55,
1064 0xb3,0xf9,0x53,0x71,0xde,0xd2,0xc9,0x37,0x8c,0xf6,0x5a,0x1f,0x2d,0xcd,0x7c,
1065 0x67,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30,
1066 0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06,0x03,0x55,
1067 0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x40,0x06,0x03,
1068 0x55,0x1d,0x1f,0x04,0x39,0x30,0x37,0x30,0x35,0xa0,0x33,0xa0,0x31,0x86,0x2f,
1069 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,
1070 0x34,0x2d,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,
1071 0x63,0x6f,0x6d,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2e,0x63,
1072 0x72,0x6c,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b,0x30,0x39,
1073 0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,0x03,0x30,0x2a,
1074 0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1c,0x68,
1075 0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,
1076 0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x30,0x13,0x06,
1077 0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
1078 0x07,0x03,0x03,0x30,0x75,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
1079 0x04,0x69,0x30,0x67,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,
1080 0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,
1081 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x3f,0x06,
1082 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x33,0x68,0x74,0x74,0x70,
1083 0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,
1084 0x61,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,
1085 0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,0x61,0x2e,0x63,
1086 0x65,0x72,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
1087 0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,0x36,0x7c,0x68,0xcf,0x5b,0x78,
1088 0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,
1089 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x04,0x10,0x30,0x16,0x06,0x0a,0x2b,0x06,
1090 0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x1b,0x04,0x08,0x30,0x06,0x01,0x01,0x00,
1091 0x01,0x01,0xff,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1092 0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6a,0xa6,0x06,0xd0,0x33,0x18,0x64,
1093 0xe2,0x69,0x82,0xee,0x6e,0x36,0x9e,0x9d,0x9a,0x0e,0x18,0xa8,0xac,0x9d,0x10,
1094 0xed,0x01,0x3c,0xb9,0x61,0x04,0x62,0xf3,0x85,0x8f,0xcc,0x4f,0x2c,0x66,0x35,
1095 0x54,0x25,0x45,0x8d,0x95,0x1c,0xd2,0x33,0xbe,0x2e,0xdd,0x7f,0x74,0xaf,0x03,
1096 0x7b,0x86,0x63,0xb0,0xc9,0xe6,0xbd,0xc7,0x8e,0xde,0x03,0x18,0x98,0x82,0xc3,
1097 0xbb,0xf8,0x15,0x99,0x1a,0xa9,0xdd,0xb9,0x5d,0xb9,0xbd,0x53,0x95,0x25,0x76,
1098 0xfb,0x5c,0x53,0x90,0xea,0x01,0x0a,0xa0,0xb1,0xbf,0x09,0x1b,0x97,0x8f,0x40,
1099 0xfa,0x85,0x12,0x74,0x01,0xdb,0xf6,0xdb,0x09,0xd6,0x5f,0x4f,0xd7,0x17,0xb4,
1100 0xbf,0x9e,0x2f,0x86,0x52,0x5d,0x70,0x24,0x52,0x32,0x1e,0xa5,0x1d,0x39,0x8b,
1101 0x66,0xf6,0xba,0x9b,0x69,0x8e,0x12,0x60,0xdb,0xb6,0xcf,0xe6,0x0d,0xd6,0x1c,
1102 0x8f,0xd4,0x5b,0x4b,0x00,0xde,0x21,0x93,0xfb,0x6e,0xc7,0x3d,0xb4,0x66,0x0d,
1103 0x29,0x0c,0x4e,0xe9,0x3f,0x94,0xd6,0xd6,0xdc,0xec,0xf8,0x53,0x3b,0x62,0xd5,
1104 0x97,0x50,0x53,0x84,0x17,0xfe,0xe2,0xed,0x4c,0x23,0x0a,0x49,0xce,0x5b,0xe9,
1105 0x70,0x31,0xc1,0x04,0x02,0x02,0x6c,0xb8,0x52,0xcd,0xc7,0x4e,0x70,0xb4,0x13,
1106 0xd7,0xe0,0x92,0xba,0x44,0x1a,0x10,0x4c,0x6e,0x45,0xc6,0x86,0x04,0xc6,0x64,
1107 0xd3,0x9c,0x6e,0xc1,0x9c,0xac,0x74,0x3d,0x77,0x06,0x5e,0x28,0x28,0x5c,0xf5,
1108 0xe0,0x9c,0x19,0xd8,0xba,0x74,0x81,0x2d,0x67,0x77,0x93,0x8d,0xbf,0xd2,0x52,
1109 0x00,0xe6,0xa5,0x38,0x4e,0x2e,0x73,0x66,0x7a };
1110 static BYTE iTunesIssuer[] = {
1111 0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
1112 0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,
1113 0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
1114 0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,
1115 0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
1116 0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,
1117 0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,
1118 0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,0x73,
1119 0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,
1120 0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,
1121 0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,
1122 0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,
1123 0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
1124 0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,
1125 0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,
1126 0x20,0x43,0x41 };
1127 static BYTE iTunesSerialNum[] = {
1128 0x8d,0xf6,0x6a,0xdf,0xd2,0x40,0xfe,0xb6,0xa6,0x61,0x9b,0x9b,
1129 0xe0,0xa0,0x1a,0x0f };
1130
1131 static void testFindCert(void)
1132 {
1133 HCERTSTORE store;
1134 PCCERT_CONTEXT context = NULL, subject;
1135 BOOL ret;
1136 CERT_INFO certInfo = { 0 };
1137 CRYPT_HASH_BLOB blob;
1138 BYTE otherSerialNumber[] = { 2 };
1139 DWORD count;
1140 static const WCHAR juan[] = { 'j','u','a','n',0 };
1141 static const WCHAR lang[] = { 'L','A','N','G',0 };
1142 static const WCHAR malcolm[] = { 'm','a','l','c','o','l','m',0 };
1143
1144 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1145 CERT_STORE_CREATE_NEW_FLAG, NULL);
1146 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1147 if (!store)
1148 return;
1149
1150 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1151 bigCert, sizeof(bigCert), CERT_STORE_ADD_NEW, NULL);
1152 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win98 */),
1153 "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1154 if (!ret && GetLastError() == OSS_DATA_ERROR)
1155 {
1156 skip("bigCert can't be decoded, skipping tests\n");
1157 return;
1158 }
1159 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1160 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
1161 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1162 GetLastError());
1163 /* This has the same name as bigCert */
1164 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1165 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1166 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1167 GetLastError());
1168
1169 /* Crashes
1170 context = CertFindCertificateInStore(NULL, 0, 0, 0, NULL, NULL);
1171 */
1172
1173 /* Check first cert's there, by issuer */
1174 certInfo.Subject.pbData = subjectName;
1175 certInfo.Subject.cbData = sizeof(subjectName);
1176 certInfo.SerialNumber.pbData = serialNum;
1177 certInfo.SerialNumber.cbData = sizeof(serialNum);
1178 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1179 CERT_FIND_ISSUER_NAME, &certInfo.Subject, NULL);
1180 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1181 GetLastError());
1182 if (context)
1183 {
1184 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1185 CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
1186 ok(context != NULL, "Expected more than one cert\n");
1187 if (context)
1188 {
1189 context = CertFindCertificateInStore(store, X509_ASN_ENCODING,
1190 0, CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
1191 ok(context == NULL, "Expected precisely two certs\n");
1192 }
1193 }
1194
1195 /* Check second cert's there as well, by subject name */
1196 certInfo.Subject.pbData = subjectName2;
1197 certInfo.Subject.cbData = sizeof(subjectName2);
1198 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1199 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, NULL);
1200 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1201 GetLastError());
1202 if (context)
1203 {
1204 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1205 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, context);
1206 ok(context == NULL, "Expected one cert only\n");
1207 }
1208
1209 /* Strange but true: searching for the subject cert requires you to set
1210 * the issuer, not the subject
1211 */
1212 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1213 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1214 ok(context == NULL, "Expected no certificate\n");
1215 certInfo.Subject.pbData = NULL;
1216 certInfo.Subject.cbData = 0;
1217 certInfo.Issuer.pbData = subjectName2;
1218 certInfo.Issuer.cbData = sizeof(subjectName2);
1219 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1220 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1221 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1222 GetLastError());
1223 if (context)
1224 {
1225 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1226 CERT_FIND_SUBJECT_CERT, &certInfo, context);
1227 ok(context == NULL, "Expected one cert only\n");
1228 }
1229 /* A non-matching serial number will not match. */
1230 certInfo.SerialNumber.pbData = otherSerialNumber;
1231 certInfo.SerialNumber.cbData = sizeof(otherSerialNumber);
1232 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1233 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1234 ok(context == NULL, "Expected no match\n");
1235 /* No serial number will not match */
1236 certInfo.SerialNumber.cbData = 0;
1237 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1238 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1239 ok(context == NULL, "Expected no match\n");
1240 /* A serial number still won't match if the name doesn't */
1241 certInfo.SerialNumber.pbData = serialNum;
1242 certInfo.SerialNumber.cbData = sizeof(serialNum);
1243 certInfo.Issuer.pbData = subjectName3;
1244 certInfo.Issuer.cbData = sizeof(subjectName3);
1245 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1246 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1247 ok(context == NULL, "Expected no match\n");
1248
1249 /* The nice thing about hashes, they're unique */
1250 blob.pbData = bigCertHash;
1251 blob.cbData = sizeof(bigCertHash);
1252 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1253 CERT_FIND_SHA1_HASH, &blob, NULL);
1254 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1255 GetLastError());
1256 if (context)
1257 {
1258 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1259 CERT_FIND_SHA1_HASH, &certInfo.Subject, context);
1260 ok(context == NULL, "Expected one cert only\n");
1261 }
1262
1263 /* Searching for NULL string matches any context. */
1264 count = 0;
1265 context = NULL;
1266 do {
1267 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1268 CERT_FIND_ISSUER_STR, NULL, context);
1269 if (context)
1270 count++;
1271 } while (context);
1272 ok(count == 3, "expected 3 contexts\n");
1273 count = 0;
1274 context = NULL;
1275 do {
1276 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1277 CERT_FIND_ISSUER_STR, juan, context);
1278 if (context)
1279 count++;
1280 } while (context);
1281 ok(count == 2, "expected 2 contexts\n");
1282 count = 0;
1283 context = NULL;
1284 do {
1285 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1286 CERT_FIND_ISSUER_STR, lang, context);
1287 if (context)
1288 count++;
1289 } while (context);
1290 ok(count == 3, "expected 3 contexts\n");
1291 SetLastError(0xdeadbeef);
1292 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1293 CERT_FIND_ISSUER_STR, malcolm, NULL);
1294 ok(!context, "expected no certs\n");
1295 ok(GetLastError() == CRYPT_E_NOT_FOUND,
1296 "expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1297
1298 CertCloseStore(store, 0);
1299
1300 /* Another subject cert search, using iTunes's certs */
1301 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1302 CERT_STORE_CREATE_NEW_FLAG, NULL);
1303 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1304 iTunesCert0, sizeof(iTunesCert0), CERT_STORE_ADD_NEW, NULL);
1305 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1306 GetLastError());
1307 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1308 iTunesCert1, sizeof(iTunesCert1), CERT_STORE_ADD_NEW, NULL);
1309 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1310 GetLastError());
1311 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1312 iTunesCert2, sizeof(iTunesCert2), CERT_STORE_ADD_NEW, NULL);
1313 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1314 GetLastError());
1315 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1316 iTunesCert3, sizeof(iTunesCert3), CERT_STORE_ADD_NEW, &subject);
1317 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1318 GetLastError());
1319
1320 /* The certInfo's issuer does not match any subject, but the serial
1321 * number does match a cert whose issuer matches certInfo's issuer.
1322 * This yields a match.
1323 */
1324 certInfo.SerialNumber.cbData = sizeof(iTunesSerialNum);
1325 certInfo.SerialNumber.pbData = iTunesSerialNum;
1326 certInfo.Issuer.cbData = sizeof(iTunesIssuer);
1327 certInfo.Issuer.pbData = iTunesIssuer;
1328 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1329 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1330 ok(context != NULL, "Expected a match\n");
1331 if (context)
1332 {
1333 ret = CertCompareCertificateName(context->dwCertEncodingType,
1334 &certInfo.Issuer, &context->pCertInfo->Subject);
1335 ok(!ret, "Expected subject name not to match\n");
1336 ret = CertCompareCertificateName(context->dwCertEncodingType,
1337 &certInfo.Issuer, &context->pCertInfo->Issuer);
1338 ok(ret, "Expected issuer name to match\n");
1339 ret = CertCompareIntegerBlob(&certInfo.SerialNumber,
1340 &context->pCertInfo->SerialNumber);
1341 ok(ret, "Expected serial number to match\n");
1342 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1343 CERT_FIND_SUBJECT_CERT, &certInfo, context);
1344 ok(context == NULL, "Expected one cert only\n");
1345 }
1346
1347 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1348 CERT_FIND_ISSUER_OF, subject, NULL);
1349 ok(context != NULL, "Expected an issuer\n");
1350 if (context)
1351 {
1352 PCCERT_CONTEXT none = CertFindCertificateInStore(store,
1353 X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_OF, context, NULL);
1354
1355 ok(!none, "Expected no parent of issuer\n");
1356 CertFreeCertificateContext(context);
1357 }
1358 CertFreeCertificateContext(subject);
1359 CertCloseStore(store, 0);
1360 }
1361
1362 static void testGetSubjectCert(void)
1363 {
1364 HCERTSTORE store;
1365 PCCERT_CONTEXT context1, context2;
1366 CERT_INFO info = { 0 };
1367 BOOL ret;
1368
1369 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1370 CERT_STORE_CREATE_NEW_FLAG, NULL);
1371 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1372 if (!store)
1373 return;
1374
1375 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1376 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1377 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win98 */),
1378 "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1379 if (!ret && GetLastError() == OSS_DATA_ERROR)
1380 {
1381 skip("bigCert can't be decoded, skipping tests\n");
1382 return;
1383 }
1384 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1385 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, &context1);
1386 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1387 GetLastError());
1388 ok(context1 != NULL, "Expected a context\n");
1389 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1390 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1391 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1392 GetLastError());
1393
1394 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1395 NULL);
1396 ok(!context2 && GetLastError() == E_INVALIDARG,
1397 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1398 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1399 &info);
1400 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1401 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1402 info.SerialNumber.cbData = sizeof(serialNum);
1403 info.SerialNumber.pbData = serialNum;
1404 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1405 &info);
1406 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1407 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1408 info.Issuer.cbData = sizeof(subjectName2);
1409 info.Issuer.pbData = subjectName2;
1410 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1411 &info);
1412 ok(context2 != NULL,
1413 "CertGetSubjectCertificateFromStore failed: %08x\n", GetLastError());
1414 /* Not only should this find a context, but it should be the same
1415 * (same address) as context1.
1416 */
1417 ok(context1 == context2, "Expected identical context addresses\n");
1418 CertFreeCertificateContext(context2);
1419
1420 CertFreeCertificateContext(context1);
1421 CertCloseStore(store, 0);
1422 }
1423
1424 /* This expires in 1970 or so */
1425 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
1426 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
1427 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
1428 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1429 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1430 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1431 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
1432 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
1433 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1434 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1435 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1436 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
1437 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
1438 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
1439 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
1440 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
1441 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
1442 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
1443 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
1444 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
1445 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
1446 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
1447 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
1448 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
1449 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
1450
1451 /* This expires in 2036 or so */
1452 static const BYTE childOfExpired[] = { 0x30, 0x81, 0xcc, 0x30, 0x78, 0xa0,
1453 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
1454 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d,
1455 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63,
1456 0x40, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e,
1457 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x35, 0x30, 0x35,
1458 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x35,
1459 0x30, 0x35, 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x30, 0x15, 0x31, 0x13,
1460 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e,
1461 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03,
1462 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
1463 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x20, 0x3b, 0xdb, 0x4d, 0x67, 0x50,
1464 0xec, 0x73, 0x9d, 0xf9, 0x85, 0x5d, 0x18, 0xe9, 0xb4, 0x98, 0xe3, 0x31, 0xb7,
1465 0x03, 0x0b, 0xc0, 0x39, 0x93, 0x56, 0x81, 0x0a, 0xfc, 0x78, 0xa8, 0x29, 0x42,
1466 0x5f, 0x69, 0xfb, 0xbc, 0x5b, 0xf2, 0xa6, 0x2a, 0xbe, 0x91, 0x2c, 0xfc, 0x89,
1467 0x69, 0x15, 0x18, 0x58, 0xe5, 0x02, 0x75, 0xf7, 0x2a, 0xb6, 0xa9, 0xfb, 0x47,
1468 0x6a, 0x6e, 0x0a, 0x9b, 0xe9, 0xdc };
1469 /* chain10_0 -+
1470 * +-> chain7_1
1471 * chain10_1 -+
1472 * A chain with two issuers, only one of whose dates is valid.
1473 */
1474 static const BYTE chain10_0[] = {
1475 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1476 0x4a,0x30,0x3a,0x42,0xa2,0x5a,0xb3,0x93,0x4d,0x94,0x06,0xad,0x6d,0x1c,0x34,
1477 0xe6,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1478 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1479 0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1480 0x30,0x5a,0x17,0x0d,0x30,0x36,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1481 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1482 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1483 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1484 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1485 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1486 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1487 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1488 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1489 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1490 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1491 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1492 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1493 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1494 0x81,0x00,0x85,0x6e,0x35,0x2f,0x2c,0x51,0x4f,0xd6,0x2a,0xe4,0x9e,0xd0,0x4b,
1495 0xe6,0x90,0xfd,0xf7,0x20,0xad,0x76,0x3f,0x93,0xea,0x7f,0x0d,0x1f,0xb3,0x8e,
1496 0xfd,0xe0,0xe1,0xd6,0xd7,0x9c,0x7d,0x46,0x6b,0x15,0x5c,0xe6,0xc9,0x62,0x3b,
1497 0x70,0x4a,0x4b,0xb2,0x82,0xe3,0x55,0x0c,0xc4,0x90,0x44,0x06,0x6c,0x86,0x1c,
1498 0x6d,0x47,0x12,0xda,0x33,0x95,0x5d,0x98,0x43,0xcb,0x7c,0xfa,0x2b,0xee,0xc4,
1499 0x2d,0xc8,0x95,0x33,0x89,0x08,0x3f,0x9f,0x87,0xea,0x20,0x04,0xaf,0x58,0x4b,
1500 0x9d,0xc0,0x7c,0x0a,0x1b,0x05,0x31,0x3b,0xbb,0x13,0x58,0x2e,0x3f,0x61,0x6b,
1501 0x10,0xb4,0xeb,0xb9,0x1a,0x30,0xfd,0xea,0xca,0x29,0x99,0x5f,0x42,0x2b,0x00,
1502 0xb0,0x08,0xc3,0xf0,0xb6,0xd6,0x6b,0xf9,0x35,0x95 };
1503 static const BYTE chain10_1[] = {
1504 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1505 0xbf,0x99,0x4f,0x14,0x03,0x77,0x44,0xb8,0x49,0x02,0x70,0xa1,0xb8,0x9c,0xa7,
1506 0x24,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1507 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1508 0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1509 0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1510 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1511 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1512 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1513 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1514 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1515 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1516 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1517 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1518 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1519 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1520 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1521 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1522 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1523 0x81,0x00,0xa8,0xec,0x8c,0x34,0xe7,0x2c,0xdf,0x75,0x87,0xc4,0xf7,0xda,0x71,
1524 0x72,0x29,0xb2,0x48,0xa8,0x2a,0xec,0x7b,0x7d,0x19,0xb9,0x5f,0x1d,0xd9,0x91,
1525 0x2b,0xc4,0x28,0x7e,0xd6,0xb5,0x91,0x69,0xa5,0x8a,0x1a,0x1f,0x97,0x98,0x46,
1526 0x9d,0xdf,0x12,0xf6,0x45,0x62,0xad,0x60,0xb6,0xba,0xb0,0xfd,0xf5,0x9f,0xc6,
1527 0x98,0x05,0x4f,0x4d,0x48,0xdc,0xee,0x69,0xbe,0xb8,0xc4,0xc4,0xd7,0x1b,0xb1,
1528 0x1f,0x64,0xd6,0x45,0xa7,0xdb,0xb3,0x87,0x63,0x0f,0x54,0xe1,0x3a,0x6b,0x57,
1529 0x36,0xd7,0x68,0x65,0xcf,0xda,0x57,0x8d,0xcd,0x84,0x75,0x47,0x26,0x2c,0xef,
1530 0x1e,0x8f,0xc7,0x3b,0xee,0x5d,0x03,0xa6,0xdf,0x3a,0x20,0xb2,0xcc,0xc9,0x09,
1531 0x2c,0xfe,0x2b,0x79,0xb0,0xca,0x2c,0x9a,0x81,0x6b };
1532 static const BYTE chain7_1[] = {
1533 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
1534 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,
1535 0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,
1536 0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,
1537 0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,
1538 0x35,0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,
1539 0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,
1540 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,
1541 0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,
1542 0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,
1543 0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,
1544 0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,
1545 0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,
1546 0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,
1547 0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,
1548 0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,
1549 0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,
1550 0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1551 0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9f,0x69,0xfd,0x26,0xd5,0x4b,
1552 0xe0,0xab,0x12,0x21,0xb9,0xfc,0xf7,0xe0,0x0c,0x09,0x94,0xad,0x27,0xd7,0x9d,
1553 0xa3,0xcc,0x46,0x2a,0x25,0x9a,0x24,0xa7,0x31,0x58,0x78,0xf5,0xfc,0x30,0xe1,
1554 0x6d,0xfd,0x59,0xab,0xbe,0x69,0xa0,0xea,0xe3,0x7d,0x7a,0x7b,0xe5,0x85,0xeb,
1555 0x86,0x6a,0x84,0x3c,0x96,0x01,0x1a,0x70,0xa7,0xb8,0xcb,0xf2,0x11,0xe7,0x52,
1556 0x9c,0x58,0x2d,0xac,0x63,0xce,0x72,0x4b,0xad,0x62,0xa8,0x1d,0x75,0x96,0xe2,
1557 0x27,0xf5,0x6f,0xba,0x91,0xf8,0xf1,0xb0,0xbf,0x90,0x24,0x6d,0xba,0x5d,0xd7,
1558 0x39,0x63,0x3b,0x7c,0x04,0x5d,0x89,0x9d,0x1c,0xf2,0xf7,0xcc,0xdf,0x6e,0x8a,
1559 0x43,0xa9,0xdd,0x86,0x05,0xa2,0xf3,0x22,0x2d,0x1e,0x70,0xa1,0x59,0xd7,0xa5,
1560 0x94,0x7d };
1561
1562 static void testGetIssuerCert(void)
1563 {
1564 BOOL ret;
1565 PCCERT_CONTEXT parent, child, cert1, cert2, cert3;
1566 DWORD flags = 0xffffffff, size;
1567 CERT_NAME_BLOB certsubject;
1568 BYTE *certencoded;
1569 WCHAR rootW[] = {'R', 'O', 'O', 'T', '\0'},
1570 certname[] = {'C', 'N', '=', 'd', 'u', 'm', 'm', 'y', ',', ' ', 'T', '=', 'T', 'e', 's', 't', '\0'};
1571 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1572 CERT_STORE_CREATE_NEW_FLAG, NULL);
1573
1574 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1575
1576 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1577 expiredCert, sizeof(expiredCert), CERT_STORE_ADD_ALWAYS, NULL);
1578 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1579 GetLastError());
1580
1581 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1582 childOfExpired, sizeof(childOfExpired), CERT_STORE_ADD_ALWAYS, &child);
1583 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1584 GetLastError());
1585
1586 /* These crash:
1587 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, NULL);
1588 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, NULL);
1589 */
1590 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, &flags);
1591 ok(!parent && GetLastError() == E_INVALIDARG,
1592 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1593 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, &flags);
1594 ok(!parent && GetLastError() == E_INVALIDARG,
1595 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1596 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1597 ok(!parent && GetLastError() == E_INVALIDARG,
1598 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1599 /* Confusing: the caller cannot set either of the
1600 * CERT_STORE_NO_*_FLAGs, as these are not checks,
1601 * they're results:
1602 */
1603 flags = CERT_STORE_NO_CRL_FLAG | CERT_STORE_NO_ISSUER_FLAG;
1604 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1605 ok(!parent && GetLastError() == E_INVALIDARG,
1606 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1607 /* Perform no checks */
1608 flags = 0;
1609 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1610 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1611 GetLastError());
1612 if (parent)
1613 CertFreeCertificateContext(parent);
1614 /* Check revocation and signature only */
1615 flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG;
1616 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1617 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1618 GetLastError());
1619 /* Confusing: CERT_STORE_REVOCATION_FLAG succeeds when there is no CRL by
1620 * setting CERT_STORE_NO_CRL_FLAG.
1621 */
1622 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
1623 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
1624 flags);
1625 if (parent)
1626 CertFreeCertificateContext(parent);
1627 /* Checking time validity is not productive, because while most Windows
1628 * versions return 0 (time valid) because the child is not expired,
1629 * Windows 2003 SP1 returns that it is expired. Thus the range of
1630 * possibilities is covered, and a test verifies nothing.
1631 */
1632
1633 CertFreeCertificateContext(child);
1634 CertCloseStore(store, 0);
1635
1636 flags = 0;
1637 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1638 CERT_STORE_CREATE_NEW_FLAG, NULL);
1639 /* With only the child certificate, no issuer will be found */
1640 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1641 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1642 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1643 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1644 ok(parent == NULL, "Expected no issuer\n");
1645 ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError());
1646 /* Adding an issuer allows one (and only one) issuer to be found */
1647 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1648 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert1);
1649 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1650 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1651 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1652 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1653 ok(parent == NULL, "Expected only one issuer\n");
1654 ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError());
1655 /* Adding a second issuer allows two issuers to be found - and the second
1656 * issuer is found before the first, implying certs are added to the head
1657 * of a list.
1658 */
1659 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1660 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert2);
1661 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1662 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1663 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1664 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1665 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1666 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1667 ok(parent == NULL, "Expected no more than two issuers\n");
1668 ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError());
1669 CertFreeCertificateContext(child);
1670 CertFreeCertificateContext(cert1);
1671 CertFreeCertificateContext(cert2);
1672 CertCloseStore(store, 0);
1673
1674 /* Repeat the test, reversing the order in which issuers are added,
1675 * to show it's order-dependent.
1676 */
1677 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1678 CERT_STORE_CREATE_NEW_FLAG, NULL);
1679 /* With only the child certificate, no issuer will be found */
1680 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1681 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1682 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1683 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1684 ok(parent == NULL, "Expected no issuer\n");
1685 ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError());
1686 /* Adding an issuer allows one (and only one) issuer to be found */
1687 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1688 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert1);
1689 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1690 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1691 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1692 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1693 ok(parent == NULL, "Expected only one issuer\n");
1694 ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError());
1695 /* Adding a second issuer allows two issuers to be found - and the second
1696 * issuer is found before the first, implying certs are added to the head
1697 * of a list.
1698 */
1699 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1700 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert2);
1701 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1702 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1703 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1704 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1705 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1706 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1707 ok(parent == NULL, "Expected no more than two issuers\n");
1708 ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError());
1709
1710 /* Self-sign a certificate, add to the store and test getting the issuer */
1711 size = 0;
1712 ok(CertStrToNameW(X509_ASN_ENCODING, certname, CERT_X500_NAME_STR, NULL, NULL, &size, NULL),
1713 "CertStrToName should have worked\n");
1714 certencoded = HeapAlloc(GetProcessHeap(), 0, size);
1715 ok(CertStrToNameW(X509_ASN_ENCODING, certname, CERT_X500_NAME_STR, NULL, certencoded, &size, NULL),
1716 "CertStrToName should have worked\n");
1717 certsubject.pbData = certencoded;
1718 certsubject.cbData = size;
1719 cert3 = CertCreateSelfSignCertificate(0, &certsubject, 0, NULL, NULL, NULL, NULL, NULL);
1720 ok(cert3 != NULL, "CertCreateSelfSignCertificate should have worked\n");
1721 ret = CertAddCertificateContextToStore(store, cert3, CERT_STORE_ADD_REPLACE_EXISTING, 0);
1722 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1723 CertFreeCertificateContext(cert3);
1724 cert3 = CertEnumCertificatesInStore(store, NULL);
1725 ok(cert3 != NULL, "CertEnumCertificatesInStore should have worked\n");
1726 SetLastError(0xdeadbeef);
1727 flags = 0;
1728 parent = CertGetIssuerCertificateFromStore(store, cert3, NULL, &flags);
1729 ok(!parent, "Expected NULL\n");
1730 ok(GetLastError() == CRYPT_E_SELF_SIGNED,
1731 "Expected CRYPT_E_SELF_SIGNED, got %08X\n", GetLastErro