2 * crypt32 cert functions tests
4 * Copyright 2005-2006 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wine/test.h"
32 static BOOL (WINAPI * pCryptVerifyCertificateSignatureEx)
33 (HCRYPTPROV, DWORD, DWORD, void *, DWORD, void *, DWORD, void *);
35 static BOOL (WINAPI * pCryptAcquireContextW)
36 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
38 static void init_function_pointers(void)
40 HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll");
41 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
43 #define GET_PROC(dll, func) \
44 p ## func = (void *)GetProcAddress(dll, #func); \
46 trace("GetProcAddress(%s) failed\n", #func);
48 GET_PROC(hCrypt32, CryptVerifyCertificateSignatureEx)
50 GET_PROC(hAdvapi32, CryptAcquireContextW)
55 static BYTE subjectName[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
56 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
58 static BYTE serialNum[] = { 1 };
59 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
60 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
61 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
62 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
63 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
64 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
65 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
66 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
67 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
68 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
69 static BYTE bigCertHash[] = { 0x6e, 0x30, 0x90, 0x71, 0x5f, 0xd9, 0x23,
70 0x56, 0xeb, 0xae, 0x25, 0x40, 0xe6, 0x22, 0xda, 0x19, 0x26, 0x02, 0xa6, 0x08 };
72 static const BYTE bigCertWithDifferentSubject[] = { 0x30, 0x7a, 0x02, 0x01, 0x02,
73 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
74 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67,
75 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31,
76 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
77 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15,
78 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c,
79 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06,
80 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
81 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
83 static const BYTE bigCertWithDifferentIssuer[] = { 0x30, 0x7a, 0x02, 0x01,
84 0x01, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
85 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
86 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
87 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
88 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
89 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
90 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
91 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
92 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
95 static BYTE subjectName2[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
96 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61,
98 static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
99 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
100 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
101 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
102 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
103 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
104 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20,
105 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
106 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
107 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
108 static const BYTE bigCert2WithDifferentSerial[] = { 0x30, 0x7a, 0x02, 0x01,
109 0x02, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
110 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
111 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
112 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
113 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
114 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41,
115 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
116 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
117 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
119 static BYTE bigCert2Hash[] = { 0x4a, 0x7f, 0x32, 0x1f, 0xcf, 0x3b, 0xc0,
120 0x87, 0x48, 0x2b, 0xa1, 0x86, 0x54, 0x18, 0xe4, 0x3a, 0x0e, 0x53, 0x7e, 0x2b };
122 static const BYTE certWithUsage[] = { 0x30, 0x81, 0x93, 0x02, 0x01, 0x01, 0x30,
123 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
124 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00,
125 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
126 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
127 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31,
128 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61,
129 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00,
130 0x03, 0x01, 0x00, 0xa3, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x1d,
131 0x25, 0x01, 0x01, 0xff, 0x04, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01,
132 0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
133 0x03, 0x02, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
135 static void testAddCert(void)
138 HCERTSTORE collection;
139 PCCERT_CONTEXT context;
140 PCCERT_CONTEXT copyContext;
143 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
144 CERT_STORE_CREATE_NEW_FLAG, NULL);
145 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
149 /* Weird--bad add disposition leads to an access violation in Windows.
151 ret = CertAddEncodedCertificateToStore(0, X509_ASN_ENCODING, bigCert,
152 sizeof(bigCert), 0, NULL);
153 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
154 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
155 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
156 bigCert, sizeof(bigCert), 0, NULL);
157 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
158 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
160 /* Weird--can add a cert to the NULL store (does this have special
164 ret = CertAddEncodedCertificateToStore(0, X509_ASN_ENCODING, bigCert,
165 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
166 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
169 CertFreeCertificateContext(context);
171 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
172 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
173 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
175 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
176 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
177 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
179 /* This has the same name as bigCert, so finding isn't done by name */
180 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
181 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, &context);
182 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
184 ok(context != NULL, "Expected a context\n");
187 CRYPT_DATA_BLOB hash = { sizeof(bigCert2Hash), bigCert2Hash };
189 /* Duplicate (AddRef) the context so we can still use it after
190 * deleting it from the store.
192 CertDuplicateCertificateContext(context);
193 CertDeleteCertificateFromStore(context);
194 /* Set the same hash as bigCert2, and try to readd it */
195 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID,
197 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
199 ret = CertAddCertificateContextToStore(store, context,
200 CERT_STORE_ADD_NEW, NULL);
201 /* The failure is a bit odd (CRYPT_E_ASN1_BADTAG), so just check
204 ok(!ret, "Expected failure\n");
205 CertFreeCertificateContext(context);
207 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
209 ok(context != NULL, "Expected a context\n");
212 /* Try to readd bigCert2 to the store */
213 ret = CertAddCertificateContextToStore(store, context,
214 CERT_STORE_ADD_NEW, NULL);
215 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
216 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
217 CertFreeCertificateContext(context);
220 /* Adding a cert with the same issuer name and serial number (but
221 * different subject) as an existing cert succeeds.
224 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
225 bigCert2WithDifferentSerial, sizeof(bigCert2WithDifferentSerial),
226 CERT_STORE_ADD_NEW, &context);
227 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
230 CertDeleteCertificateFromStore(context);
232 /* Adding a cert with the same subject name and serial number (but
233 * different issuer) as an existing cert succeeds.
236 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
237 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject),
238 CERT_STORE_ADD_NEW, &context);
239 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
242 CertDeleteCertificateFromStore(context);
244 /* Adding a cert with the same issuer name and serial number (but
245 * different otherwise) as an existing cert succeeds.
248 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
249 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer),
250 CERT_STORE_ADD_NEW, &context);
251 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
254 CertDeleteCertificateFromStore(context);
256 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
257 CERT_STORE_CREATE_NEW_FLAG, NULL);
258 ok(collection != NULL, "CertOpenStore failed: %08x\n", GetLastError());
261 /* Add store to the collection, but disable updates */
262 CertAddStoreToCollection(collection, store, 0, 0);
264 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
266 ok(context != NULL, "Expected a context\n");
269 /* Try to readd bigCert2 to the collection */
270 ret = CertAddCertificateContextToStore(collection, context,
271 CERT_STORE_ADD_NEW, NULL);
272 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
273 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
274 /* Replacing an existing certificate context is allowed, even
275 * though updates to the collection aren't..
277 ret = CertAddCertificateContextToStore(collection, context,
278 CERT_STORE_ADD_REPLACE_EXISTING, NULL);
279 ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
281 /* use the existing certificate and ask for a copy of the context*/
283 ret = CertAddCertificateContextToStore(collection, context,
284 CERT_STORE_ADD_USE_EXISTING, ©Context);
285 ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
287 ok(copyContext != NULL, "Expected on output a non NULL copyContext\n");
289 CertFreeCertificateContext(copyContext);
290 /* but adding a new certificate isn't allowed. */
291 ret = CertAddCertificateContextToStore(collection, context,
292 CERT_STORE_ADD_ALWAYS, NULL);
293 ok(!ret && GetLastError() == E_ACCESSDENIED,
294 "Expected E_ACCESSDENIED, got %08x\n", GetLastError());
295 CertFreeCertificateContext(context);
298 CertCloseStore(collection, 0);
301 CertCloseStore(store, 0);
304 static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
305 PCCERT_CONTEXT context, DWORD propID)
307 BYTE hash[20] = { 0 }, hashProperty[20];
310 DWORD dwSizeWithNull;
312 memset(hash, 0, sizeof(hash));
313 memset(hashProperty, 0, sizeof(hashProperty));
315 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
316 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
317 ret = CertGetCertificateContextProperty(context, propID, NULL,
319 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
321 ret = CertGetCertificateContextProperty(context, propID, hashProperty,
323 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
325 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
327 ok(size == dwSizeWithNull, "Unexpected length of hash for property: received %d instead of %d\n",
328 dwSizeWithNull,size);
331 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e','m','p',0 };
332 static const BYTE v1CertWithPubKey[] = {
333 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
334 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
335 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
336 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
337 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
338 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
339 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
340 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
341 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
342 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
344 static const BYTE v1CertWithSubjectKeyId[] = {
345 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
346 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
347 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
348 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
349 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
350 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
351 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
352 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
353 0x4c,0x61,0x6e,0x67,0x00 };
354 static const BYTE subjectKeyId[] = {
355 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
357 static void testCertProperties(void)
359 PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
360 bigCert, sizeof(bigCert));
361 DWORD propID, numProps, access, size;
363 BYTE hash[20] = { 0 }, hashProperty[20];
364 CRYPT_DATA_BLOB blob;
365 CERT_KEY_CONTEXT keyContext;
367 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
373 propID = CertEnumCertificateContextProperties(NULL, 0);
379 propID = CertEnumCertificateContextProperties(context, propID);
382 } while (propID != 0);
383 ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
385 /* Tests with a NULL cert context. Prop ID 0 fails.. */
386 ret = CertSetCertificateContextProperty(NULL, 0, 0, NULL);
387 ok(!ret && GetLastError() == E_INVALIDARG,
388 "Expected E_INVALIDARG, got %08x\n", GetLastError());
389 /* while this just crashes.
390 ret = CertSetCertificateContextProperty(NULL,
391 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
394 ret = CertSetCertificateContextProperty(context, 0, 0, NULL);
395 ok(!ret && GetLastError() == E_INVALIDARG,
396 "Expected E_INVALIDARG, got %08x\n", GetLastError());
397 /* Can't set the cert property directly, this crashes.
398 ret = CertSetCertificateContextProperty(context,
399 CERT_CERT_PROP_ID, 0, bigCert2);
403 ret = CertGetCertificateContextProperty(context,
404 CERT_ACCESS_STATE_PROP_ID, 0, NULL);
405 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
407 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
412 ret = CertGetCertificateContextProperty(context,
413 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
414 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
415 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
416 /* And, an implicit property */
417 size = sizeof(access);
418 ret = CertGetCertificateContextProperty(context,
419 CERT_ACCESS_STATE_PROP_ID, &access, &size);
420 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
422 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
423 "Didn't expect a persisted cert\n");
424 /* Trying to set this "read only" property crashes.
425 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
426 ret = CertSetCertificateContextProperty(context,
427 CERT_ACCESS_STATE_PROP_ID, 0, &access);
430 /* Can I set the hash to an invalid hash? */
432 blob.cbData = sizeof(hash);
433 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
435 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
437 size = sizeof(hashProperty);
438 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
439 hashProperty, &size);
440 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
441 /* Delete the (bogus) hash, and get the real one */
442 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
444 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
446 checkHash(bigCert, sizeof(bigCert), CALG_SHA1, context,
449 /* Now that the hash property is set, we should get one property when
455 propID = CertEnumCertificateContextProperties(context, propID);
458 } while (propID != 0);
459 ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
461 /* Check a few other implicit properties */
462 checkHash(bigCert, sizeof(bigCert), CALG_MD5, context,
463 CERT_MD5_HASH_PROP_ID);
465 context->pCertInfo->Subject.pbData,
466 context->pCertInfo->Subject.cbData,
467 CALG_MD5, context, CERT_SUBJECT_NAME_MD5_HASH_PROP_ID);
469 context->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
470 context->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
471 CALG_MD5, context, CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID);
473 /* Test key contexts and handles and such */
475 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
477 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
478 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
479 size = sizeof(CERT_KEY_CONTEXT);
480 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
482 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
483 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
484 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
486 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
487 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
488 /* Key context with an invalid size */
489 keyContext.cbSize = 0;
490 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
492 ok(!ret && GetLastError() == E_INVALIDARG,
493 "Expected E_INVALIDARG, got %08x\n", GetLastError());
494 size = sizeof(keyContext);
495 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
497 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
498 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
499 keyContext.cbSize = sizeof(keyContext);
500 keyContext.hCryptProv = 0;
501 keyContext.dwKeySpec = AT_SIGNATURE;
502 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
504 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
505 /* Now that that's set, the key prov handle property is also gettable.
507 size = sizeof(DWORD);
508 ret = CertGetCertificateContextProperty(context,
509 CERT_KEY_PROV_HANDLE_PROP_ID, &keyContext.hCryptProv, &size);
510 ok(ret, "Expected to get the CERT_KEY_PROV_HANDLE_PROP_ID, got %08x\n",
512 /* Remove the key prov handle property.. */
513 ret = CertSetCertificateContextProperty(context,
514 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
515 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
517 /* and the key context's CSP is set to NULL. */
518 size = sizeof(keyContext);
519 ret = CertGetCertificateContextProperty(context,
520 CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
521 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
523 ok(keyContext.hCryptProv == 0, "Expected no hCryptProv\n");
525 /* According to MSDN the subject key id can be stored as a property,
526 * as a subject key extension, or as the SHA1 hash of the public key,
527 * but this cert has none of them:
529 ret = CertGetCertificateContextProperty(context,
530 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
531 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
532 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
533 CertFreeCertificateContext(context);
534 /* This cert does have a public key, but its subject key identifier still
535 * isn't available: */
536 context = CertCreateCertificateContext(X509_ASN_ENCODING,
537 v1CertWithPubKey, sizeof(v1CertWithPubKey));
538 ret = CertGetCertificateContextProperty(context,
539 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
540 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
541 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
542 CertFreeCertificateContext(context);
543 /* This cert with a subject key extension can have its key identifier
544 * property retrieved:
546 context = CertCreateCertificateContext(X509_ASN_ENCODING,
547 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId));
548 ret = CertGetCertificateContextProperty(context,
549 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
550 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
553 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
557 ret = CertGetCertificateContextProperty(context,
558 CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
559 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
561 ok(!memcmp(buf, subjectKeyId, size), "Unexpected subject key id\n");
562 HeapFree(GetProcessHeap(), 0, buf);
565 CertFreeCertificateContext(context);
568 static void testDupCert(void)
571 PCCERT_CONTEXT context, dupContext;
574 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
575 CERT_STORE_CREATE_NEW_FLAG, NULL);
576 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
580 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
581 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
582 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
584 ok(context != NULL, "Expected a valid cert context\n");
587 ok(context->cbCertEncoded == sizeof(bigCert),
588 "Wrong cert size %d\n", context->cbCertEncoded);
589 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)),
590 "Unexpected encoded cert in context\n");
591 ok(context->hCertStore == store, "Unexpected store\n");
593 dupContext = CertDuplicateCertificateContext(context);
594 ok(dupContext != NULL, "Expected valid duplicate\n");
595 /* Not only is it a duplicate, it's identical: the address is the
598 ok(dupContext == context, "Expected identical context addresses\n");
599 CertFreeCertificateContext(dupContext);
600 CertFreeCertificateContext(context);
602 CertCloseStore(store, 0);
605 static BYTE subjectName3[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
606 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x52, 0x6f, 0x62, 0x20, 0x20, 0x4c, 0x61,
608 static const BYTE iTunesCert0[] = {
609 0x30,0x82,0x03,0xc4,0x30,0x82,0x03,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
610 0x47,0xbf,0x19,0x95,0xdf,0x8d,0x52,0x46,0x43,0xf7,0xdb,0x6d,0x48,0x0d,0x31,
611 0xa4,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
612 0x00,0x30,0x81,0x8b,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
613 0x5a,0x41,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0c,0x57,0x65,
614 0x73,0x74,0x65,0x72,0x6e,0x20,0x43,0x61,0x70,0x65,0x31,0x14,0x30,0x12,0x06,
615 0x03,0x55,0x04,0x07,0x13,0x0b,0x44,0x75,0x72,0x62,0x61,0x6e,0x76,0x69,0x6c,
616 0x6c,0x65,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x0a,0x13,0x06,0x54,0x68,
617 0x61,0x77,0x74,0x65,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14,
618 0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
619 0x61,0x74,0x69,0x6f,0x6e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13,
620 0x16,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
621 0x6d,0x70,0x69,0x6e,0x67,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x33,0x31,
622 0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x33,0x31,
623 0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x53,0x31,0x0b,0x30,
624 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,
625 0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
626 0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,
627 0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,0x6d,0x65,0x20,
628 0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,0x76,0x69,0x63,
629 0x65,0x73,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,
630 0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,
631 0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa9,0xca,0xb2,0xa4,0xcc,0xcd,0x20,
632 0xaf,0x0a,0x7d,0x89,0xac,0x87,0x75,0xf0,0xb4,0x4e,0xf1,0xdf,0xc1,0x0f,0xbf,
633 0x67,0x61,0xbd,0xa3,0x64,0x1c,0xda,0xbb,0xf9,0xca,0x33,0xab,0x84,0x30,0x89,
634 0x58,0x7e,0x8c,0xdb,0x6b,0xdd,0x36,0x9e,0x0f,0xbf,0xd1,0xec,0x78,0xf2,0x77,
635 0xa6,0x7e,0x6f,0x3c,0xbf,0x93,0xaf,0x0d,0xba,0x68,0xf4,0x6c,0x94,0xca,0xbd,
636 0x52,0x2d,0xab,0x48,0x3d,0xf5,0xb6,0xd5,0x5d,0x5f,0x1b,0x02,0x9f,0xfa,0x2f,
637 0x6b,0x1e,0xa4,0xf7,0xa3,0x9a,0xa6,0x1a,0xc8,0x02,0xe1,0x7f,0x4c,0x52,0xe3,
638 0x0e,0x60,0xec,0x40,0x1c,0x7e,0xb9,0x0d,0xde,0x3f,0xc7,0xb4,0xdf,0x87,0xbd,
639 0x5f,0x7a,0x6a,0x31,0x2e,0x03,0x99,0x81,0x13,0xa8,0x47,0x20,0xce,0x31,0x73,
640 0x0d,0x57,0x2d,0xcd,0x78,0x34,0x33,0x95,0x12,0x99,0x12,0xb9,0xde,0x68,0x2f,
641 0xaa,0xe6,0xe3,0xc2,0x8a,0x8c,0x2a,0xc3,0x8b,0x21,0x87,0x66,0xbd,0x83,0x58,
642 0x57,0x6f,0x75,0xbf,0x3c,0xaa,0x26,0x87,0x5d,0xca,0x10,0x15,0x3c,0x9f,0x84,
643 0xea,0x54,0xc1,0x0a,0x6e,0xc4,0xfe,0xc5,0x4a,0xdd,0xb9,0x07,0x11,0x97,0x22,
644 0x7c,0xdb,0x3e,0x27,0xd1,0x1e,0x78,0xec,0x9f,0x31,0xc9,0xf1,0xe6,0x22,0x19,
645 0xdb,0xc4,0xb3,0x47,0x43,0x9a,0x1a,0x5f,0xa0,0x1e,0x90,0xe4,0x5e,0xf5,0xee,
646 0x7c,0xf1,0x7d,0xab,0x62,0x01,0x8f,0xf5,0x4d,0x0b,0xde,0xd0,0x22,0x56,0xa8,
647 0x95,0xcd,0xae,0x88,0x76,0xae,0xee,0xba,0x0d,0xf3,0xe4,0x4d,0xd9,0xa0,0xfb,
648 0x68,0xa0,0xae,0x14,0x3b,0xb3,0x87,0xc1,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,
649 0x81,0xdb,0x30,0x81,0xd8,0x30,0x34,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
650 0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
651 0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,
652 0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,
653 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
654 0xff,0x02,0x01,0x00,0x30,0x41,0x06,0x03,0x55,0x1d,0x1f,0x04,0x3a,0x30,0x38,
655 0x30,0x36,0xa0,0x34,0xa0,0x32,0x86,0x30,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
656 0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,
657 0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
658 0x6d,0x70,0x69,0x6e,0x67,0x43,0x41,0x2e,0x63,0x72,0x6c,0x30,0x13,0x06,0x03,
659 0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
660 0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,
661 0x02,0x01,0x06,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,0x04,0x1d,0x30,0x1b,0xa4,
662 0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0c,0x54,
663 0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,0x33,0x30,0x0d,0x06,0x09,
664 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,
665 0x4a,0x6b,0xf9,0xea,0x58,0xc2,0x44,0x1c,0x31,0x89,0x79,0x99,0x2b,0x96,0xbf,
666 0x82,0xac,0x01,0xd6,0x1c,0x4c,0xcd,0xb0,0x8a,0x58,0x6e,0xdf,0x08,0x29,0xa3,
667 0x5e,0xc8,0xca,0x93,0x13,0xe7,0x04,0x52,0x0d,0xef,0x47,0x27,0x2f,0x00,0x38,
668 0xb0,0xe4,0xc9,0x93,0x4e,0x9a,0xd4,0x22,0x62,0x15,0xf7,0x3f,0x37,0x21,0x4f,
669 0x70,0x31,0x80,0xf1,0x8b,0x38,0x87,0xb3,0xe8,0xe8,0x97,0x00,0xfe,0xcf,0x55,
670 0x96,0x4e,0x24,0xd2,0xa9,0x27,0x4e,0x7a,0xae,0xb7,0x61,0x41,0xf3,0x2a,0xce,
671 0xe7,0xc9,0xd9,0x5e,0xdd,0xbb,0x2b,0x85,0x3e,0xb5,0x9d,0xb5,0xd9,0xe1,0x57,
672 0xff,0xbe,0xb4,0xc5,0x7e,0xf5,0xcf,0x0c,0x9e,0xf0,0x97,0xfe,0x2b,0xd3,0x3b,
673 0x52,0x1b,0x1b,0x38,0x27,0xf7,0x3f,0x4a };
674 static const BYTE iTunesCert1[] = {
675 0x30,0x82,0x03,0xff,0x30,0x82,0x02,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
676 0x0d,0xe9,0x2b,0xf0,0xd4,0xd8,0x29,0x88,0x18,0x32,0x05,0x09,0x5e,0x9a,0x76,
677 0x88,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
678 0x00,0x30,0x53,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
679 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
680 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,
681 0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
682 0x20,0x54,0x69,0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,
683 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,
684 0x30,0x33,0x31,0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
685 0x30,0x38,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x57,
686 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,
687 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,
688 0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2f,0x30,0x2d,0x06,0x03,0x55,
689 0x04,0x03,0x13,0x26,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,
690 0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,
691 0x76,0x69,0x63,0x65,0x73,0x20,0x53,0x69,0x67,0x6e,0x65,0x72,0x30,0x82,0x01,
692 0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
693 0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,
694 0xb2,0x50,0x28,0x48,0xdd,0xd3,0x68,0x7a,0x84,0x18,0x44,0x66,0x75,0x5d,0x7e,
695 0xc4,0xb8,0x9f,0x63,0x26,0xff,0x3d,0x43,0x9c,0x7c,0x11,0x38,0x10,0x25,0x55,
696 0x73,0xd9,0x75,0x27,0x69,0xfd,0x4e,0xb9,0x20,0x5c,0xd3,0x0a,0xf9,0xa0,0x1b,
697 0x2a,0xed,0x55,0x56,0x21,0x61,0xd8,0x1e,0xdb,0xe4,0xbc,0x33,0x6b,0xc7,0xef,
698 0xdd,0xa3,0x37,0x65,0x8e,0x1b,0x93,0x0c,0xb6,0x53,0x1e,0x5c,0x7c,0x66,0x35,
699 0x5f,0x05,0x8a,0x45,0xfe,0x76,0x4e,0xdf,0x53,0x80,0xa2,0x81,0x20,0x9d,0xae,
700 0x88,0x5c,0xa2,0x08,0xf7,0xe5,0x30,0xf9,0xee,0x22,0x37,0x4c,0x42,0x0a,0xce,
701 0xdf,0xc6,0x1f,0xc4,0xd6,0x55,0xe9,0x81,0x3f,0xb5,0x52,0xa3,0x2c,0xaa,0x01,
702 0x7a,0xf2,0xa2,0xaa,0x8d,0x35,0xfe,0x9f,0xe6,0x5d,0x6a,0x05,0x9f,0x3d,0x6b,
703 0xe3,0xbf,0x96,0xc0,0xfe,0xcc,0x60,0xf9,0x40,0xe7,0x07,0xa0,0x44,0xeb,0x81,
704 0x51,0x6e,0xa5,0x2a,0xf2,0xb6,0x8a,0x10,0x28,0xed,0x8f,0xdc,0x06,0xa0,0x86,
705 0x50,0x9a,0x7b,0x4a,0x08,0x0d,0x30,0x1d,0xca,0x10,0x9e,0x6b,0xf7,0xe9,0x58,
706 0xae,0x04,0xa9,0x40,0x99,0xb2,0x28,0xe8,0x8f,0x16,0xac,0x3c,0xe3,0x53,0x6f,
707 0x4b,0xd3,0x35,0x9d,0xb5,0x6f,0x64,0x1d,0xb3,0x96,0x2c,0xbb,0x3d,0xe7,0x79,
708 0xeb,0x6d,0x7a,0xf9,0x16,0xe6,0x26,0xad,0xaf,0xef,0x99,0x53,0xb7,0x40,0x2c,
709 0x95,0xb8,0x79,0xaa,0xfe,0xd4,0x52,0xab,0x29,0x74,0x7e,0x42,0xec,0x39,0x1e,
710 0xa2,0x6a,0x16,0xe6,0x59,0xbb,0x24,0x68,0xd8,0x00,0x80,0x43,0x10,0x87,0x80,
711 0x6b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xca,0x30,0x81,0xc7,0x30,0x34,0x06,
712 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,
713 0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,
714 0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
715 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
716 0xff,0x04,0x02,0x30,0x00,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30,
717 0x2a,0x30,0x28,0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,
718 0x2f,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,
719 0x6f,0x6d,0x2f,0x74,0x73,0x73,0x2d,0x63,0x61,0x2e,0x63,0x72,0x6c,0x30,0x16,
720 0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,
721 0x06,0x01,0x05,0x05,0x07,0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
722 0x01,0xff,0x04,0x04,0x03,0x02,0x06,0xc0,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,
723 0x04,0x1d,0x30,0x1b,0xa4,0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,
724 0x04,0x03,0x13,0x0c,0x54,0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,
725 0x34,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
726 0x00,0x03,0x82,0x01,0x01,0x00,0x87,0x78,0x70,0xda,0x4e,0x52,0x01,0x20,0x5b,
727 0xe0,0x79,0xc9,0x82,0x30,0xc4,0xfd,0xb9,0x19,0x96,0xbd,0x91,0x00,0xc3,0xbd,
728 0xcd,0xcd,0xc6,0xf4,0x0e,0xd8,0xff,0xf9,0x4d,0xc0,0x33,0x62,0x30,0x11,0xc5,
729 0xf5,0x74,0x1b,0xd4,0x92,0xde,0x5f,0x9c,0x20,0x13,0xb1,0x7c,0x45,0xbe,0x50,
730 0xcd,0x83,0xe7,0x80,0x17,0x83,0xa7,0x27,0x93,0x67,0x13,0x46,0xfb,0xca,0xb8,
731 0x98,0x41,0x03,0xcc,0x9b,0x51,0x5b,0x05,0x8b,0x7f,0xa8,0x6f,0xf3,0x1b,0x50,
732 0x1b,0x24,0x2e,0xf2,0x69,0x8d,0x6c,0x22,0xf7,0xbb,0xca,0x16,0x95,0xed,0x0c,
733 0x74,0xc0,0x68,0x77,0xd9,0xeb,0x99,0x62,0x87,0xc1,0x73,0x90,0xf8,0x89,0x74,
734 0x7a,0x23,0xab,0xa3,0x98,0x7b,0x97,0xb1,0xf7,0x8f,0x29,0x71,0x4d,0x2e,0x75,
735 0x1b,0x48,0x41,0xda,0xf0,0xb5,0x0d,0x20,0x54,0xd6,0x77,0xa0,0x97,0x82,0x63,
736 0x69,0xfd,0x09,0xcf,0x8a,0xf0,0x75,0xbb,0x09,0x9b,0xd9,0xf9,0x11,0x55,0x26,
737 0x9a,0x61,0x32,0xbe,0x7a,0x02,0xb0,0x7b,0x86,0xbe,0xa2,0xc3,0x8b,0x22,0x2c,
738 0x78,0xd1,0x35,0x76,0xbc,0x92,0x73,0x5c,0xf9,0xb9,0xe6,0x4c,0x15,0x0a,0x23,
739 0xcc,0xe4,0xd2,0xd4,0x34,0x2e,0x49,0x40,0x15,0x3c,0x0f,0x60,0x7a,0x24,0xc6,
740 0xa5,0x66,0xef,0x96,0xcf,0x70,0xeb,0x3e,0xe7,0xf4,0x0d,0x7e,0xdc,0xd1,0x7c,
741 0xa3,0x76,0x71,0x69,0xc1,0x9c,0x4f,0x47,0x30,0x35,0x21,0xb1,0xa2,0xaf,0x1a,
742 0x62,0x3c,0x2b,0xd9,0x8e,0xaa,0x2a,0x07,0x7b,0xd8,0x18,0xb3,0x5c,0x7b,0xe2,
743 0x9d,0xa5,0x6f,0xfe,0x3c,0x89,0xad };
744 static const BYTE iTunesCert2[] = {
745 0x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
746 0x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75,
747 0xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
748 0x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
749 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
750 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,
751 0x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,
752 0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,
753 0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,
754 0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x34,0x30,
755 0x37,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30,
756 0x37,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,
757 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,
758 0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
759 0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b,
760 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,
761 0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,
762 0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,
763 0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,
764 0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,
765 0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,
766 0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,
767 0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,0x53,0x69,
768 0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,0x20,0x43,0x41,0x30,0x82,
769 0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,
770 0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,
771 0x00,0xbe,0xbc,0xee,0xbc,0x7e,0xef,0x83,0xeb,0xe0,0x37,0x4f,0xfb,0x03,0x10,
772 0x38,0xbe,0x08,0xd2,0x8c,0x7d,0x9d,0xfa,0x92,0x7f,0x19,0x0c,0xc2,0x6b,0xee,
773 0x42,0x52,0x8c,0xde,0xd3,0x1c,0x48,0x13,0x25,0xea,0xc1,0x63,0x7a,0xf9,0x51,
774 0x65,0xee,0xd3,0xaa,0x3b,0xf5,0xf0,0x94,0x9c,0x2b,0xfb,0xf2,0x66,0xd4,0x24,
775 0xda,0xf7,0xf5,0x9f,0x6e,0x19,0x39,0x36,0xbc,0xd0,0xa3,0x76,0x08,0x1e,0x22,
776 0x27,0x24,0x6c,0x38,0x91,0x27,0xe2,0x84,0x49,0xae,0x1b,0x8a,0xa1,0xfd,0x25,
777 0x82,0x2c,0x10,0x30,0xe8,0x71,0xab,0x28,0xe8,0x77,0x4a,0x51,0xf1,0xec,0xcd,
778 0xf8,0xf0,0x54,0xd4,0x6f,0xc0,0xe3,0x6d,0x0a,0x8f,0xd9,0xd8,0x64,0x8d,0x63,
779 0xb2,0x2d,0x4e,0x27,0xf6,0x85,0x0e,0xfe,0x6d,0xe3,0x29,0x99,0xe2,0x85,0x47,
780 0x7c,0x2d,0x86,0x7f,0xe8,0x57,0x8f,0xad,0x67,0xc2,0x33,0x32,0x91,0x13,0x20,
781 0xfc,0xa9,0x23,0x14,0x9a,0x6d,0xc2,0x84,0x4b,0x76,0x68,0x04,0xd5,0x71,0x2c,
782 0x5d,0x21,0xfa,0x88,0x0d,0x26,0xfd,0x1f,0x2d,0x91,0x2b,0xe7,0x01,0x55,0x4d,
783 0xf2,0x6d,0x35,0x28,0x82,0xdf,0xd9,0x6b,0x5c,0xb6,0xd6,0xd9,0xaa,0x81,0xfd,
784 0x5f,0xcd,0x83,0xba,0x63,0x9d,0xd0,0x22,0xfc,0xa9,0x3b,0x42,0x69,0xb2,0x8e,
785 0x3a,0xb5,0xbc,0xb4,0x9e,0x0f,0x5e,0xc4,0xea,0x2c,0x82,0x8b,0x28,0xfd,0x53,
786 0x08,0x96,0xdd,0xb5,0x01,0x20,0xd1,0xf9,0xa5,0x18,0xe7,0xc0,0xee,0x51,0x70,
787 0x37,0xe1,0xb6,0x05,0x48,0x52,0x48,0x6f,0x38,0xea,0xc3,0xe8,0x6c,0x7b,0x44,
788 0x84,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xa0,0x30,0x82,0x01,0x9c,
789 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
790 0x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,
791 0x3b,0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,
792 0x03,0x30,0x2a,0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
793 0x16,0x1c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,
794 0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,
795 0x30,0x31,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24,
796 0xa0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,
797 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63,
798 0x61,0x33,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16,
799 0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2b,
800 0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
801 0x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48,
802 0x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x01,0x30,0x29,0x06,
803 0x03,0x55,0x1d,0x11,0x04,0x22,0x30,0x20,0xa4,0x1e,0x30,0x1c,0x31,0x1a,0x30,
804 0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6c,0x61,0x73,0x73,0x33,0x43,
805 0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x34,0x33,0x30,0x1d,0x06,0x03,0x55,
806 0x1d,0x0e,0x04,0x16,0x04,0x14,0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,
807 0x36,0x7c,0x68,0xcf,0x5b,0x78,0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x81,0x80,0x06,
808 0x03,0x55,0x1d,0x23,0x04,0x79,0x30,0x77,0xa1,0x63,0xa4,0x61,0x30,0x5f,0x31,
809 0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,
810 0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
811 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,
812 0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6c,
813 0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,
814 0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,
815 0x72,0x69,0x74,0x79,0x82,0x10,0x70,0xba,0xe4,0x1d,0x10,0xd9,0x29,0x34,0xb6,
816 0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
817 0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xae,0x3a,0x17,0xb8,
818 0x4a,0x7b,0x55,0xfa,0x64,0x55,0xec,0x40,0xa4,0xed,0x49,0x41,0x90,0x99,0x9c,
819 0x89,0xbc,0xaf,0x2e,0x1d,0xca,0x78,0x23,0xf9,0x1c,0x19,0x0f,0x7f,0xeb,0x68,
820 0xbc,0x32,0xd9,0x88,0x38,0xde,0xdc,0x3f,0xd3,0x89,0xb4,0x3f,0xb1,0x82,0x96,
821 0xf1,0xa4,0x5a,0xba,0xed,0x2e,0x26,0xd3,0xde,0x7c,0x01,0x6e,0x00,0x0a,0x00,
822 0xa4,0x06,0x92,0x11,0x48,0x09,0x40,0xf9,0x1c,0x18,0x79,0x67,0x23,0x24,0xe0,
823 0xbb,0xd5,0xe1,0x50,0xae,0x1b,0xf5,0x0e,0xdd,0xe0,0x2e,0x81,0xcd,0x80,0xa3,
824 0x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88,
825 0x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f,
826 0x5e,0xf6,0x7a,0xb5 };
827 static const BYTE iTunesCert3[] = {
828 0x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
829 0x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6,
830 0x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
831 0x00,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
832 0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,
833 0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,
834 0x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
835 0x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,
836 0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,
837 0x73,0x20,0x6f,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,
838 0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
839 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,
840 0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,
841 0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,
842 0x6f,0x64,0x65,0x20,0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,
843 0x34,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x31,0x37,0x30,
844 0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x38,0x30,0x31,0x32,0x32,0x32,
845 0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,
846 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
847 0x08,0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x12,
848 0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,
849 0x69,0x6e,0x6f,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0a,0x14,0x14,0x41,
850 0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x2c,0x20,
851 0x49,0x6e,0x63,0x2e,0x31,0x3e,0x30,0x3c,0x06,0x03,0x55,0x04,0x0b,0x13,0x35,
852 0x44,0x69,0x67,0x69,0x74,0x61,0x6c,0x20,0x49,0x44,0x20,0x43,0x6c,0x61,0x73,
853 0x73,0x20,0x33,0x20,0x2d,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
854 0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x56,0x61,0x6c,0x69,0x64,
855 0x61,0x74,0x69,0x6f,0x6e,0x20,0x76,0x32,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,
856 0x04,0x03,0x14,0x14,0x41,0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,
857 0x74,0x65,0x72,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x30,0x81,0x9f,0x30,0x0d,0x06,
858 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,
859 0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xd3,0xab,0x3b,0x7f,0xec,0x48,0x84,
860 0xce,0xa8,0x1a,0x12,0xf3,0x3c,0x87,0xcb,0x24,0x58,0x96,0x02,0x87,0x66,0x49,
861 0xeb,0x89,0xee,0x79,0x44,0x70,0x8d,0xe7,0xd4,0x1f,0x30,0x92,0xc0,0x9c,0x35,
862 0x78,0xc0,0xaf,0x1c,0xb6,0x28,0xd3,0xe0,0xe0,0x9d,0xd3,0x49,0x76,0x73,0x57,
863 0x19,0x4d,0x8d,0x70,0x85,0x64,0x4d,0x1d,0xc6,0x02,0x3e,0xe5,0x2c,0x66,0x07,
864 0xd2,0x27,0x4b,0xd6,0xc8,0x3c,0x93,0xb6,0x15,0x0c,0xde,0x5b,0xd7,0x93,0xdd,
865 0xbe,0x85,0x62,0x34,0x17,0x8a,0x05,0x60,0xf0,0x8a,0x1c,0x5a,0x40,0x21,0x8d,
866 0x51,0x6c,0xb0,0x62,0xd8,0xb5,0xd4,0xf9,0xb1,0xd0,0x58,0x7a,0x7a,0x82,0x55,
867 0xb3,0xf9,0x53,0x71,0xde,0xd2,0xc9,0x37,0x8c,0xf6,0x5a,0x1f,0x2d,0xcd,0x7c,
868 0x67,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30,
869 0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06,0x03,0x55,
870 0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x40,0x06,0x03,
871 0x55,0x1d,0x1f,0x04,0x39,0x30,0x37,0x30,0x35,0xa0,0x33,0xa0,0x31,0x86,0x2f,
872 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,
873 0x34,0x2d,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,
874 0x63,0x6f,0x6d,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2e,0x63,
875 0x72,0x6c,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b,0x30,0x39,
876 0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,0x03,0x30,0x2a,
877 0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1c,0x68,
878 0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,
879 0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x30,0x13,0x06,
880 0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
881 0x07,0x03,0x03,0x30,0x75,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
882 0x04,0x69,0x30,0x67,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,
883 0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,
884 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x3f,0x06,
885 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x33,0x68,0x74,0x74,0x70,
886 0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,
887 0x61,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,
888 0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,0x61,0x2e,0x63,
889 0x65,0x72,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
890 0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,0x36,0x7c,0x68,0xcf,0x5b,0x78,
891 0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,
892 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x04,0x10,0x30,0x16,0x06,0x0a,0x2b,0x06,
893 0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x1b,0x04,0x08,0x30,0x06,0x01,0x01,0x00,
894 0x01,0x01,0xff,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
895 0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6a,0xa6,0x06,0xd0,0x33,0x18,0x64,
896 0xe2,0x69,0x82,0xee,0x6e,0x36,0x9e,0x9d,0x9a,0x0e,0x18,0xa8,0xac,0x9d,0x10,
897 0xed,0x01,0x3c,0xb9,0x61,0x04,0x62,0xf3,0x85,0x8f,0xcc,0x4f,0x2c,0x66,0x35,
898 0x54,0x25,0x45,0x8d,0x95,0x1c,0xd2,0x33,0xbe,0x2e,0xdd,0x7f,0x74,0xaf,0x03,
899 0x7b,0x86,0x63,0xb0,0xc9,0xe6,0xbd,0xc7,0x8e,0xde,0x03,0x18,0x98,0x82,0xc3,
900 0xbb,0xf8,0x15,0x99,0x1a,0xa9,0xdd,0xb9,0x5d,0xb9,0xbd,0x53,0x95,0x25,0x76,
901 0xfb,0x5c,0x53,0x90,0xea,0x01,0x0a,0xa0,0xb1,0xbf,0x09,0x1b,0x97,0x8f,0x40,
902 0xfa,0x85,0x12,0x74,0x01,0xdb,0xf6,0xdb,0x09,0xd6,0x5f,0x4f,0xd7,0x17,0xb4,
903 0xbf,0x9e,0x2f,0x86,0x52,0x5d,0x70,0x24,0x52,0x32,0x1e,0xa5,0x1d,0x39,0x8b,
904 0x66,0xf6,0xba,0x9b,0x69,0x8e,0x12,0x60,0xdb,0xb6,0xcf,0xe6,0x0d,0xd6,0x1c,
905 0x8f,0xd4,0x5b,0x4b,0x00,0xde,0x21,0x93,0xfb,0x6e,0xc7,0x3d,0xb4,0x66,0x0d,
906 0x29,0x0c,0x4e,0xe9,0x3f,0x94,0xd6,0xd6,0xdc,0xec,0xf8,0x53,0x3b,0x62,0xd5,
907 0x97,0x50,0x53,0x84,0x17,0xfe,0xe2,0xed,0x4c,0x23,0x0a,0x49,0xce,0x5b,0xe9,
908 0x70,0x31,0xc1,0x04,0x02,0x02,0x6c,0xb8,0x52,0xcd,0xc7,0x4e,0x70,0xb4,0x13,
909 0xd7,0xe0,0x92,0xba,0x44,0x1a,0x10,0x4c,0x6e,0x45,0xc6,0x86,0x04,0xc6,0x64,
910 0xd3,0x9c,0x6e,0xc1,0x9c,0xac,0x74,0x3d,0x77,0x06,0x5e,0x28,0x28,0x5c,0xf5,
911 0xe0,0x9c,0x19,0xd8,0xba,0x74,0x81,0x2d,0x67,0x77,0x93,0x8d,0xbf,0xd2,0x52,
912 0x00,0xe6,0xa5,0x38,0x4e,0x2e,0x73,0x66,0x7a };
913 static BYTE iTunesIssuer[] = {
914 0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
915 0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,
916 0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
917 0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,
918 0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
919 0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,
920 0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,
921 0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,0x73,
922 0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,
923 0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,
924 0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,
925 0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,
926 0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
927 0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,
928 0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,
930 static BYTE iTunesSerialNum[] = {
931 0x8d,0xf6,0x6a,0xdf,0xd2,0x40,0xfe,0xb6,0xa6,0x61,0x9b,0x9b,
932 0xe0,0xa0,0x1a,0x0f };
934 static void testFindCert(void)
937 PCCERT_CONTEXT context = NULL, subject;
939 CERT_INFO certInfo = { 0 };
940 CRYPT_HASH_BLOB blob;
941 BYTE otherSerialNumber[] = { 2 };
943 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
944 CERT_STORE_CREATE_NEW_FLAG, NULL);
945 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
949 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
950 bigCert, sizeof(bigCert), CERT_STORE_ADD_NEW, NULL);
951 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
953 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
954 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
955 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
957 /* This has the same name as bigCert */
958 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
959 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
960 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
964 context = CertFindCertificateInStore(NULL, 0, 0, 0, NULL, NULL);
967 /* Check first cert's there, by issuer */
968 certInfo.Subject.pbData = subjectName;
969 certInfo.Subject.cbData = sizeof(subjectName);
970 certInfo.SerialNumber.pbData = serialNum;
971 certInfo.SerialNumber.cbData = sizeof(serialNum);
972 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
973 CERT_FIND_ISSUER_NAME, &certInfo.Subject, NULL);
974 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
978 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
979 CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
980 ok(context != NULL, "Expected more than one cert\n");
983 context = CertFindCertificateInStore(store, X509_ASN_ENCODING,
984 0, CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
985 ok(context == NULL, "Expected precisely two certs\n");
989 /* Check second cert's there as well, by subject name */
990 certInfo.Subject.pbData = subjectName2;
991 certInfo.Subject.cbData = sizeof(subjectName2);
992 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
993 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, NULL);
994 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
998 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
999 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, context);
1000 ok(context == NULL, "Expected one cert only\n");
1003 /* Strange but true: searching for the subject cert requires you to set
1004 * the issuer, not the subject
1006 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1007 CERT_FIND_SUBJECT_CERT, &certInfo.Subject, NULL);
1008 ok(context == NULL, "Expected no certificate\n");
1009 certInfo.Subject.pbData = NULL;
1010 certInfo.Subject.cbData = 0;
1011 certInfo.Issuer.pbData = subjectName2;
1012 certInfo.Issuer.cbData = sizeof(subjectName2);
1013 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1014 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1015 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1019 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1020 CERT_FIND_SUBJECT_CERT, &certInfo.Subject, context);
1021 ok(context == NULL, "Expected one cert only\n");
1023 /* A non-matching serial number will not match. */
1024 certInfo.SerialNumber.pbData = otherSerialNumber;
1025 certInfo.SerialNumber.cbData = sizeof(otherSerialNumber);
1026 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1027 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1028 ok(context == NULL, "Expected no match\n");
1029 /* No serial number will not match */
1030 certInfo.SerialNumber.cbData = 0;
1031 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1032 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1033 ok(context == NULL, "Expected no match\n");
1034 /* A serial number still won't match if the name doesn't */
1035 certInfo.SerialNumber.pbData = serialNum;
1036 certInfo.SerialNumber.cbData = sizeof(serialNum);
1037 certInfo.Issuer.pbData = subjectName3;
1038 certInfo.Issuer.cbData = sizeof(subjectName3);
1039 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1040 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1041 ok(context == NULL, "Expected no match\n");
1043 /* The nice thing about hashes, they're unique */
1044 blob.pbData = bigCertHash;
1045 blob.cbData = sizeof(bigCertHash);
1046 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1047 CERT_FIND_SHA1_HASH, &blob, NULL);
1048 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1052 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1053 CERT_FIND_SHA1_HASH, &certInfo.Subject, context);
1054 ok(context == NULL, "Expected one cert only\n");
1057 CertCloseStore(store, 0);
1059 /* Another subject cert search, using iTunes's certs */
1060 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1061 CERT_STORE_CREATE_NEW_FLAG, NULL);
1062 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1063 iTunesCert0, sizeof(iTunesCert0), CERT_STORE_ADD_NEW, NULL);
1064 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1066 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1067 iTunesCert1, sizeof(iTunesCert1), CERT_STORE_ADD_NEW, NULL);
1068 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1070 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1071 iTunesCert2, sizeof(iTunesCert2), CERT_STORE_ADD_NEW, NULL);
1072 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1074 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1075 iTunesCert3, sizeof(iTunesCert3), CERT_STORE_ADD_NEW, &subject);
1076 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1079 /* The certInfo's issuer does not match any subject, but the serial
1080 * number does match a cert whose issuer matches certInfo's issuer.
1081 * This yields a match.
1083 certInfo.SerialNumber.cbData = sizeof(iTunesSerialNum);
1084 certInfo.SerialNumber.pbData = iTunesSerialNum;
1085 certInfo.Issuer.cbData = sizeof(iTunesIssuer);
1086 certInfo.Issuer.pbData = iTunesIssuer;
1087 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1088 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1089 ok(context != NULL, "Expected a match\n");
1092 ret = CertCompareCertificateName(context->dwCertEncodingType,
1093 &certInfo.Issuer, &context->pCertInfo->Subject);
1094 ok(!ret, "Expected subject name not to match\n");
1095 ret = CertCompareCertificateName(context->dwCertEncodingType,
1096 &certInfo.Issuer, &context->pCertInfo->Issuer);
1097 ok(ret, "Expected issuer name to match\n");
1098 ret = CertCompareIntegerBlob(&certInfo.SerialNumber,
1099 &context->pCertInfo->SerialNumber);
1100 ok(ret, "Expected serial number to match\n");
1101 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1102 CERT_FIND_SUBJECT_CERT, &certInfo, context);
1103 ok(context == NULL, "Expected one cert only\n");
1106 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1107 CERT_FIND_ISSUER_OF, subject, NULL);
1108 ok(context != NULL, "Expected an issuer\n");
1111 PCCERT_CONTEXT none = CertFindCertificateInStore(store,
1112 X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_OF, context, NULL);
1114 ok(!none, "Expected no parent of issuer\n");
1115 CertFreeCertificateContext(context);
1117 CertFreeCertificateContext(subject);
1118 CertCloseStore(store, 0);
1121 static void testGetSubjectCert(void)
1124 PCCERT_CONTEXT context1, context2;
1125 CERT_INFO info = { 0 };
1128 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1129 CERT_STORE_CREATE_NEW_FLAG, NULL);
1130 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1134 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1135 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1136 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1138 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1139 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, &context1);
1140 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1142 ok(context1 != NULL, "Expected a context\n");
1143 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1144 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1145 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1148 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1150 ok(!context2 && GetLastError() == E_INVALIDARG,
1151 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1152 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1154 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1155 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1156 info.SerialNumber.cbData = sizeof(serialNum);
1157 info.SerialNumber.pbData = serialNum;
1158 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1160 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1161 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1162 info.Issuer.cbData = sizeof(subjectName2);
1163 info.Issuer.pbData = subjectName2;
1164 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1166 ok(context2 != NULL,
1167 "CertGetSubjectCertificateFromStore failed: %08x\n", GetLastError());
1168 /* Not only should this find a context, but it should be the same
1169 * (same address) as context1.
1171 ok(context1 == context2, "Expected identical context addresses\n");
1172 CertFreeCertificateContext(context2);
1174 CertFreeCertificateContext(context1);
1175 CertCloseStore(store, 0);
1178 /* This expires in 1970 or so */
1179 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
1180 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
1181 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
1182 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1183 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1184 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1185 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
1186 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
1187 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1188 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1189 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1190 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
1191 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
1192 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
1193 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
1194 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
1195 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
1196 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
1197 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
1198 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
1199 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
1200 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
1201 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
1202 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
1203 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
1205 /* This expires in 2036 or so */
1206 static const BYTE childOfExpired[] = { 0x30, 0x81, 0xcc, 0x30, 0x78, 0xa0,
1207 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
1208 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d,
1209 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63,
1210 0x40, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e,
1211 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x35, 0x30, 0x35,
1212 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x35,
1213 0x30, 0x35, 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x30, 0x15, 0x31, 0x13,
1214 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e,
1215 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03,
1216 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
1217 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x20, 0x3b, 0xdb, 0x4d, 0x67, 0x50,
1218 0xec, 0x73, 0x9d, 0xf9, 0x85, 0x5d, 0x18, 0xe9, 0xb4, 0x98, 0xe3, 0x31, 0xb7,
1219 0x03, 0x0b, 0xc0, 0x39, 0x93, 0x56, 0x81, 0x0a, 0xfc, 0x78, 0xa8, 0x29, 0x42,
1220 0x5f, 0x69, 0xfb, 0xbc, 0x5b, 0xf2, 0xa6, 0x2a, 0xbe, 0x91, 0x2c, 0xfc, 0x89,
1221 0x69, 0x15, 0x18, 0x58, 0xe5, 0x02, 0x75, 0xf7, 0x2a, 0xb6, 0xa9, 0xfb, 0x47,
1222 0x6a, 0x6e, 0x0a, 0x9b, 0xe9, 0xdc };
1226 * A chain with two issuers, only one of whose dates is valid.
1228 static const BYTE chain10_0[] = {
1229 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1230 0x4a,0x30,0x3a,0x42,0xa2,0x5a,0xb3,0x93,0x4d,0x94,0x06,0xad,0x6d,0x1c,0x34,
1231 0xe6,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1232 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1233 0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1234 0x30,0x5a,0x17,0x0d,0x30,0x36,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1235 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1236 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1237 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1238 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1239 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1240 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1241 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1242 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1243 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1244 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1245 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1246 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1247 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1248 0x81,0x00,0x85,0x6e,0x35,0x2f,0x2c,0x51,0x4f,0xd6,0x2a,0xe4,0x9e,0xd0,0x4b,
1249 0xe6,0x90,0xfd,0xf7,0x20,0xad,0x76,0x3f,0x93,0xea,0x7f,0x0d,0x1f,0xb3,0x8e,
1250 0xfd,0xe0,0xe1,0xd6,0xd7,0x9c,0x7d,0x46,0x6b,0x15,0x5c,0xe6,0xc9,0x62,0x3b,
1251 0x70,0x4a,0x4b,0xb2,0x82,0xe3,0x55,0x0c,0xc4,0x90,0x44,0x06,0x6c,0x86,0x1c,
1252 0x6d,0x47,0x12,0xda,0x33,0x95,0x5d,0x98,0x43,0xcb,0x7c,0xfa,0x2b,0xee,0xc4,
1253 0x2d,0xc8,0x95,0x33,0x89,0x08,0x3f,0x9f,0x87,0xea,0x20,0x04,0xaf,0x58,0x4b,
1254 0x9d,0xc0,0x7c,0x0a,0x1b,0x05,0x31,0x3b,0xbb,0x13,0x58,0x2e,0x3f,0x61,0x6b,
1255 0x10,0xb4,0xeb,0xb9,0x1a,0x30,0xfd,0xea,0xca,0x29,0x99,0x5f,0x42,0x2b,0x00,
1256 0xb0,0x08,0xc3,0xf0,0xb6,0xd6,0x6b,0xf9,0x35,0x95 };
1257 static const BYTE chain10_1[] = {
1258 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1259 0xbf,0x99,0x4f,0x14,0x03,0x77,0x44,0xb8,0x49,0x02,0x70,0xa1,0xb8,0x9c,0xa7,
1260 0x24,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1261 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1262 0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1263 0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1264 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1265 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1266 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1267 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1268 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1269 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1270 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1271 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1272 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1273 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1274 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1275 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1276 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1277 0x81,0x00,0xa8,0xec,0x8c,0x34,0xe7,0x2c,0xdf,0x75,0x87,0xc4,0xf7,0xda,0x71,
1278 0x72,0x29,0xb2,0x48,0xa8,0x2a,0xec,0x7b,0x7d,0x19,0xb9,0x5f,0x1d,0xd9,0x91,
1279 0x2b,0xc4,0x28,0x7e,0xd6,0xb5,0x91,0x69,0xa5,0x8a,0x1a,0x1f,0x97,0x98,0x46,
1280 0x9d,0xdf,0x12,0xf6,0x45,0x62,0xad,0x60,0xb6,0xba,0xb0,0xfd,0xf5,0x9f,0xc6,
1281 0x98,0x05,0x4f,0x4d,0x48,0xdc,0xee,0x69,0xbe,0xb8,0xc4,0xc4,0xd7,0x1b,0xb1,
1282 0x1f,0x64,0xd6,0x45,0xa7,0xdb,0xb3,0x87,0x63,0x0f,0x54,0xe1,0x3a,0x6b,0x57,
1283 0x36,0xd7,0x68,0x65,0xcf,0xda,0x57,0x8d,0xcd,0x84,0x75,0x47,0x26,0x2c,0xef,
1284 0x1e,0x8f,0xc7,0x3b,0xee,0x5d,0x03,0xa6,0xdf,0x3a,0x20,0xb2,0xcc,0xc9,0x09,
1285 0x2c,0xfe,0x2b,0x79,0xb0,0xca,0x2c,0x9a,0x81,0x6b };
1286 static const BYTE chain7_1[] = {
1287 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
1288 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,
1289 0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,
1290 0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,
1291 0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,
1292 0x35,0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,
1293 0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,
1294 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,
1295 0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,
1296 0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,
1297 0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,
1298 0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,
1299 0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,
1300 0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,
1301 0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,
1302 0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,
1303 0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,
1304 0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1305 0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9f,0x69,0xfd,0x26,0xd5,0x4b,
1306 0xe0,0xab,0x12,0x21,0xb9,0xfc,0xf7,0xe0,0x0c,0x09,0x94,0xad,0x27,0xd7,0x9d,
1307 0xa3,0xcc,0x46,0x2a,0x25,0x9a,0x24,0xa7,0x31,0x58,0x78,0xf5,0xfc,0x30,0xe1,
1308 0x6d,0xfd,0x59,0xab,0xbe,0x69,0xa0,0xea,0xe3,0x7d,0x7a,0x7b,0xe5,0x85,0xeb,
1309 0x86,0x6a,0x84,0x3c,0x96,0x01,0x1a,0x70,0xa7,0xb8,0xcb,0xf2,0x11,0xe7,0x52,
1310 0x9c,0x58,0x2d,0xac,0x63,0xce,0x72,0x4b,0xad,0x62,0xa8,0x1d,0x75,0x96,0xe2,
1311 0x27,0xf5,0x6f,0xba,0x91,0xf8,0xf1,0xb0,0xbf,0x90,0x24,0x6d,0xba,0x5d,0xd7,
1312 0x39,0x63,0x3b,0x7c,0x04,0x5d,0x89,0x9d,0x1c,0xf2,0xf7,0xcc,0xdf,0x6e,0x8a,
1313 0x43,0xa9,0xdd,0x86,0x05,0xa2,0xf3,0x22,0x2d,0x1e,0x70,0xa1,0x59,0xd7,0xa5,
1316 static void testGetIssuerCert(void)
1319 PCCERT_CONTEXT parent, child, cert1, cert2;
1320 DWORD flags = 0xffffffff;
1321 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1322 CERT_STORE_CREATE_NEW_FLAG, NULL);
1324 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1326 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1327 expiredCert, sizeof(expiredCert), CERT_STORE_ADD_ALWAYS, NULL);
1328 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1331 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1332 childOfExpired, sizeof(childOfExpired), CERT_STORE_ADD_ALWAYS, &child);
1333 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1337 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, NULL);
1338 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, NULL);
1340 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, &flags);
1341 ok(!parent && GetLastError() == E_INVALIDARG,
1342 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1343 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, &flags);
1344 ok(!parent && GetLastError() == E_INVALIDARG,
1345 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1346 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1347 ok(!parent && GetLastError() == E_INVALIDARG,
1348 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1349 /* Confusing: the caller cannot set either of the
1350 * CERT_STORE_NO_*_FLAGs, as these are not checks,
1353 flags = CERT_STORE_NO_CRL_FLAG | CERT_STORE_NO_ISSUER_FLAG;
1354 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1355 ok(!parent && GetLastError() == E_INVALIDARG,
1356 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1357 /* Perform no checks */
1359 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1360 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1363 CertFreeCertificateContext(parent);
1364 /* Check revocation and signature only */
1365 flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG;
1366 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1367 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1369 /* Confusing: CERT_STORE_REVOCATION_FLAG succeeds when there is no CRL by
1370 * setting CERT_STORE_NO_CRL_FLAG.
1372 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
1373 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
1376 CertFreeCertificateContext(parent);
1377 /* Now check just the time */
1378 flags = CERT_STORE_TIME_VALIDITY_FLAG;
1379 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1380 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1382 /* Oops: the child is not expired, so the time validity check actually
1383 * succeeds, even though the signing cert is expired.
1385 ok(!flags, "Expected check to succeed, got %08x\n", flags);
1387 CertFreeCertificateContext(parent);
1389 CertFreeCertificateContext(child);
1390 CertCloseStore(store, 0);
1393 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1394 CERT_STORE_CREATE_NEW_FLAG, NULL);
1395 /* With only the child certificate, no issuer will be found */
1396 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1397 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1398 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1399 ok(parent == NULL, "Expected no issuer\n");
1400 /* Adding an issuer allows one (and only one) issuer to be found */
1401 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1402 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert1);
1403 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1404 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1405 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1406 ok(parent == NULL, "Expected only one issuer\n");
1407 /* Adding a second issuer allows two issuers to be found - and the second
1408 * issuer is found before the first, implying certs are added to the head
1411 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1412 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert2);
1413 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1414 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1415 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1416 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1417 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1418 ok(parent == NULL, "Expected no more than two issuers\n");
1419 CertFreeCertificateContext(child);
1420 CertFreeCertificateContext(cert1);
1421 CertFreeCertificateContext(cert2);
1422 CertCloseStore(store, 0);
1424 /* Repeat the test, reversing the order in which issuers are added,
1425 * to show it's order-dependent.
1427 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1428 CERT_STORE_CREATE_NEW_FLAG, NULL);
1429 /* With only the child certificate, no issuer will be found */
1430 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1431 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1432 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1433 ok(parent == NULL, "Expected no issuer\n");
1434 /* Adding an issuer allows one (and only one) issuer to be found */
1435 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1436 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert1);
1437 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1438 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1439 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1440 ok(parent == NULL, "Expected only one issuer\n");
1441 /* Adding a second issuer allows two issuers to be found - and the second
1442 * issuer is found before the first, implying certs are added to the head
1445 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1446 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert2);
1447 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1448 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1449 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1450 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1451 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1452 ok(parent == NULL, "Expected no more than two issuers\n");
1453 CertFreeCertificateContext(child);
1454 CertFreeCertificateContext(cert1);
1455 CertFreeCertificateContext(cert2);
1456 CertCloseStore(store, 0);
1459 static void testCryptHashCert(void)
1461 static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b,
1462 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07,
1464 static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee,
1465 0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8,
1467 static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:";
1470 DWORD hashLen = sizeof(hash);
1472 /* NULL buffer and nonzero length crashes
1473 ret = CryptHashCertificate(0, 0, 0, NULL, size, hash, &hashLen);
1474 empty hash length also crashes
1475 ret = CryptHashCertificate(0, 0, 0, buf, size, hash, NULL);
1477 /* Test empty hash */
1478 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), NULL,
1480 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1481 ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen);
1482 /* Test with empty buffer */
1483 ret = CryptHashCertificate(0, 0, 0, NULL, 0, hash, &hashLen);
1484 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1485 ok(!memcmp(hash, emptyHash, sizeof(emptyHash)),
1486 "Unexpected hash of nothing\n");
1487 /* Test a known value */
1488 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), hash,
1490 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1491 ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
1494 static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen,
1495 const BYTE *sig, unsigned int sigLen)
1498 BOOL ret = CryptCreateHash(csp, CALG_SHA1, 0, 0, &hash);
1500 ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
1504 DWORD mySigSize = sizeof(mySig);
1506 ret = CryptHashData(hash, toSign, toSignLen, 0);
1507 ok(ret, "CryptHashData failed: %08x\n", GetLastError());
1508 /* use the A variant so the test can run on Win9x */
1509 ret = CryptSignHashA(hash, AT_SIGNATURE, NULL, 0, mySig, &mySigSize);
1510 ok(ret, "CryptSignHash failed: %08x\n", GetLastError());
1513 ok(mySigSize == sigLen, "Expected sig length %d, got %d\n",
1515 ok(!memcmp(mySig, sig, sigLen), "Unexpected signature\n");
1517 CryptDestroyHash(hash);
1521 /* Tests signing the certificate described by toBeSigned with the CSP passed in,
1522 * using the algorithm with OID sigOID. The CSP is assumed to be empty, and a
1523 * keyset named AT_SIGNATURE will be added to it. The signing key will be
1524 * stored in *key, and the signature will be stored in sig. sigLen should be
1525 * at least 64 bytes.
1527 static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1528 LPCSTR sigOID, HCRYPTKEY *key, BYTE *sig, DWORD *sigLen)
1532 CRYPT_ALGORITHM_IDENTIFIER algoID = { NULL, { 0, NULL } };
1535 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1536 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, &size);
1537 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1538 NULL, NULL, NULL, &size);
1540 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1541 &algoID, NULL, NULL, &size);
1542 ok(!ret && GetLastError() == NTE_BAD_ALGID,
1543 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1544 algoID.pszObjId = (LPSTR)sigOID;
1545 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1546 &algoID, NULL, NULL, &size);
1547 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1548 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1549 ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData,
1550 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1551 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1552 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1554 /* No keys exist in the new CSP yet.. */
1555 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1556 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1557 ok(!ret && (GetLastError() == NTE_BAD_KEYSET || GetLastError() ==
1558 NTE_NO_KEY), "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %08x\n",
1560 ret = CryptGenKey(csp, AT_SIGNATURE, 0, key);
1561 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1564 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1565 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1566 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1567 ok(size <= *sigLen, "Expected size <= %d, got %d\n", *sigLen, size);
1570 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1571 toBeSigned->cbData, &algoID, NULL, sig, &size);
1572 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1576 verifySig(csp, toBeSigned->pbData, toBeSigned->cbData, sig,
1583 static void testVerifyCertSig(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1584 LPCSTR sigOID, const BYTE *sig, DWORD sigLen)
1586 CERT_SIGNED_CONTENT_INFO info;
1591 if (!pCryptVerifyCertificateSignatureEx)
1593 skip("no CryptVerifyCertificateSignatureEx support\n");
1596 ret = pCryptVerifyCertificateSignatureEx(0, 0, 0, NULL, 0, NULL, 0, NULL);
1597 ok(!ret && GetLastError() == E_INVALIDARG,
1598 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1599 ret = pCryptVerifyCertificateSignatureEx(csp, 0, 0, NULL, 0, NULL, 0, NULL);
1600 ok(!ret && GetLastError() == E_INVALIDARG,
1601 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1602 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 0, NULL, 0,
1604 ok(!ret && GetLastError() == E_INVALIDARG,
1605 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1607 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1608 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, NULL, 0, NULL, 0, NULL);
1610 info.ToBeSigned.cbData = toBeSigned->cbData;
1611 info.ToBeSigned.pbData = toBeSigned->pbData;
1612 info.SignatureAlgorithm.pszObjId = (LPSTR)sigOID;
1613 info.SignatureAlgorithm.Parameters.cbData = 0;
1614 info.Signature.cbData = sigLen;
1615 info.Signature.pbData = (BYTE *)sig;
1616 info.Signature.cUnusedBits = 0;
1617 ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT, &info,
1618 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&cert, &size);
1619 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1622 CRYPT_DATA_BLOB certBlob = { 0, NULL };
1623 PCERT_PUBLIC_KEY_INFO pubKeyInfo = NULL;
1625 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1626 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1627 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
1628 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
1629 certBlob.cbData = 1;
1630 certBlob.pbData = (void *)0xdeadbeef;
1631 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1632 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1633 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1634 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1635 certBlob.cbData = size;
1636 certBlob.pbData = cert;
1637 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1638 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1639 ok(!ret && GetLastError() == E_INVALIDARG,
1640 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1641 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1642 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1643 CRYPT_VERIFY_CERT_SIGN_ISSUER_NULL, NULL, 0, NULL);
1644 ok(!ret && GetLastError() == E_INVALIDARG,
1645 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1647 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1648 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1649 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, NULL, 0, NULL);
1651 CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
1652 (LPSTR)sigOID, 0, NULL, NULL, &size);
1653 pubKeyInfo = HeapAlloc(GetProcessHeap(), 0, size);
1656 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
1657 X509_ASN_ENCODING, (LPSTR)sigOID, 0, NULL, pubKeyInfo, &size);
1658 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
1661 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1662 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1663 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pubKeyInfo, 0, NULL);
1664 ok(ret, "CryptVerifyCertificateSignatureEx failed: %08x\n",
1667 HeapFree(GetProcessHeap(), 0, pubKeyInfo);
1673 static BYTE emptyCert[] = { 0x30, 0x00 };
1675 static void testCertSigs(void)
1678 CRYPT_DATA_BLOB toBeSigned = { sizeof(emptyCert), emptyCert };
1682 DWORD sigSize = sizeof(sig);
1684 /* Just in case a previous run failed, delete this thing */
1685 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1686 CRYPT_DELETEKEYSET);
1687 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1689 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1691 testSignCert(csp, &toBeSigned, szOID_RSA_SHA1RSA, &key, sig, &sigSize);
1692 testVerifyCertSig(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize);
1694 CryptDestroyKey(key);
1695 CryptReleaseContext(csp, 0);
1696 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1697 CRYPT_DELETEKEYSET);
1700 static const BYTE md5SignedEmptyCert[] = {
1701 0x30,0x56,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1702 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
1703 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
1704 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1705 0x0d,0x02,0x05,0x05,0x00,0x03,0x11,0x00,0xfb,0x0f,0x66,0x82,0x66,0xd9,0xe5,0xf8,
1706 0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
1707 static const BYTE md5SignedEmptyCertNoNull[] = {
1708 0x30,0x54,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1709 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
1710 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
1711 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1712 0x0d,0x02,0x05,0x03,0x11,0x00,0x04,0xd9,0xa5,0xe1,0x2b,0x55,0xa2,0xd8,0xf8,0xe5,
1713 0xd9,0x66,0x82,0x66,0x0f,0xfb };
1715 static void testSignAndEncodeCert(void)
1717 static char oid_rsa_md5rsa[] = szOID_RSA_MD5RSA;
1718 static char oid_rsa_md5[] = szOID_RSA_MD5;
1721 CRYPT_ALGORITHM_IDENTIFIER algID = { 0 };
1722 CERT_INFO info = { 0 };
1725 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1727 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1730 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, &algID, NULL, NULL,
1732 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1733 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1734 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, NULL, NULL,
1735 &algID, NULL, NULL, &size);
1736 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1737 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1738 ret = CryptSignAndEncodeCertificate(0, 0, 0, X509_CERT_TO_BE_SIGNED, NULL,
1739 &algID, NULL, NULL, &size);
1740 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1741 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1742 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1743 X509_CERT_TO_BE_SIGNED, NULL, &algID, NULL, NULL, &size);
1744 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1745 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1747 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1748 X509_CERT_TO_BE_SIGNED, &info, NULL, NULL, NULL, &size);
1750 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1751 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1752 ok(!ret && GetLastError() == NTE_BAD_ALGID,
1753 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1754 algID.pszObjId = oid_rsa_md5rsa;
1755 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1756 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1757 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1758 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1759 algID.pszObjId = oid_rsa_md5;
1760 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1761 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1762 ok(ret, "CryptSignAndEncodeCertificate failed: %08x\n", GetLastError());
1765 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
1769 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1770 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, buf, &size);
1771 ok(ret, "CryptSignAndEncodeCertificate failed: %08x\n",
1773 /* Tricky: because the NULL parameters may either be omitted or
1774 * included as an asn.1-encoded NULL (0x05,0x00), two different
1775 * values are allowed.
1777 ok(size == sizeof(md5SignedEmptyCert) ||
1778 size == sizeof(md5SignedEmptyCertNoNull), "Unexpected size %d\n",
1780 if (size == sizeof(md5SignedEmptyCert))
1781 ok(!memcmp(buf, md5SignedEmptyCert, size),
1782 "Unexpected value\n");
1783 else if (size == sizeof(md5SignedEmptyCertNoNull))
1784 ok(!memcmp(buf, md5SignedEmptyCertNoNull, size),
1785 "Unexpected value\n");
1786 HeapFree(GetProcessHeap(), 0, buf);
1791 static void testCreateSelfSignCert(void)
1793 PCCERT_CONTEXT context;
1794 CERT_NAME_BLOB name = { sizeof(subjectName), subjectName };
1798 CRYPT_KEY_PROV_INFO info;
1801 context = CertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL,
1803 * Calling this with no first parameter creates a new key container, which
1804 * lasts beyond the test, so I don't test that. Nb: the generated key
1806 context = CertCreateSelfSignCertificate(0, &name, 0, NULL, NULL, NULL, NULL,
1811 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1812 CRYPT_DELETEKEYSET);
1813 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1815 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1817 context = CertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1819 ok(!context && GetLastError() == NTE_NO_KEY,
1820 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1821 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
1822 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1825 context = CertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1827 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1832 PCRYPT_KEY_PROV_INFO info;
1834 /* The context must have a key provider info property */
1835 ret = CertGetCertificateContextProperty(context,
1836 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1837 ok(ret && size, "Expected non-zero key provider info\n");
1840 info = HeapAlloc(GetProcessHeap(), 0, size);
1843 ret = CertGetCertificateContextProperty(context,
1844 CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1845 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1849 /* Sanity-check the key provider */
1850 ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1851 "Unexpected key container\n");
1852 ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1853 "Unexpected provider\n");
1854 ok(info->dwKeySpec == AT_SIGNATURE,
1855 "Expected AT_SIGNATURE, got %d\n", info->dwKeySpec);
1857 HeapFree(GetProcessHeap(), 0, info);
1861 CertFreeCertificateContext(context);
1864 CryptDestroyKey(key);
1867 CryptReleaseContext(csp, 0);
1868 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1869 CRYPT_DELETEKEYSET);
1871 /* do the same test with AT_KEYEXCHANGE and key info*/
1872 memset(&info,0,sizeof(info));
1873 info.dwProvType = PROV_RSA_FULL;
1874 info.dwKeySpec = AT_KEYEXCHANGE;
1875 info.pwszProvName = (LPWSTR) MS_DEF_PROV_W;
1876 info.pwszContainerName = cspNameW;
1877 context = CertCreateSelfSignCertificate(0, &name, 0, &info, NULL, NULL,
1879 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1884 PCRYPT_KEY_PROV_INFO info;
1886 /* The context must have a key provider info property */
1887 ret = CertGetCertificateContextProperty(context,
1888 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1889 ok(ret && size, "Expected non-zero key provider info\n");
1892 info = HeapAlloc(GetProcessHeap(), 0, size);
1895 ret = CertGetCertificateContextProperty(context,
1896 CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1897 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1901 /* Sanity-check the key provider */
1902 ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1903 "Unexpected key container\n");
1904 ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1905 "Unexpected provider\n");
1906 ok(info->dwKeySpec == AT_KEYEXCHANGE,
1907 "Expected AT_KEYEXCHANGE, got %d\n", info->dwKeySpec);
1909 HeapFree(GetProcessHeap(), 0, info);
1913 CertFreeCertificateContext(context);
1916 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1917 CRYPT_DELETEKEYSET);
1920 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
1921 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
1923 static void testKeyUsage(void)
1926 PCCERT_CONTEXT context;
1929 /* Test base cases */
1930 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, NULL);
1931 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1932 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1934 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
1935 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1936 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1938 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
1939 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1940 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1942 ret = CertSetEnhancedKeyUsage(NULL, NULL);
1943 usage.cUsageIdentifier = 0;
1944 ret = CertSetEnhancedKeyUsage(NULL, &usage);
1946 /* Test with a cert with no enhanced key usage extension */
1947 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
1949 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
1953 static const char oid[] = "1.2.3.4";
1954 BYTE buf[sizeof(CERT_ENHKEY_USAGE) + 2 * (sizeof(LPSTR) + sizeof(oid))];
1955 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
1957 ret = CertGetEnhancedKeyUsage(context, 0, NULL, NULL);
1958 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1959 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1961 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &size);
1964 /* Windows 2000, ME, or later: even though it succeeded, we expect
1965 * CRYPT_E_NOT_FOUND, which indicates there is no enhanced key
1966 * usage set for this cert (which implies it's valid for all uses.)
1968 ok(GetLastError() == CRYPT_E_NOT_FOUND,
1969 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1970 ok(size == sizeof(CERT_ENHKEY_USAGE), "Wrong size %d\n", size);
1971 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
1972 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
1973 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
1974 pUsage->cUsageIdentifier);
1978 /* Windows NT, 95, or 98: it fails, and the last error is
1979 * CRYPT_E_NOT_FOUND.
1981 ok(GetLastError() == CRYPT_E_NOT_FOUND,
1982 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1984 /* I can add a usage identifier when no key usage has been set */
1985 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
1986 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
1989 ret = CertGetEnhancedKeyUsage(context,
1990 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
1991 ok(ret && GetLastError() == 0,
1992 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
1993 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
1994 pUsage->cUsageIdentifier);
1995 if (pUsage->cUsageIdentifier)
1996 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
1997 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
1998 /* Now set an empty key usage */
1999 pUsage->cUsageIdentifier = 0;
2000 ret = CertSetEnhancedKeyUsage(context, pUsage);
2001 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2002 /* Shouldn't find it in the cert */
2004 ret = CertGetEnhancedKeyUsage(context,
2005 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2006 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2007 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2008 /* Should find it as an extended property */
2009 ret = CertGetEnhancedKeyUsage(context,
2010 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2011 ok(ret && GetLastError() == 0,
2012 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2013 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2014 pUsage->cUsageIdentifier);
2015 /* Should find it as either */
2016 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2017 ok(ret && GetLastError() == 0,
2018 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2019 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2020 pUsage->cUsageIdentifier);
2021 /* Add a usage identifier */
2022 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2023 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2026 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2027 ok(ret && GetLastError() == 0,
2028 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2029 ok(pUsage->cUsageIdentifier == 1, "Expected 1 identifier, got %d\n",
2030 pUsage->cUsageIdentifier);
2031 if (pUsage->cUsageIdentifier)
2032 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2033 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2034 /* Yep, I can re-add the same usage identifier */
2035 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2036 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2039 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2040 ok(ret && GetLastError() == 0,
2041 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2042 ok(pUsage->cUsageIdentifier == 2, "Expected 2 identifiers, got %d\n",
2043 pUsage->cUsageIdentifier);
2044 if (pUsage->cUsageIdentifier)
2045 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2046 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2047 if (pUsage->cUsageIdentifier >= 2)
2048 ok(!strcmp(pUsage->rgpszUsageIdentifier[1], oid),
2049 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[1]);
2050 /* Now set a NULL extended property--this deletes the property. */
2051 ret = CertSetEnhancedKeyUsage(context, NULL);
2052 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2053 SetLastError(0xbaadcafe);
2055 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2056 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2057 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2059 CertFreeCertificateContext(context);
2061 /* Now test with a cert with an enhanced key usage extension */
2062 context = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2063 sizeof(certWithUsage));
2064 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2069 DWORD bufSize = 0, i;
2071 /* The size may depend on what flags are used to query it, so I
2072 * realloc the buffer for each test.
2074 ret = CertGetEnhancedKeyUsage(context,
2075 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2076 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2077 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2080 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2082 /* Should find it in the cert */
2084 ret = CertGetEnhancedKeyUsage(context,
2085 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2086 ok(ret && GetLastError() == 0,
2087 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2088 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2089 pUsage->cUsageIdentifier);
2090 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2091 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2092 "Expected %s, got %s\n", keyUsages[i],
2093 pUsage->rgpszUsageIdentifier[i]);
2094 HeapFree(GetProcessHeap(), 0, buf);
2096 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2097 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2098 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2101 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2103 /* Should find it as either */
2105 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2106 /* In Windows, GetLastError returns CRYPT_E_NOT_FOUND not found
2107 * here, even though the return is successful and the usage id
2108 * count is positive. I don't enforce that here.
2111 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2112 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2113 pUsage->cUsageIdentifier);
2114 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2115 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2116 "Expected %s, got %s\n", keyUsages[i],
2117 pUsage->rgpszUsageIdentifier[i]);
2118 HeapFree(GetProcessHeap(), 0, buf);
2120 /* Shouldn't find it as an extended property */
2121 ret = CertGetEnhancedKeyUsage(context,
2122 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &size);
2123 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2124 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2125 /* Adding a usage identifier overrides the cert's usage!? */
2126 ret = CertAddEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2127 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2129 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2130 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2131 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2134 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2136 /* Should find it as either */
2138 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2140 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2141 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2142 pUsage->cUsageIdentifier);
2143 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], szOID_RSA_RSA),
2144 "Expected %s, got %s\n", szOID_RSA_RSA,
2145 pUsage->rgpszUsageIdentifier[0]);
2146 HeapFree(GetProcessHeap(), 0, buf);
2148 /* But querying the cert directly returns its usage */
2149 ret = CertGetEnhancedKeyUsage(context,
2150 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2151 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2152 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2155 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2158 ret = CertGetEnhancedKeyUsage(context,
2159 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2161 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2162 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2163 pUsage->cUsageIdentifier);
2164 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2165 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2166 "Expected %s, got %s\n", keyUsages[i],
2167 pUsage->rgpszUsageIdentifier[i]);
2168 HeapFree(GetProcessHeap(), 0, buf);
2170 /* And removing the only usage identifier in the extended property
2171 * results in the cert's key usage being found.
2173 ret = CertRemoveEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2174 ok(ret, "CertRemoveEnhancedKeyUsage failed: %08x\n", GetLastError());
2175 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2176 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2177 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2180 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2182 /* Should find it as either */
2184 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2186 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2187 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2188 pUsage->cUsageIdentifier);
2189 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2190 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2191 "Expected %s, got %s\n", keyUsages[i],
2192 pUsage->rgpszUsageIdentifier[i]);
2193 HeapFree(GetProcessHeap(), 0, buf);
2196 CertFreeCertificateContext(context);
2200 static const BYTE cert2WithUsage[] = {
2201 0x30,0x81,0x89,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2202 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2203 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2204 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2205 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2206 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2207 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x25,0x30,0x23,
2208 0x30,0x21,0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x17,0x30,0x15,0x06,
2209 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x2a,0x86,0x48,0x86,
2210 0xf7,0x0d,0x01,0x01,0x01 };
2212 static void testGetValidUsages(void)
2214 static const LPCSTR expectedOIDs[] = {
2215 "1.3.6.1.5.5.7.3.3",
2216 "1.3.6.1.5.5.7.3.2",
2217 "1.2.840.113549.1.1.1",
2219 static const LPCSTR expectedOIDs2[] = {
2220 "1.3.6.1.5.5.7.3.2",
2221 "1.2.840.113549.1.1.1",
2227 PCCERT_CONTEXT contexts[3];
2230 ret = CertGetValidUsages(0, NULL, NULL, NULL, NULL);
2231 ret = CertGetValidUsages(0, NULL, NULL, NULL, &size);
2234 numOIDs = size = 0xdeadbeef;
2235 SetLastError(0xdeadbeef);
2236 ret = CertGetValidUsages(1, &contexts[0], &numOIDs, NULL, &size);
2237 ok(ret, "CertGetValidUsages failed: %d\n", GetLastError());
2238 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2239 ok(size == 0, "Expected size 0, got %d\n", size);
2240 contexts[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2242 contexts[1] = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2243 sizeof(certWithUsage));
2244 contexts[2] = CertCreateCertificateContext(X509_ASN_ENCODING,
2245 cert2WithUsage, sizeof(cert2WithUsage));
2246 numOIDs = size = 0xdeadbeef;
2247 ret = CertGetValidUsages(0, NULL, &numOIDs, NULL, &size);
2248 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2249 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2250 ok(size == 0, "Expected size 0, got %d\n", size);
2251 numOIDs = size = 0xdeadbeef;
2252 ret = CertGetValidUsages(1, contexts, &numOIDs, NULL, &size);
2253 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2254 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2255 ok(size == 0, "Expected size 0, got %d\n", size);
2256 ret = CertGetValidUsages(1, &contexts[1], &numOIDs, NULL, &size);
2257 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2258 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2259 ok(size, "Expected non-zero size\n");
2260 oids = HeapAlloc(GetProcessHeap(), 0, size);
2264 DWORD smallSize = 1;
2266 SetLastError(0xdeadbeef);
2267 ret = CertGetValidUsages(1, &contexts[1], &numOIDs, oids, &smallSize);
2268 ok(!ret && GetLastError() == ERROR_MORE_DATA,
2269 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
2270 ret = CertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2271 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2272 for (i = 0; i < numOIDs; i++)
2273 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2275 HeapFree(GetProcessHeap(), 0, oids);
2277 numOIDs = size = 0xdeadbeef;
2278 /* Oddly enough, this crashes when the number of contexts is not 1:
2279 ret = CertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2280 * but setting size to 0 allows it to succeed:
2283 ret = CertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2284 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2285 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2286 ok(size, "Expected non-zero size\n");
2287 oids = HeapAlloc(GetProcessHeap(), 0, size);
2292 ret = CertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2293 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2294 for (i = 0; i < numOIDs; i++)
2295 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2297 HeapFree(GetProcessHeap(), 0, oids);
2299 numOIDs = 0xdeadbeef;
2301 ret = CertGetValidUsages(1, &contexts[2], &numOIDs, NULL, &size);
2302 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2303 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2304 ok(size, "Expected non-zero size\n");
2305 oids = HeapAlloc(GetProcessHeap(), 0, size);
2310 ret = CertGetValidUsages(1, &contexts[2], &numOIDs, oids, &size);
2311 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2312 for (i = 0; i < numOIDs; i++)
2313 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2315 HeapFree(GetProcessHeap(), 0, oids);
2317 numOIDs = 0xdeadbeef;
2319 ret = CertGetValidUsages(3, contexts, &numOIDs, NULL, &size);
2320 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2321 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2322 ok(size, "Expected non-zero size\n");
2323 oids = HeapAlloc(GetProcessHeap(), 0, size);
2328 ret = CertGetValidUsages(3, contexts, &numOIDs, oids, &size);
2329 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2330 for (i = 0; i < numOIDs; i++)
2331 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2333 HeapFree(GetProcessHeap(), 0, oids);
2335 CertFreeCertificateContext(contexts[0]);
2336 CertFreeCertificateContext(contexts[1]);
2337 CertFreeCertificateContext(contexts[2]);
2340 static void testCompareCertName(void)
2342 static BYTE bogus[] = { 1, 2, 3, 4 };
2343 static BYTE bogusPrime[] = { 0, 1, 2, 3, 4 };
2344 static BYTE emptyPrime[] = { 0x30, 0x00, 0x01 };
2346 CERT_NAME_BLOB blob1, blob2;
2349 ret = CertCompareCertificateName(0, NULL, NULL);
2351 /* An empty name checks against itself.. */
2352 blob1.pbData = emptyCert;
2353 blob1.cbData = sizeof(emptyCert);
2354 ret = CertCompareCertificateName(0, &blob1, &blob1);
2355 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2356 /* It doesn't have to be a valid encoded name.. */
2357 blob1.pbData = bogus;
2358 blob1.cbData = sizeof(bogus);
2359 ret = CertCompareCertificateName(0, &blob1, &blob1);
2360 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2361 /* Leading zeroes matter.. */
2362 blob2.pbData = bogusPrime;
2363 blob2.cbData = sizeof(bogusPrime);
2364 ret = CertCompareCertificateName(0, &blob1, &blob2);
2365 ok(!ret, "Expected failure\n");
2366 /* As do trailing extra bytes. */
2367 blob2.pbData = emptyPrime;
2368 blob2.cbData = sizeof(emptyPrime);
2369 ret = CertCompareCertificateName(0, &blob1, &blob2);
2370 ok(!ret, "Expected failure\n");
2373 static BYTE int1[] = { 0x88, 0xff, 0xff, 0xff };
2374 static BYTE int2[] = { 0x88, 0xff };
2375 static BYTE int3[] = { 0x23, 0xff };
2376 static BYTE int4[] = { 0x7f, 0x00 };
2377 static BYTE int5[] = { 0x7f };
2378 static BYTE int6[] = { 0x80, 0x00, 0x00, 0x00 };
2379 static BYTE int7[] = { 0x80, 0x00 };
2381 static struct IntBlobTest
2383 CRYPT_INTEGER_BLOB blob1;
2384 CRYPT_INTEGER_BLOB blob2;
2387 { { sizeof(int1), int1 }, { sizeof(int2), int2 }, TRUE },
2388 { { sizeof(int3), int3 }, { sizeof(int3), int3 }, TRUE },
2389 { { sizeof(int4), int4 }, { sizeof(int5), int5 }, TRUE },
2390 { { sizeof(int6), int6 }, { sizeof(int7), int7 }, TRUE },
2391 { { sizeof(int1), int1 }, { sizeof(int7), int7 }, FALSE },
2394 static void testCompareIntegerBlob(void)
2399 for (i = 0; i < sizeof(intBlobs) / sizeof(intBlobs[0]); i++)
2401 ret = CertCompareIntegerBlob(&intBlobs[i].blob1, &intBlobs[i].blob2);
2402 ok(ret == intBlobs[i].areEqual,
2403 "%d: expected blobs %s compare\n", i, intBlobs[i].areEqual ?
2408 static void testComparePublicKeyInfo(void)
2411 CERT_PUBLIC_KEY_INFO info1 = { { 0 } }, info2 = { { 0 } };
2412 static CHAR oid_rsa_rsa[] = szOID_RSA_RSA;
2413 static CHAR oid_rsa_sha1rsa[] = szOID_RSA_SHA1RSA;
2414 static CHAR oid_x957_dsa[] = szOID_X957_DSA;
2415 static BYTE bits1[] = { 1, 0 };
2416 static BYTE bits2[] = { 0 };
2417 static BYTE bits3[] = { 1 };
2420 ret = CertComparePublicKeyInfo(0, NULL, NULL);
2422 /* Empty public keys compare */
2423 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2424 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2425 /* Different OIDs appear to compare */
2426 info1.Algorithm.pszObjId = oid_rsa_rsa;
2427 info2.Algorithm.pszObjId = oid_rsa_sha1rsa;
2428 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2429 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2430 info2.Algorithm.pszObjId = oid_x957_dsa;
2431 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2432 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2433 info1.PublicKey.cbData = sizeof(bits1);
2434 info1.PublicKey.pbData = bits1;
2435 info1.PublicKey.cUnusedBits = 0;
2436 info2.PublicKey.cbData = sizeof(bits1);
2437 info2.PublicKey.pbData = bits1;
2438 info2.PublicKey.cUnusedBits = 0;
2439 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2440 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2441 /* Even though they compare in their used bits, these do not compare */
2442 info1.PublicKey.cbData = sizeof(bits2);
2443 info1.PublicKey.pbData = bits2;
2444 info1.PublicKey.cUnusedBits = 0;
2445 info2.PublicKey.cbData = sizeof(bits3);
2446 info2.PublicKey.pbData = bits3;
2447 info2.PublicKey.cUnusedBits = 1;
2448 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2449 /* Simple (non-comparing) case */
2450 ok(!ret, "Expected keys not to compare\n");
2451 info2.PublicKey.cbData = sizeof(bits1);
2452 info2.PublicKey.pbData = bits1;
2453 info2.PublicKey.cUnusedBits = 0;
2454 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2455 ok(!ret, "Expected keys not to compare\n");
2458 static void testHashPublicKeyInfo(void)
2461 CERT_PUBLIC_KEY_INFO info = { { 0 } };
2465 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, NULL);
2466 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, &info, NULL, NULL);
2468 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, &len);
2469 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2470 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2471 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, NULL, NULL, &len);
2472 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2473 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2474 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, NULL, &len);
2475 ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2476 ok(len == 16, "Expected hash size 16, got %d\n", len);
2479 static const BYTE emptyHash[] = { 0xb8,0x51,0x3a,0x31,0x0e,0x9f,0x40,
2480 0x36,0x9c,0x92,0x45,0x1b,0x9d,0xc8,0xf9,0xf6 };
2483 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, buf,
2485 ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2486 ok(!memcmp(buf, emptyHash, len), "Unexpected hash\n");
2490 static void testCompareCert(void)
2492 CERT_INFO info1 = { 0 }, info2 = { 0 };
2496 ret = CertCompareCertificate(X509_ASN_ENCODING, NULL, NULL);
2499 /* Certs with the same issuer and serial number are equal, even if they
2500 * differ in other respects (like subject).
2502 info1.SerialNumber.pbData = serialNum;
2503 info1.SerialNumber.cbData = sizeof(serialNum);
2504 info1.Issuer.pbData = subjectName;
2505 info1.Issuer.cbData = sizeof(subjectName);
2506 info1.Subject.pbData = subjectName2;
2507 info1.Subject.cbData = sizeof(subjectName2);
2508 info2.SerialNumber.pbData = serialNum;
2509 info2.SerialNumber.cbData = sizeof(serialNum);
2510 info2.Issuer.pbData = subjectName;
2511 info2.Issuer.cbData = sizeof(subjectName);
2512 info2.Subject.pbData = subjectName;
2513 info2.Subject.cbData = sizeof(subjectName);
2514 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2515 ok(ret, "Expected certs to be equal\n");
2517 info2.Issuer.pbData = subjectName2;
2518 info2.Issuer.cbData = sizeof(subjectName2);
2519 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2520 ok(!ret, "Expected certs not to be equal\n");
2523 static void testVerifySubjectCert(void)
2527 PCCERT_CONTEXT context1, context2;
2530 ret = CertVerifySubjectCertificateContext(NULL, NULL, NULL);
2533 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2534 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2536 flags = CERT_STORE_NO_CRL_FLAG;
2537 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2538 ok(!ret && GetLastError() == E_INVALIDARG,
2539 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2542 context1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2544 ret = CertVerifySubjectCertificateContext(NULL, context1, &flags);
2545 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2547 ret = CertVerifySubjectCertificateContext(context1, NULL, &flags);
2548 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2550 ret = CertVerifySubjectCertificateContext(context1, context1, &flags);
2551 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2554 context2 = CertCreateCertificateContext(X509_ASN_ENCODING,
2555 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject));
2556 SetLastError(0xdeadbeef);
2557 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2558 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2560 flags = CERT_STORE_REVOCATION_FLAG;
2561 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2562 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2564 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
2565 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
2567 flags = CERT_STORE_SIGNATURE_FLAG;
2568 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2569 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2571 ok(flags == CERT_STORE_SIGNATURE_FLAG,
2572 "Expected CERT_STORE_SIGNATURE_FLAG, got %08x\n", flags);
2573 CertFreeCertificateContext(context2);
2575 CertFreeCertificateContext(context1);
2578 static void testVerifyRevocation(void)
2581 CERT_REVOCATION_STATUS status = { 0 };
2582 PCCERT_CONTEXT cert = CertCreateCertificateContext(X509_ASN_ENCODING,
2583 bigCert, sizeof(bigCert));
2586 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL);
2588 SetLastError(0xdeadbeef);
2589 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2590 ok(!ret && GetLastError() == E_INVALIDARG,
2591 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2592 status.cbSize = sizeof(status);
2593 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2594 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2595 ret = CertVerifyRevocation(0, 2, 0, NULL, 0, NULL, &status);
2596 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2597 ret = CertVerifyRevocation(2, 0, 0, NULL, 0, NULL, &status);
2598 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2599 SetLastError(0xdeadbeef);
2600 ret = CertVerifyRevocation(0, 0, 1, (void **)&cert, 0, NULL, &status);
2601 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2602 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2603 SetLastError(0xdeadbeef);
2604 ret = CertVerifyRevocation(0, 2, 1, (void **)&cert, 0, NULL, &status);
2605 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2606 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2608 CertFreeCertificateContext(cert);
2611 static BYTE privKey[] = {
2612 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
2613 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
2614 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
2615 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
2616 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
2617 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
2618 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
2619 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
2620 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
2621 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
2622 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
2623 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
2624 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
2625 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
2626 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
2627 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
2628 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
2629 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
2630 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
2631 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
2632 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
2633 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
2634 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
2635 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
2637 static const BYTE selfSignedCert[] = {
2638 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2639 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
2640 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
2641 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
2642 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
2643 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
2644 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
2645 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
2646 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
2647 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
2648 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
2649 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
2650 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
2651 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
2652 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
2653 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
2654 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
2655 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
2656 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
2657 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
2658 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
2659 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
2660 0xa8, 0x76, 0x57, 0x92, 0x36 };
2662 static const BYTE exportedPublicKeyBlob[] = {
2663 0x06,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x31,0x00,0x02,0x00,0x00,
2664 0x01,0x00,0x01,0x00,0x79,0x10,0x1c,0xd0,0x6b,0x10,0x18,0x30,0x94,0x61,0xdc,0x0e,
2665 0xcb,0x96,0x4e,0x21,0x3f,0x79,0xcd,0xa9,0x17,0x62,0xbc,0xbb,0x61,0x4c,0xe0,0x75,
2666 0x38,0x6c,0xf3,0xde,0x60,0x86,0x03,0x97,0x65,0xeb,0x1e,0x6b,0xdb,0x53,0x85,0xad,
2667 0x68,0x21,0xf1,0x5d,0xe7,0x1f,0xe6,0x53,0xb4,0xbb,0x59,0x3e,0x14,0x27,0xb1,0x83,
2668 0xa7,0x3a,0x54,0xe2 };
2670 static const BYTE asnEncodedPublicKey[] = {
2671 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,
2672 0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
2673 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,
2674 0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
2675 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
2677 static void testAcquireCertPrivateKey(void)
2680 PCCERT_CONTEXT cert;
2682 DWORD size, keySpec;
2684 CRYPT_KEY_PROV_INFO keyProvInfo;
2686 WCHAR ms_def_prov_w[MAX_PATH];
2688 lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
2690 keyProvInfo.pwszContainerName = cspNameW;
2691 keyProvInfo.pwszProvName = ms_def_prov_w;
2692 keyProvInfo.dwProvType = PROV_RSA_FULL;
2693 keyProvInfo.dwFlags = 0;
2694 keyProvInfo.cProvParam = 0;
2695 keyProvInfo.rgProvParam = NULL;
2696 keyProvInfo.dwKeySpec = AT_SIGNATURE;
2698 pCryptAcquireContextW(NULL, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
2699 CRYPT_DELETEKEYSET);
2701 cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
2702 sizeof(selfSignedCert));
2705 ret = CryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL, NULL);
2706 ret = CryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL,
2708 ret = CryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, &keySpec,
2710 ret = CryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, NULL, NULL);
2711 ret = CryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, &keySpec,
2713 ret = CryptAcquireCertificatePrivateKey(cert, 0, NULL, NULL, NULL, NULL);
2716 /* Missing private key */
2717 ret = CryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, NULL, NULL);
2718 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2719 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2720 ret = CryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2722 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2723 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2724 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2726 ret = CryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2728 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2729 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2731 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
2733 ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
2734 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
2739 CERT_KEY_CONTEXT keyContext;
2741 /* Don't cache provider */
2742 ret = CryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2743 &keySpec, &callerFree);
2744 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2746 ok(callerFree, "Expected callerFree to be TRUE\n");
2747 CryptReleaseContext(certCSP, 0);
2748 ret = CryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2750 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2752 CryptReleaseContext(certCSP, 0);
2754 /* Use the key prov info's caching (there shouldn't be any) */
2755 ret = CryptAcquireCertificatePrivateKey(cert,
2756 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2758 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2760 ok(callerFree, "Expected callerFree to be TRUE\n");
2761 CryptReleaseContext(certCSP, 0);
2763 /* Cache it (and check that it's cached) */
2764 ret = CryptAcquireCertificatePrivateKey(cert,
2765 CRYPT_ACQUIRE_CACHE_FLAG, NULL, &certCSP, &keySpec, &callerFree);
2766 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2768 ok(!callerFree, "Expected callerFree to be FALSE\n");
2769 size = sizeof(keyContext);
2770 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2771 &keyContext, &size);
2772 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2775 /* Remove the cached provider */
2776 CryptReleaseContext(keyContext.hCryptProv, 0);
2777 CertSetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID, 0,
2779 /* Allow caching via the key prov info */
2780 keyProvInfo.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
2781 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2783 /* Now use the key prov info's caching */
2784 ret = CryptAcquireCertificatePrivateKey(cert,
2785 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2787 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2789 ok(!callerFree, "Expected callerFree to be FALSE\n");
2790 size = sizeof(keyContext);
2791 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2792 &keyContext, &size);
2793 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2796 CryptDestroyKey(key);
2799 /* Some sanity-checking on public key exporting */
2800 ret = CryptImportPublicKeyInfo(csp, X509_ASN_ENCODING,
2801 &cert->pCertInfo->SubjectPublicKeyInfo, &key);
2802 ok(ret, "CryptImportPublicKeyInfo failed: %08x\n", GetLastError());
2805 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, NULL, &size);
2806 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
2809 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size), encodedKey;
2811 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, buf, &size);
2812 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
2813 ok(size == sizeof(exportedPublicKeyBlob), "Unexpected size %d\n",
2815 ok(!memcmp(buf, exportedPublicKeyBlob, size), "Unexpected value\n");
2816 ret = CryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB,
2817 buf, CRYPT_ENCODE_ALLOC_FLAG, NULL, &encodedKey, &size);
2818 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2821 ok(size == sizeof(asnEncodedPublicKey), "Unexpected size %d\n",
2823 ok(!memcmp(encodedKey, asnEncodedPublicKey, size),
2824 "Unexpected value\n");
2825 LocalFree(encodedKey);
2827 HeapFree(GetProcessHeap(), 0, buf);
2829 CryptDestroyKey(key);
2831 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
2832 NULL, 0, NULL, NULL, &size);
2833 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
2836 PCERT_PUBLIC_KEY_INFO info = HeapAlloc(GetProcessHeap(), 0, size);
2838 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
2839 NULL, 0, NULL, info, &size);
2840 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
2843 ok(info->PublicKey.cbData == sizeof(asnEncodedPublicKey),
2844 "Unexpected size %d\n", info->PublicKey.cbData);
2845 ok(!memcmp(info->PublicKey.pbData, asnEncodedPublicKey,
2846 info->PublicKey.cbData), "Unexpected value\n");
2848 HeapFree(GetProcessHeap(), 0, info);
2851 CryptReleaseContext(csp, 0);
2852 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
2853 CRYPT_DELETEKEYSET);
2855 CertFreeCertificateContext(cert);
2858 static void testGetPublicKeyLength(void)
2860 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2861 static char oid_rsa_dh[] = szOID_RSA_DH;
2862 static char bogusOID[] = "1.2.3";
2864 CERT_PUBLIC_KEY_INFO info = { { 0 } };
2865 BYTE bogusKey[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
2866 BYTE key[] = { 0x30,0x0f,0x02,0x08,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2867 0x02,0x03,0x01,0x00,0x01 };
2870 ret = CertGetPublicKeyLength(0, NULL);
2872 /* With an empty public key info */
2873 SetLastError(0xdeadbeef);
2874 ret = CertGetPublicKeyLength(0, &info);
2875 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
2876 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
2877 ret, GetLastError());
2878 SetLastError(0xdeadbeef);
2879 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2880 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_EOD,
2881 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
2882 ret, GetLastError());
2883 /* With a nearly-empty public key info */
2884 info.Algorithm.pszObjId = oid_rsa_rsa;
2885 SetLastError(0xdeadbeef);
2886 ret = CertGetPublicKeyLength(0, &info);
2887 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
2888 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
2889 ret, GetLastError());
2890 SetLastError(0xdeadbeef);
2891 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2892 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_EOD,
2893 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
2894 ret, GetLastError());
2895 /* With a bogus key */
2896 info.PublicKey.cbData = sizeof(bogusKey);
2897 info.PublicKey.pbData = bogusKey;
2898 SetLastError(0xdeadbeef);
2899 ret = CertGetPublicKeyLength(0, &info);
2900 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
2901 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
2902 ret, GetLastError());
2903 SetLastError(0xdeadbeef);
2904 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2905 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_BADTAG,
2906 "Expected length 0 and CRYPT_E_ASN1_BADTAGTAG, got length %d, %08x\n",
2907 ret, GetLastError());
2908 /* With a believable RSA key but a bogus OID */
2909 info.Algorithm.pszObjId = bogusOID;
2910 info.PublicKey.cbData = sizeof(key);
2911 info.PublicKey.pbData = key;
2912 SetLastError(0xdeadbeef);
2913 ret = CertGetPublicKeyLength(0, &info);
2914 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
2915 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
2916 ret, GetLastError());
2917 SetLastError(0xdeadbeef);
2918 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2919 ok(ret == 56, "Expected length 56, got %d\n", ret);
2920 /* An RSA key with the DH OID */
2921 info.Algorithm.pszObjId = oid_rsa_dh;
2922 SetLastError(0xdeadbeef);
2923 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2924 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_BADTAG,
2925 "Expected length 0 and CRYPT_E_ASN1_BADTAG, got length %d, %08x\n",
2926 ret, GetLastError());
2927 /* With the RSA OID */
2928 info.Algorithm.pszObjId = oid_rsa_rsa;
2929 SetLastError(0xdeadbeef);
2930 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2931 ok(ret == 56, "Expected length 56, got %d\n", ret);
2936 init_function_pointers();
2939 testCertProperties();
2942 testGetSubjectCert();
2943 testGetIssuerCert();
2945 testCryptHashCert();
2947 testSignAndEncodeCert();
2948 testCreateSelfSignCert();
2950 testGetValidUsages();
2951 testCompareCertName();
2952 testCompareIntegerBlob();
2953 testComparePublicKeyInfo();
2954 testHashPublicKeyInfo();
2956 testVerifySubjectCert();
2957 testVerifyRevocation();
2958 testAcquireCertPrivateKey();
2959 testGetPublicKeyLength();