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 *pCertAddStoreToCollection)(HCERTSTORE,HCERTSTORE,DWORD,DWORD);
33 static PCCERT_CONTEXT (WINAPI *pCertCreateSelfSignCertificate)(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE,PCERT_NAME_BLOB,DWORD,PCRYPT_KEY_PROV_INFO,PCRYPT_ALGORITHM_IDENTIFIER,PSYSTEMTIME,PSYSTEMTIME,PCERT_EXTENSIONS);
34 static BOOL (WINAPI *pCertGetValidUsages)(DWORD,PCCERT_CONTEXT*,int*,LPSTR*,DWORD*);
35 static BOOL (WINAPI *pCryptAcquireCertificatePrivateKey)(PCCERT_CONTEXT,DWORD,void*,HCRYPTPROV_OR_NCRYPT_KEY_HANDLE*,DWORD*,BOOL*);
36 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*);
37 static BOOL (WINAPI * pCryptVerifyCertificateSignatureEx)
38 (HCRYPTPROV, DWORD, DWORD, void *, DWORD, void *, DWORD, void *);
40 static BOOL (WINAPI * pCryptAcquireContextW)
41 (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD);
43 static void init_function_pointers(void)
45 HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll");
46 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
48 #define GET_PROC(dll, func) \
49 p ## func = (void *)GetProcAddress(dll, #func); \
51 trace("GetProcAddress(%s) failed\n", #func);
53 GET_PROC(hCrypt32, CertAddStoreToCollection)
54 GET_PROC(hCrypt32, CertCreateSelfSignCertificate)
55 GET_PROC(hCrypt32, CertGetValidUsages)
56 GET_PROC(hCrypt32, CryptAcquireCertificatePrivateKey)
57 GET_PROC(hCrypt32, CryptEncodeObjectEx)
58 GET_PROC(hCrypt32, CryptVerifyCertificateSignatureEx)
60 GET_PROC(hAdvapi32, CryptAcquireContextW)
65 static BYTE subjectName[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
66 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
68 static BYTE serialNum[] = { 1 };
69 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
70 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
71 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
72 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
73 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
74 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
75 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
76 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
77 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
78 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
79 static BYTE bigCertHash[] = { 0x6e, 0x30, 0x90, 0x71, 0x5f, 0xd9, 0x23,
80 0x56, 0xeb, 0xae, 0x25, 0x40, 0xe6, 0x22, 0xda, 0x19, 0x26, 0x02, 0xa6, 0x08 };
82 static const BYTE bigCertWithDifferentSubject[] = { 0x30, 0x7a, 0x02, 0x01, 0x02,
83 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
84 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67,
85 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31,
86 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
87 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15,
88 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c,
89 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06,
90 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
91 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
93 static const BYTE bigCertWithDifferentIssuer[] = { 0x30, 0x7a, 0x02, 0x01,
94 0x01, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
95 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
96 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
97 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
98 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
99 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
100 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
101 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
102 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
105 static BYTE subjectName2[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
106 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61,
108 static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
109 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
110 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
111 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
112 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
113 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
114 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20,
115 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
116 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
117 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
118 static const BYTE bigCert2WithDifferentSerial[] = { 0x30, 0x7a, 0x02, 0x01,
119 0x02, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
120 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
121 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
122 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
123 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
124 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41,
125 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
126 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
127 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
129 static BYTE bigCert2Hash[] = { 0x4a, 0x7f, 0x32, 0x1f, 0xcf, 0x3b, 0xc0,
130 0x87, 0x48, 0x2b, 0xa1, 0x86, 0x54, 0x18, 0xe4, 0x3a, 0x0e, 0x53, 0x7e, 0x2b };
132 static const BYTE certWithUsage[] = { 0x30, 0x81, 0x93, 0x02, 0x01, 0x01, 0x30,
133 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
134 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00,
135 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
136 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
137 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31,
138 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61,
139 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00,
140 0x03, 0x01, 0x00, 0xa3, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x1d,
141 0x25, 0x01, 0x01, 0xff, 0x04, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01,
142 0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
143 0x03, 0x02, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
145 static void testAddCert(void)
148 HCERTSTORE collection;
149 PCCERT_CONTEXT context;
150 PCCERT_CONTEXT copyContext;
153 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
154 CERT_STORE_CREATE_NEW_FLAG, NULL);
155 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
159 /* Weird--bad add disposition leads to an access violation in Windows.
161 ret = CertAddEncodedCertificateToStore(0, X509_ASN_ENCODING, bigCert,
162 sizeof(bigCert), 0, NULL);
163 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
164 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
165 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
166 bigCert, sizeof(bigCert), 0, NULL);
167 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
168 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
170 /* Weird--can add a cert to the NULL store (does this have special
174 ret = CertAddEncodedCertificateToStore(0, X509_ASN_ENCODING, bigCert,
175 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
176 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
179 CertFreeCertificateContext(context);
181 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
182 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
183 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
185 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
186 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
187 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
189 /* This has the same name as bigCert, so finding isn't done by name */
190 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
191 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, &context);
192 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
194 ok(context != NULL, "Expected a context\n");
197 CRYPT_DATA_BLOB hash = { sizeof(bigCert2Hash), bigCert2Hash };
199 /* Duplicate (AddRef) the context so we can still use it after
200 * deleting it from the store.
202 CertDuplicateCertificateContext(context);
203 CertDeleteCertificateFromStore(context);
204 /* Set the same hash as bigCert2, and try to readd it */
205 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID,
207 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
209 ret = CertAddCertificateContextToStore(store, context,
210 CERT_STORE_ADD_NEW, NULL);
211 /* The failure is a bit odd (CRYPT_E_ASN1_BADTAG), so just check
214 ok(!ret, "Expected failure\n");
215 CertFreeCertificateContext(context);
217 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
219 ok(context != NULL, "Expected a context\n");
222 /* Try to readd bigCert2 to the store */
223 ret = CertAddCertificateContextToStore(store, context,
224 CERT_STORE_ADD_NEW, NULL);
225 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
226 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
227 CertFreeCertificateContext(context);
230 /* Adding a cert with the same issuer name and serial number (but
231 * different subject) as an existing cert succeeds.
234 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
235 bigCert2WithDifferentSerial, sizeof(bigCert2WithDifferentSerial),
236 CERT_STORE_ADD_NEW, &context);
237 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
240 CertDeleteCertificateFromStore(context);
242 /* Adding a cert with the same subject name and serial number (but
243 * different issuer) as an existing cert succeeds.
246 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
247 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject),
248 CERT_STORE_ADD_NEW, &context);
249 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
252 CertDeleteCertificateFromStore(context);
254 /* Adding a cert with the same issuer name and serial number (but
255 * different otherwise) as an existing cert succeeds.
258 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
259 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer),
260 CERT_STORE_ADD_NEW, &context);
261 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
264 CertDeleteCertificateFromStore(context);
266 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
267 CERT_STORE_CREATE_NEW_FLAG, NULL);
268 ok(collection != NULL, "CertOpenStore failed: %08x\n", GetLastError());
269 if (collection && pCertAddStoreToCollection)
271 /* Add store to the collection, but disable updates */
272 pCertAddStoreToCollection(collection, store, 0, 0);
274 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
276 ok(context != NULL, "Expected a context\n");
279 /* Try to readd bigCert2 to the collection */
280 ret = CertAddCertificateContextToStore(collection, context,
281 CERT_STORE_ADD_NEW, NULL);
282 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
283 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
284 /* Replacing an existing certificate context is allowed, even
285 * though updates to the collection aren't..
287 ret = CertAddCertificateContextToStore(collection, context,
288 CERT_STORE_ADD_REPLACE_EXISTING, NULL);
289 ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
291 /* use the existing certificate and ask for a copy of the context*/
293 ret = CertAddCertificateContextToStore(collection, context,
294 CERT_STORE_ADD_USE_EXISTING, ©Context);
295 ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
297 ok(copyContext != NULL, "Expected on output a non NULL copyContext\n");
299 CertFreeCertificateContext(copyContext);
300 /* but adding a new certificate isn't allowed. */
301 ret = CertAddCertificateContextToStore(collection, context,
302 CERT_STORE_ADD_ALWAYS, NULL);
303 ok(!ret && GetLastError() == E_ACCESSDENIED,
304 "Expected E_ACCESSDENIED, got %08x\n", GetLastError());
305 CertFreeCertificateContext(context);
308 CertCloseStore(collection, 0);
311 CertCloseStore(store, 0);
314 static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
315 PCCERT_CONTEXT context, DWORD propID)
317 BYTE hash[20] = { 0 }, hashProperty[20];
320 DWORD dwSizeWithNull;
322 memset(hash, 0, sizeof(hash));
323 memset(hashProperty, 0, sizeof(hashProperty));
325 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
326 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
327 ret = CertGetCertificateContextProperty(context, propID, NULL,
329 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
331 ret = CertGetCertificateContextProperty(context, propID, hashProperty,
333 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
335 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
337 ok(size == dwSizeWithNull, "Unexpected length of hash for property: received %d instead of %d\n",
338 dwSizeWithNull,size);
341 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e','m','p',0 };
342 static const BYTE v1CertWithPubKey[] = {
343 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
344 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
345 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
346 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
347 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
348 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
349 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
350 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
351 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
352 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
354 static const BYTE v1CertWithSubjectKeyId[] = {
355 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
356 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
357 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
358 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
359 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
360 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
361 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
362 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
363 0x4c,0x61,0x6e,0x67,0x00 };
364 static const BYTE subjectKeyId[] = {
365 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
367 static void testCertProperties(void)
369 PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
370 bigCert, sizeof(bigCert));
371 DWORD propID, numProps, access, size;
373 BYTE hash[20] = { 0 }, hashProperty[20];
374 CRYPT_DATA_BLOB blob;
375 CERT_KEY_CONTEXT keyContext;
377 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
383 propID = CertEnumCertificateContextProperties(NULL, 0);
389 propID = CertEnumCertificateContextProperties(context, propID);
392 } while (propID != 0);
393 ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
395 /* Tests with a NULL cert context. Prop ID 0 fails.. */
396 ret = CertSetCertificateContextProperty(NULL, 0, 0, NULL);
397 ok(!ret && GetLastError() == E_INVALIDARG,
398 "Expected E_INVALIDARG, got %08x\n", GetLastError());
399 /* while this just crashes.
400 ret = CertSetCertificateContextProperty(NULL,
401 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
404 ret = CertSetCertificateContextProperty(context, 0, 0, NULL);
405 ok(!ret && GetLastError() == E_INVALIDARG,
406 "Expected E_INVALIDARG, got %08x\n", GetLastError());
407 /* Can't set the cert property directly, this crashes.
408 ret = CertSetCertificateContextProperty(context,
409 CERT_CERT_PROP_ID, 0, bigCert2);
413 ret = CertGetCertificateContextProperty(context,
414 CERT_ACCESS_STATE_PROP_ID, 0, NULL);
415 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
417 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
422 ret = CertGetCertificateContextProperty(context,
423 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
424 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
425 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
426 /* And, an implicit property */
427 size = sizeof(access);
428 ret = CertGetCertificateContextProperty(context,
429 CERT_ACCESS_STATE_PROP_ID, &access, &size);
430 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
432 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
433 "Didn't expect a persisted cert\n");
434 /* Trying to set this "read only" property crashes.
435 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
436 ret = CertSetCertificateContextProperty(context,
437 CERT_ACCESS_STATE_PROP_ID, 0, &access);
440 /* Can I set the hash to an invalid hash? */
442 blob.cbData = sizeof(hash);
443 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
445 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
447 size = sizeof(hashProperty);
448 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
449 hashProperty, &size);
450 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
451 /* Delete the (bogus) hash, and get the real one */
452 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
454 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
456 checkHash(bigCert, sizeof(bigCert), CALG_SHA1, context,
459 /* Now that the hash property is set, we should get one property when
465 propID = CertEnumCertificateContextProperties(context, propID);
468 } while (propID != 0);
469 ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
471 /* Check a few other implicit properties */
472 checkHash(bigCert, sizeof(bigCert), CALG_MD5, context,
473 CERT_MD5_HASH_PROP_ID);
475 context->pCertInfo->Subject.pbData,
476 context->pCertInfo->Subject.cbData,
477 CALG_MD5, context, CERT_SUBJECT_NAME_MD5_HASH_PROP_ID);
479 context->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
480 context->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
481 CALG_MD5, context, CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID);
483 /* Test key contexts and handles and such */
485 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
487 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
488 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
489 size = sizeof(CERT_KEY_CONTEXT);
490 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
492 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
493 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
494 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
496 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
497 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
498 /* Key context with an invalid size */
499 keyContext.cbSize = 0;
500 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
502 ok(!ret && GetLastError() == E_INVALIDARG,
503 "Expected E_INVALIDARG, got %08x\n", GetLastError());
504 size = sizeof(keyContext);
505 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
507 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
508 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
509 keyContext.cbSize = sizeof(keyContext);
510 keyContext.hCryptProv = 0;
511 keyContext.dwKeySpec = AT_SIGNATURE;
512 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
514 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
515 /* Now that that's set, the key prov handle property is also gettable.
517 size = sizeof(DWORD);
518 ret = CertGetCertificateContextProperty(context,
519 CERT_KEY_PROV_HANDLE_PROP_ID, &keyContext.hCryptProv, &size);
520 ok(ret, "Expected to get the CERT_KEY_PROV_HANDLE_PROP_ID, got %08x\n",
522 /* Remove the key prov handle property.. */
523 ret = CertSetCertificateContextProperty(context,
524 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
525 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
527 /* and the key context's CSP is set to NULL. */
528 size = sizeof(keyContext);
529 ret = CertGetCertificateContextProperty(context,
530 CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
531 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
533 ok(keyContext.hCryptProv == 0, "Expected no hCryptProv\n");
535 /* According to MSDN the subject key id can be stored as a property,
536 * as a subject key extension, or as the SHA1 hash of the public key,
537 * but this cert has none of them:
539 ret = CertGetCertificateContextProperty(context,
540 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
541 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
542 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
543 CertFreeCertificateContext(context);
544 /* This cert does have a public key, but its subject key identifier still
545 * isn't available: */
546 context = CertCreateCertificateContext(X509_ASN_ENCODING,
547 v1CertWithPubKey, sizeof(v1CertWithPubKey));
548 ret = CertGetCertificateContextProperty(context,
549 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
550 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
551 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
552 CertFreeCertificateContext(context);
553 /* This cert with a subject key extension can have its key identifier
554 * property retrieved:
556 context = CertCreateCertificateContext(X509_ASN_ENCODING,
557 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId));
558 ret = CertGetCertificateContextProperty(context,
559 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
560 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
563 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
567 ret = CertGetCertificateContextProperty(context,
568 CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
569 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
571 ok(!memcmp(buf, subjectKeyId, size), "Unexpected subject key id\n");
572 HeapFree(GetProcessHeap(), 0, buf);
575 CertFreeCertificateContext(context);
578 static void testDupCert(void)
581 PCCERT_CONTEXT context, dupContext;
584 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
585 CERT_STORE_CREATE_NEW_FLAG, NULL);
586 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
590 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
591 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
592 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
594 ok(context != NULL, "Expected a valid cert context\n");
597 ok(context->cbCertEncoded == sizeof(bigCert),
598 "Wrong cert size %d\n", context->cbCertEncoded);
599 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)),
600 "Unexpected encoded cert in context\n");
601 ok(context->hCertStore == store, "Unexpected store\n");
603 dupContext = CertDuplicateCertificateContext(context);
604 ok(dupContext != NULL, "Expected valid duplicate\n");
605 /* Not only is it a duplicate, it's identical: the address is the
608 ok(dupContext == context, "Expected identical context addresses\n");
609 CertFreeCertificateContext(dupContext);
610 CertFreeCertificateContext(context);
612 CertCloseStore(store, 0);
615 static BYTE subjectName3[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
616 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x52, 0x6f, 0x62, 0x20, 0x20, 0x4c, 0x61,
618 static const BYTE iTunesCert0[] = {
619 0x30,0x82,0x03,0xc4,0x30,0x82,0x03,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
620 0x47,0xbf,0x19,0x95,0xdf,0x8d,0x52,0x46,0x43,0xf7,0xdb,0x6d,0x48,0x0d,0x31,
621 0xa4,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
622 0x00,0x30,0x81,0x8b,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
623 0x5a,0x41,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0c,0x57,0x65,
624 0x73,0x74,0x65,0x72,0x6e,0x20,0x43,0x61,0x70,0x65,0x31,0x14,0x30,0x12,0x06,
625 0x03,0x55,0x04,0x07,0x13,0x0b,0x44,0x75,0x72,0x62,0x61,0x6e,0x76,0x69,0x6c,
626 0x6c,0x65,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x0a,0x13,0x06,0x54,0x68,
627 0x61,0x77,0x74,0x65,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14,
628 0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
629 0x61,0x74,0x69,0x6f,0x6e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13,
630 0x16,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
631 0x6d,0x70,0x69,0x6e,0x67,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x33,0x31,
632 0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x33,0x31,
633 0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x53,0x31,0x0b,0x30,
634 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,
635 0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
636 0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,
637 0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,0x6d,0x65,0x20,
638 0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,0x76,0x69,0x63,
639 0x65,0x73,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,
640 0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,
641 0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa9,0xca,0xb2,0xa4,0xcc,0xcd,0x20,
642 0xaf,0x0a,0x7d,0x89,0xac,0x87,0x75,0xf0,0xb4,0x4e,0xf1,0xdf,0xc1,0x0f,0xbf,
643 0x67,0x61,0xbd,0xa3,0x64,0x1c,0xda,0xbb,0xf9,0xca,0x33,0xab,0x84,0x30,0x89,
644 0x58,0x7e,0x8c,0xdb,0x6b,0xdd,0x36,0x9e,0x0f,0xbf,0xd1,0xec,0x78,0xf2,0x77,
645 0xa6,0x7e,0x6f,0x3c,0xbf,0x93,0xaf,0x0d,0xba,0x68,0xf4,0x6c,0x94,0xca,0xbd,
646 0x52,0x2d,0xab,0x48,0x3d,0xf5,0xb6,0xd5,0x5d,0x5f,0x1b,0x02,0x9f,0xfa,0x2f,
647 0x6b,0x1e,0xa4,0xf7,0xa3,0x9a,0xa6,0x1a,0xc8,0x02,0xe1,0x7f,0x4c,0x52,0xe3,
648 0x0e,0x60,0xec,0x40,0x1c,0x7e,0xb9,0x0d,0xde,0x3f,0xc7,0xb4,0xdf,0x87,0xbd,
649 0x5f,0x7a,0x6a,0x31,0x2e,0x03,0x99,0x81,0x13,0xa8,0x47,0x20,0xce,0x31,0x73,
650 0x0d,0x57,0x2d,0xcd,0x78,0x34,0x33,0x95,0x12,0x99,0x12,0xb9,0xde,0x68,0x2f,
651 0xaa,0xe6,0xe3,0xc2,0x8a,0x8c,0x2a,0xc3,0x8b,0x21,0x87,0x66,0xbd,0x83,0x58,
652 0x57,0x6f,0x75,0xbf,0x3c,0xaa,0x26,0x87,0x5d,0xca,0x10,0x15,0x3c,0x9f,0x84,
653 0xea,0x54,0xc1,0x0a,0x6e,0xc4,0xfe,0xc5,0x4a,0xdd,0xb9,0x07,0x11,0x97,0x22,
654 0x7c,0xdb,0x3e,0x27,0xd1,0x1e,0x78,0xec,0x9f,0x31,0xc9,0xf1,0xe6,0x22,0x19,
655 0xdb,0xc4,0xb3,0x47,0x43,0x9a,0x1a,0x5f,0xa0,0x1e,0x90,0xe4,0x5e,0xf5,0xee,
656 0x7c,0xf1,0x7d,0xab,0x62,0x01,0x8f,0xf5,0x4d,0x0b,0xde,0xd0,0x22,0x56,0xa8,
657 0x95,0xcd,0xae,0x88,0x76,0xae,0xee,0xba,0x0d,0xf3,0xe4,0x4d,0xd9,0xa0,0xfb,
658 0x68,0xa0,0xae,0x14,0x3b,0xb3,0x87,0xc1,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,
659 0x81,0xdb,0x30,0x81,0xd8,0x30,0x34,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
660 0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
661 0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,
662 0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,
663 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
664 0xff,0x02,0x01,0x00,0x30,0x41,0x06,0x03,0x55,0x1d,0x1f,0x04,0x3a,0x30,0x38,
665 0x30,0x36,0xa0,0x34,0xa0,0x32,0x86,0x30,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
666 0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,
667 0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
668 0x6d,0x70,0x69,0x6e,0x67,0x43,0x41,0x2e,0x63,0x72,0x6c,0x30,0x13,0x06,0x03,
669 0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
670 0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,
671 0x02,0x01,0x06,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,0x04,0x1d,0x30,0x1b,0xa4,
672 0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0c,0x54,
673 0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,0x33,0x30,0x0d,0x06,0x09,
674 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,
675 0x4a,0x6b,0xf9,0xea,0x58,0xc2,0x44,0x1c,0x31,0x89,0x79,0x99,0x2b,0x96,0xbf,
676 0x82,0xac,0x01,0xd6,0x1c,0x4c,0xcd,0xb0,0x8a,0x58,0x6e,0xdf,0x08,0x29,0xa3,
677 0x5e,0xc8,0xca,0x93,0x13,0xe7,0x04,0x52,0x0d,0xef,0x47,0x27,0x2f,0x00,0x38,
678 0xb0,0xe4,0xc9,0x93,0x4e,0x9a,0xd4,0x22,0x62,0x15,0xf7,0x3f,0x37,0x21,0x4f,
679 0x70,0x31,0x80,0xf1,0x8b,0x38,0x87,0xb3,0xe8,0xe8,0x97,0x00,0xfe,0xcf,0x55,
680 0x96,0x4e,0x24,0xd2,0xa9,0x27,0x4e,0x7a,0xae,0xb7,0x61,0x41,0xf3,0x2a,0xce,
681 0xe7,0xc9,0xd9,0x5e,0xdd,0xbb,0x2b,0x85,0x3e,0xb5,0x9d,0xb5,0xd9,0xe1,0x57,
682 0xff,0xbe,0xb4,0xc5,0x7e,0xf5,0xcf,0x0c,0x9e,0xf0,0x97,0xfe,0x2b,0xd3,0x3b,
683 0x52,0x1b,0x1b,0x38,0x27,0xf7,0x3f,0x4a };
684 static const BYTE iTunesCert1[] = {
685 0x30,0x82,0x03,0xff,0x30,0x82,0x02,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
686 0x0d,0xe9,0x2b,0xf0,0xd4,0xd8,0x29,0x88,0x18,0x32,0x05,0x09,0x5e,0x9a,0x76,
687 0x88,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
688 0x00,0x30,0x53,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
689 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
690 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,
691 0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
692 0x20,0x54,0x69,0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,
693 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,
694 0x30,0x33,0x31,0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
695 0x30,0x38,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x57,
696 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,
697 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,
698 0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2f,0x30,0x2d,0x06,0x03,0x55,
699 0x04,0x03,0x13,0x26,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,
700 0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,
701 0x76,0x69,0x63,0x65,0x73,0x20,0x53,0x69,0x67,0x6e,0x65,0x72,0x30,0x82,0x01,
702 0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
703 0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,
704 0xb2,0x50,0x28,0x48,0xdd,0xd3,0x68,0x7a,0x84,0x18,0x44,0x66,0x75,0x5d,0x7e,
705 0xc4,0xb8,0x9f,0x63,0x26,0xff,0x3d,0x43,0x9c,0x7c,0x11,0x38,0x10,0x25,0x55,
706 0x73,0xd9,0x75,0x27,0x69,0xfd,0x4e,0xb9,0x20,0x5c,0xd3,0x0a,0xf9,0xa0,0x1b,
707 0x2a,0xed,0x55,0x56,0x21,0x61,0xd8,0x1e,0xdb,0xe4,0xbc,0x33,0x6b,0xc7,0xef,
708 0xdd,0xa3,0x37,0x65,0x8e,0x1b,0x93,0x0c,0xb6,0x53,0x1e,0x5c,0x7c,0x66,0x35,
709 0x5f,0x05,0x8a,0x45,0xfe,0x76,0x4e,0xdf,0x53,0x80,0xa2,0x81,0x20,0x9d,0xae,
710 0x88,0x5c,0xa2,0x08,0xf7,0xe5,0x30,0xf9,0xee,0x22,0x37,0x4c,0x42,0x0a,0xce,
711 0xdf,0xc6,0x1f,0xc4,0xd6,0x55,0xe9,0x81,0x3f,0xb5,0x52,0xa3,0x2c,0xaa,0x01,
712 0x7a,0xf2,0xa2,0xaa,0x8d,0x35,0xfe,0x9f,0xe6,0x5d,0x6a,0x05,0x9f,0x3d,0x6b,
713 0xe3,0xbf,0x96,0xc0,0xfe,0xcc,0x60,0xf9,0x40,0xe7,0x07,0xa0,0x44,0xeb,0x81,
714 0x51,0x6e,0xa5,0x2a,0xf2,0xb6,0x8a,0x10,0x28,0xed,0x8f,0xdc,0x06,0xa0,0x86,
715 0x50,0x9a,0x7b,0x4a,0x08,0x0d,0x30,0x1d,0xca,0x10,0x9e,0x6b,0xf7,0xe9,0x58,
716 0xae,0x04,0xa9,0x40,0x99,0xb2,0x28,0xe8,0x8f,0x16,0xac,0x3c,0xe3,0x53,0x6f,
717 0x4b,0xd3,0x35,0x9d,0xb5,0x6f,0x64,0x1d,0xb3,0x96,0x2c,0xbb,0x3d,0xe7,0x79,
718 0xeb,0x6d,0x7a,0xf9,0x16,0xe6,0x26,0xad,0xaf,0xef,0x99,0x53,0xb7,0x40,0x2c,
719 0x95,0xb8,0x79,0xaa,0xfe,0xd4,0x52,0xab,0x29,0x74,0x7e,0x42,0xec,0x39,0x1e,
720 0xa2,0x6a,0x16,0xe6,0x59,0xbb,0x24,0x68,0xd8,0x00,0x80,0x43,0x10,0x87,0x80,
721 0x6b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xca,0x30,0x81,0xc7,0x30,0x34,0x06,
722 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,
723 0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,
724 0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
725 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
726 0xff,0x04,0x02,0x30,0x00,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30,
727 0x2a,0x30,0x28,0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,
728 0x2f,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,
729 0x6f,0x6d,0x2f,0x74,0x73,0x73,0x2d,0x63,0x61,0x2e,0x63,0x72,0x6c,0x30,0x16,
730 0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,
731 0x06,0x01,0x05,0x05,0x07,0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
732 0x01,0xff,0x04,0x04,0x03,0x02,0x06,0xc0,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,
733 0x04,0x1d,0x30,0x1b,0xa4,0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,
734 0x04,0x03,0x13,0x0c,0x54,0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,
735 0x34,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
736 0x00,0x03,0x82,0x01,0x01,0x00,0x87,0x78,0x70,0xda,0x4e,0x52,0x01,0x20,0x5b,
737 0xe0,0x79,0xc9,0x82,0x30,0xc4,0xfd,0xb9,0x19,0x96,0xbd,0x91,0x00,0xc3,0xbd,
738 0xcd,0xcd,0xc6,0xf4,0x0e,0xd8,0xff,0xf9,0x4d,0xc0,0x33,0x62,0x30,0x11,0xc5,
739 0xf5,0x74,0x1b,0xd4,0x92,0xde,0x5f,0x9c,0x20,0x13,0xb1,0x7c,0x45,0xbe,0x50,
740 0xcd,0x83,0xe7,0x80,0x17,0x83,0xa7,0x27,0x93,0x67,0x13,0x46,0xfb,0xca,0xb8,
741 0x98,0x41,0x03,0xcc,0x9b,0x51,0x5b,0x05,0x8b,0x7f,0xa8,0x6f,0xf3,0x1b,0x50,
742 0x1b,0x24,0x2e,0xf2,0x69,0x8d,0x6c,0x22,0xf7,0xbb,0xca,0x16,0x95,0xed,0x0c,
743 0x74,0xc0,0x68,0x77,0xd9,0xeb,0x99,0x62,0x87,0xc1,0x73,0x90,0xf8,0x89,0x74,
744 0x7a,0x23,0xab,0xa3,0x98,0x7b,0x97,0xb1,0xf7,0x8f,0x29,0x71,0x4d,0x2e,0x75,
745 0x1b,0x48,0x41,0xda,0xf0,0xb5,0x0d,0x20,0x54,0xd6,0x77,0xa0,0x97,0x82,0x63,
746 0x69,0xfd,0x09,0xcf,0x8a,0xf0,0x75,0xbb,0x09,0x9b,0xd9,0xf9,0x11,0x55,0x26,
747 0x9a,0x61,0x32,0xbe,0x7a,0x02,0xb0,0x7b,0x86,0xbe,0xa2,0xc3,0x8b,0x22,0x2c,
748 0x78,0xd1,0x35,0x76,0xbc,0x92,0x73,0x5c,0xf9,0xb9,0xe6,0x4c,0x15,0x0a,0x23,
749 0xcc,0xe4,0xd2,0xd4,0x34,0x2e,0x49,0x40,0x15,0x3c,0x0f,0x60,0x7a,0x24,0xc6,
750 0xa5,0x66,0xef,0x96,0xcf,0x70,0xeb,0x3e,0xe7,0xf4,0x0d,0x7e,0xdc,0xd1,0x7c,
751 0xa3,0x76,0x71,0x69,0xc1,0x9c,0x4f,0x47,0x30,0x35,0x21,0xb1,0xa2,0xaf,0x1a,
752 0x62,0x3c,0x2b,0xd9,0x8e,0xaa,0x2a,0x07,0x7b,0xd8,0x18,0xb3,0x5c,0x7b,0xe2,
753 0x9d,0xa5,0x6f,0xfe,0x3c,0x89,0xad };
754 static const BYTE iTunesCert2[] = {
755 0x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
756 0x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75,
757 0xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
758 0x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
759 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
760 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,
761 0x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,
762 0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,
763 0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,
764 0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x34,0x30,
765 0x37,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30,
766 0x37,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,
767 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,
768 0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
769 0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b,
770 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,
771 0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,
772 0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,
773 0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,
774 0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,
775 0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,
776 0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,
777 0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,0x53,0x69,
778 0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,0x20,0x43,0x41,0x30,0x82,
779 0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,
780 0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,
781 0x00,0xbe,0xbc,0xee,0xbc,0x7e,0xef,0x83,0xeb,0xe0,0x37,0x4f,0xfb,0x03,0x10,
782 0x38,0xbe,0x08,0xd2,0x8c,0x7d,0x9d,0xfa,0x92,0x7f,0x19,0x0c,0xc2,0x6b,0xee,
783 0x42,0x52,0x8c,0xde,0xd3,0x1c,0x48,0x13,0x25,0xea,0xc1,0x63,0x7a,0xf9,0x51,
784 0x65,0xee,0xd3,0xaa,0x3b,0xf5,0xf0,0x94,0x9c,0x2b,0xfb,0xf2,0x66,0xd4,0x24,
785 0xda,0xf7,0xf5,0x9f,0x6e,0x19,0x39,0x36,0xbc,0xd0,0xa3,0x76,0x08,0x1e,0x22,
786 0x27,0x24,0x6c,0x38,0x91,0x27,0xe2,0x84,0x49,0xae,0x1b,0x8a,0xa1,0xfd,0x25,
787 0x82,0x2c,0x10,0x30,0xe8,0x71,0xab,0x28,0xe8,0x77,0x4a,0x51,0xf1,0xec,0xcd,
788 0xf8,0xf0,0x54,0xd4,0x6f,0xc0,0xe3,0x6d,0x0a,0x8f,0xd9,0xd8,0x64,0x8d,0x63,
789 0xb2,0x2d,0x4e,0x27,0xf6,0x85,0x0e,0xfe,0x6d,0xe3,0x29,0x99,0xe2,0x85,0x47,
790 0x7c,0x2d,0x86,0x7f,0xe8,0x57,0x8f,0xad,0x67,0xc2,0x33,0x32,0x91,0x13,0x20,
791 0xfc,0xa9,0x23,0x14,0x9a,0x6d,0xc2,0x84,0x4b,0x76,0x68,0x04,0xd5,0x71,0x2c,
792 0x5d,0x21,0xfa,0x88,0x0d,0x26,0xfd,0x1f,0x2d,0x91,0x2b,0xe7,0x01,0x55,0x4d,
793 0xf2,0x6d,0x35,0x28,0x82,0xdf,0xd9,0x6b,0x5c,0xb6,0xd6,0xd9,0xaa,0x81,0xfd,
794 0x5f,0xcd,0x83,0xba,0x63,0x9d,0xd0,0x22,0xfc,0xa9,0x3b,0x42,0x69,0xb2,0x8e,
795 0x3a,0xb5,0xbc,0xb4,0x9e,0x0f,0x5e,0xc4,0xea,0x2c,0x82,0x8b,0x28,0xfd,0x53,
796 0x08,0x96,0xdd,0xb5,0x01,0x20,0xd1,0xf9,0xa5,0x18,0xe7,0xc0,0xee,0x51,0x70,
797 0x37,0xe1,0xb6,0x05,0x48,0x52,0x48,0x6f,0x38,0xea,0xc3,0xe8,0x6c,0x7b,0x44,
798 0x84,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xa0,0x30,0x82,0x01,0x9c,
799 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
800 0x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,
801 0x3b,0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,
802 0x03,0x30,0x2a,0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
803 0x16,0x1c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,
804 0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,
805 0x30,0x31,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24,
806 0xa0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,
807 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63,
808 0x61,0x33,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16,
809 0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2b,
810 0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
811 0x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48,
812 0x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x01,0x30,0x29,0x06,
813 0x03,0x55,0x1d,0x11,0x04,0x22,0x30,0x20,0xa4,0x1e,0x30,0x1c,0x31,0x1a,0x30,
814 0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6c,0x61,0x73,0x73,0x33,0x43,
815 0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x34,0x33,0x30,0x1d,0x06,0x03,0x55,
816 0x1d,0x0e,0x04,0x16,0x04,0x14,0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,
817 0x36,0x7c,0x68,0xcf,0x5b,0x78,0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x81,0x80,0x06,
818 0x03,0x55,0x1d,0x23,0x04,0x79,0x30,0x77,0xa1,0x63,0xa4,0x61,0x30,0x5f,0x31,
819 0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,
820 0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
821 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,
822 0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6c,
823 0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,
824 0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,
825 0x72,0x69,0x74,0x79,0x82,0x10,0x70,0xba,0xe4,0x1d,0x10,0xd9,0x29,0x34,0xb6,
826 0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
827 0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xae,0x3a,0x17,0xb8,
828 0x4a,0x7b,0x55,0xfa,0x64,0x55,0xec,0x40,0xa4,0xed,0x49,0x41,0x90,0x99,0x9c,
829 0x89,0xbc,0xaf,0x2e,0x1d,0xca,0x78,0x23,0xf9,0x1c,0x19,0x0f,0x7f,0xeb,0x68,
830 0xbc,0x32,0xd9,0x88,0x38,0xde,0xdc,0x3f,0xd3,0x89,0xb4,0x3f,0xb1,0x82,0x96,
831 0xf1,0xa4,0x5a,0xba,0xed,0x2e,0x26,0xd3,0xde,0x7c,0x01,0x6e,0x00,0x0a,0x00,
832 0xa4,0x06,0x92,0x11,0x48,0x09,0x40,0xf9,0x1c,0x18,0x79,0x67,0x23,0x24,0xe0,
833 0xbb,0xd5,0xe1,0x50,0xae,0x1b,0xf5,0x0e,0xdd,0xe0,0x2e,0x81,0xcd,0x80,0xa3,
834 0x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88,
835 0x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f,
836 0x5e,0xf6,0x7a,0xb5 };
837 static const BYTE iTunesCert3[] = {
838 0x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
839 0x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6,
840 0x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
841 0x00,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
842 0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,
843 0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,
844 0x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
845 0x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,
846 0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,
847 0x73,0x20,0x6f,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,
848 0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
849 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,
850 0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,
851 0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,
852 0x6f,0x64,0x65,0x20,0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,
853 0x34,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x31,0x37,0x30,
854 0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x38,0x30,0x31,0x32,0x32,0x32,
855 0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,
856 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
857 0x08,0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x12,
858 0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,
859 0x69,0x6e,0x6f,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0a,0x14,0x14,0x41,
860 0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x2c,0x20,
861 0x49,0x6e,0x63,0x2e,0x31,0x3e,0x30,0x3c,0x06,0x03,0x55,0x04,0x0b,0x13,0x35,
862 0x44,0x69,0x67,0x69,0x74,0x61,0x6c,0x20,0x49,0x44,0x20,0x43,0x6c,0x61,0x73,
863 0x73,0x20,0x33,0x20,0x2d,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
864 0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x56,0x61,0x6c,0x69,0x64,
865 0x61,0x74,0x69,0x6f,0x6e,0x20,0x76,0x32,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,
866 0x04,0x03,0x14,0x14,0x41,0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,
867 0x74,0x65,0x72,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x30,0x81,0x9f,0x30,0x0d,0x06,
868 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,
869 0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xd3,0xab,0x3b,0x7f,0xec,0x48,0x84,
870 0xce,0xa8,0x1a,0x12,0xf3,0x3c,0x87,0xcb,0x24,0x58,0x96,0x02,0x87,0x66,0x49,
871 0xeb,0x89,0xee,0x79,0x44,0x70,0x8d,0xe7,0xd4,0x1f,0x30,0x92,0xc0,0x9c,0x35,
872 0x78,0xc0,0xaf,0x1c,0xb6,0x28,0xd3,0xe0,0xe0,0x9d,0xd3,0x49,0x76,0x73,0x57,
873 0x19,0x4d,0x8d,0x70,0x85,0x64,0x4d,0x1d,0xc6,0x02,0x3e,0xe5,0x2c,0x66,0x07,
874 0xd2,0x27,0x4b,0xd6,0xc8,0x3c,0x93,0xb6,0x15,0x0c,0xde,0x5b,0xd7,0x93,0xdd,
875 0xbe,0x85,0x62,0x34,0x17,0x8a,0x05,0x60,0xf0,0x8a,0x1c,0x5a,0x40,0x21,0x8d,
876 0x51,0x6c,0xb0,0x62,0xd8,0xb5,0xd4,0xf9,0xb1,0xd0,0x58,0x7a,0x7a,0x82,0x55,
877 0xb3,0xf9,0x53,0x71,0xde,0xd2,0xc9,0x37,0x8c,0xf6,0x5a,0x1f,0x2d,0xcd,0x7c,
878 0x67,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30,
879 0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06,0x03,0x55,
880 0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x40,0x06,0x03,
881 0x55,0x1d,0x1f,0x04,0x39,0x30,0x37,0x30,0x35,0xa0,0x33,0xa0,0x31,0x86,0x2f,
882 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,
883 0x34,0x2d,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,
884 0x63,0x6f,0x6d,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2e,0x63,
885 0x72,0x6c,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b,0x30,0x39,
886 0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,0x03,0x30,0x2a,
887 0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1c,0x68,
888 0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,
889 0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x30,0x13,0x06,
890 0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
891 0x07,0x03,0x03,0x30,0x75,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
892 0x04,0x69,0x30,0x67,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,
893 0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,
894 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x3f,0x06,
895 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x33,0x68,0x74,0x74,0x70,
896 0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,
897 0x61,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,
898 0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,0x61,0x2e,0x63,
899 0x65,0x72,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
900 0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,0x36,0x7c,0x68,0xcf,0x5b,0x78,
901 0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,
902 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x04,0x10,0x30,0x16,0x06,0x0a,0x2b,0x06,
903 0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x1b,0x04,0x08,0x30,0x06,0x01,0x01,0x00,
904 0x01,0x01,0xff,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
905 0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6a,0xa6,0x06,0xd0,0x33,0x18,0x64,
906 0xe2,0x69,0x82,0xee,0x6e,0x36,0x9e,0x9d,0x9a,0x0e,0x18,0xa8,0xac,0x9d,0x10,
907 0xed,0x01,0x3c,0xb9,0x61,0x04,0x62,0xf3,0x85,0x8f,0xcc,0x4f,0x2c,0x66,0x35,
908 0x54,0x25,0x45,0x8d,0x95,0x1c,0xd2,0x33,0xbe,0x2e,0xdd,0x7f,0x74,0xaf,0x03,
909 0x7b,0x86,0x63,0xb0,0xc9,0xe6,0xbd,0xc7,0x8e,0xde,0x03,0x18,0x98,0x82,0xc3,
910 0xbb,0xf8,0x15,0x99,0x1a,0xa9,0xdd,0xb9,0x5d,0xb9,0xbd,0x53,0x95,0x25,0x76,
911 0xfb,0x5c,0x53,0x90,0xea,0x01,0x0a,0xa0,0xb1,0xbf,0x09,0x1b,0x97,0x8f,0x40,
912 0xfa,0x85,0x12,0x74,0x01,0xdb,0xf6,0xdb,0x09,0xd6,0x5f,0x4f,0xd7,0x17,0xb4,
913 0xbf,0x9e,0x2f,0x86,0x52,0x5d,0x70,0x24,0x52,0x32,0x1e,0xa5,0x1d,0x39,0x8b,
914 0x66,0xf6,0xba,0x9b,0x69,0x8e,0x12,0x60,0xdb,0xb6,0xcf,0xe6,0x0d,0xd6,0x1c,
915 0x8f,0xd4,0x5b,0x4b,0x00,0xde,0x21,0x93,0xfb,0x6e,0xc7,0x3d,0xb4,0x66,0x0d,
916 0x29,0x0c,0x4e,0xe9,0x3f,0x94,0xd6,0xd6,0xdc,0xec,0xf8,0x53,0x3b,0x62,0xd5,
917 0x97,0x50,0x53,0x84,0x17,0xfe,0xe2,0xed,0x4c,0x23,0x0a,0x49,0xce,0x5b,0xe9,
918 0x70,0x31,0xc1,0x04,0x02,0x02,0x6c,0xb8,0x52,0xcd,0xc7,0x4e,0x70,0xb4,0x13,
919 0xd7,0xe0,0x92,0xba,0x44,0x1a,0x10,0x4c,0x6e,0x45,0xc6,0x86,0x04,0xc6,0x64,
920 0xd3,0x9c,0x6e,0xc1,0x9c,0xac,0x74,0x3d,0x77,0x06,0x5e,0x28,0x28,0x5c,0xf5,
921 0xe0,0x9c,0x19,0xd8,0xba,0x74,0x81,0x2d,0x67,0x77,0x93,0x8d,0xbf,0xd2,0x52,
922 0x00,0xe6,0xa5,0x38,0x4e,0x2e,0x73,0x66,0x7a };
923 static BYTE iTunesIssuer[] = {
924 0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
925 0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,
926 0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
927 0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,
928 0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
929 0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,
930 0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,
931 0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,0x73,
932 0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,
933 0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,
934 0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,
935 0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,
936 0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
937 0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,
938 0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,
940 static BYTE iTunesSerialNum[] = {
941 0x8d,0xf6,0x6a,0xdf,0xd2,0x40,0xfe,0xb6,0xa6,0x61,0x9b,0x9b,
942 0xe0,0xa0,0x1a,0x0f };
944 static void testFindCert(void)
947 PCCERT_CONTEXT context = NULL, subject;
949 CERT_INFO certInfo = { 0 };
950 CRYPT_HASH_BLOB blob;
951 BYTE otherSerialNumber[] = { 2 };
953 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
954 CERT_STORE_CREATE_NEW_FLAG, NULL);
955 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
959 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
960 bigCert, sizeof(bigCert), CERT_STORE_ADD_NEW, NULL);
961 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
963 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
964 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
965 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
967 /* This has the same name as bigCert */
968 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
969 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
970 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
974 context = CertFindCertificateInStore(NULL, 0, 0, 0, NULL, NULL);
977 /* Check first cert's there, by issuer */
978 certInfo.Subject.pbData = subjectName;
979 certInfo.Subject.cbData = sizeof(subjectName);
980 certInfo.SerialNumber.pbData = serialNum;
981 certInfo.SerialNumber.cbData = sizeof(serialNum);
982 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
983 CERT_FIND_ISSUER_NAME, &certInfo.Subject, NULL);
984 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
988 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
989 CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
990 ok(context != NULL, "Expected more than one cert\n");
993 context = CertFindCertificateInStore(store, X509_ASN_ENCODING,
994 0, CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
995 ok(context == NULL, "Expected precisely two certs\n");
999 /* Check second cert's there as well, by subject name */
1000 certInfo.Subject.pbData = subjectName2;
1001 certInfo.Subject.cbData = sizeof(subjectName2);
1002 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1003 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, NULL);
1004 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1008 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1009 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, context);
1010 ok(context == NULL, "Expected one cert only\n");
1013 /* Strange but true: searching for the subject cert requires you to set
1014 * the issuer, not the subject
1016 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1017 CERT_FIND_SUBJECT_CERT, &certInfo.Subject, NULL);
1018 ok(context == NULL, "Expected no certificate\n");
1019 certInfo.Subject.pbData = NULL;
1020 certInfo.Subject.cbData = 0;
1021 certInfo.Issuer.pbData = subjectName2;
1022 certInfo.Issuer.cbData = sizeof(subjectName2);
1023 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1024 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1025 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1029 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1030 CERT_FIND_SUBJECT_CERT, &certInfo.Subject, context);
1031 ok(context == NULL, "Expected one cert only\n");
1033 /* A non-matching serial number will not match. */
1034 certInfo.SerialNumber.pbData = otherSerialNumber;
1035 certInfo.SerialNumber.cbData = sizeof(otherSerialNumber);
1036 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1037 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1038 ok(context == NULL, "Expected no match\n");
1039 /* No serial number will not match */
1040 certInfo.SerialNumber.cbData = 0;
1041 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1042 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1043 ok(context == NULL, "Expected no match\n");
1044 /* A serial number still won't match if the name doesn't */
1045 certInfo.SerialNumber.pbData = serialNum;
1046 certInfo.SerialNumber.cbData = sizeof(serialNum);
1047 certInfo.Issuer.pbData = subjectName3;
1048 certInfo.Issuer.cbData = sizeof(subjectName3);
1049 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1050 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1051 ok(context == NULL, "Expected no match\n");
1053 /* The nice thing about hashes, they're unique */
1054 blob.pbData = bigCertHash;
1055 blob.cbData = sizeof(bigCertHash);
1056 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1057 CERT_FIND_SHA1_HASH, &blob, NULL);
1058 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1062 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1063 CERT_FIND_SHA1_HASH, &certInfo.Subject, context);
1064 ok(context == NULL, "Expected one cert only\n");
1067 CertCloseStore(store, 0);
1069 /* Another subject cert search, using iTunes's certs */
1070 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1071 CERT_STORE_CREATE_NEW_FLAG, NULL);
1072 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1073 iTunesCert0, sizeof(iTunesCert0), CERT_STORE_ADD_NEW, NULL);
1074 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1076 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1077 iTunesCert1, sizeof(iTunesCert1), CERT_STORE_ADD_NEW, NULL);
1078 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1080 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1081 iTunesCert2, sizeof(iTunesCert2), CERT_STORE_ADD_NEW, NULL);
1082 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1084 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1085 iTunesCert3, sizeof(iTunesCert3), CERT_STORE_ADD_NEW, &subject);
1086 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1089 /* The certInfo's issuer does not match any subject, but the serial
1090 * number does match a cert whose issuer matches certInfo's issuer.
1091 * This yields a match.
1093 certInfo.SerialNumber.cbData = sizeof(iTunesSerialNum);
1094 certInfo.SerialNumber.pbData = iTunesSerialNum;
1095 certInfo.Issuer.cbData = sizeof(iTunesIssuer);
1096 certInfo.Issuer.pbData = iTunesIssuer;
1097 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1098 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1099 ok(context != NULL, "Expected a match\n");
1102 ret = CertCompareCertificateName(context->dwCertEncodingType,
1103 &certInfo.Issuer, &context->pCertInfo->Subject);
1104 ok(!ret, "Expected subject name not to match\n");
1105 ret = CertCompareCertificateName(context->dwCertEncodingType,
1106 &certInfo.Issuer, &context->pCertInfo->Issuer);
1107 ok(ret, "Expected issuer name to match\n");
1108 ret = CertCompareIntegerBlob(&certInfo.SerialNumber,
1109 &context->pCertInfo->SerialNumber);
1110 ok(ret, "Expected serial number to match\n");
1111 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1112 CERT_FIND_SUBJECT_CERT, &certInfo, context);
1113 ok(context == NULL, "Expected one cert only\n");
1116 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1117 CERT_FIND_ISSUER_OF, subject, NULL);
1118 ok(context != NULL, "Expected an issuer\n");
1121 PCCERT_CONTEXT none = CertFindCertificateInStore(store,
1122 X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_OF, context, NULL);
1124 ok(!none, "Expected no parent of issuer\n");
1125 CertFreeCertificateContext(context);
1127 CertFreeCertificateContext(subject);
1128 CertCloseStore(store, 0);
1131 static void testGetSubjectCert(void)
1134 PCCERT_CONTEXT context1, context2;
1135 CERT_INFO info = { 0 };
1138 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1139 CERT_STORE_CREATE_NEW_FLAG, NULL);
1140 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1144 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1145 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1146 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1148 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1149 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, &context1);
1150 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1152 ok(context1 != NULL, "Expected a context\n");
1153 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1154 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1155 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1158 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1160 ok(!context2 && GetLastError() == E_INVALIDARG,
1161 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1162 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1164 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1165 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1166 info.SerialNumber.cbData = sizeof(serialNum);
1167 info.SerialNumber.pbData = serialNum;
1168 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1170 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1171 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1172 info.Issuer.cbData = sizeof(subjectName2);
1173 info.Issuer.pbData = subjectName2;
1174 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1176 ok(context2 != NULL,
1177 "CertGetSubjectCertificateFromStore failed: %08x\n", GetLastError());
1178 /* Not only should this find a context, but it should be the same
1179 * (same address) as context1.
1181 ok(context1 == context2, "Expected identical context addresses\n");
1182 CertFreeCertificateContext(context2);
1184 CertFreeCertificateContext(context1);
1185 CertCloseStore(store, 0);
1188 /* This expires in 1970 or so */
1189 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
1190 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
1191 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
1192 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1193 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1194 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1195 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
1196 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
1197 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1198 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1199 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1200 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
1201 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
1202 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
1203 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
1204 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
1205 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
1206 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
1207 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
1208 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
1209 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
1210 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
1211 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
1212 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
1213 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
1215 /* This expires in 2036 or so */
1216 static const BYTE childOfExpired[] = { 0x30, 0x81, 0xcc, 0x30, 0x78, 0xa0,
1217 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
1218 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d,
1219 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63,
1220 0x40, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e,
1221 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x35, 0x30, 0x35,
1222 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x35,
1223 0x30, 0x35, 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x30, 0x15, 0x31, 0x13,
1224 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e,
1225 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03,
1226 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
1227 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x20, 0x3b, 0xdb, 0x4d, 0x67, 0x50,
1228 0xec, 0x73, 0x9d, 0xf9, 0x85, 0x5d, 0x18, 0xe9, 0xb4, 0x98, 0xe3, 0x31, 0xb7,
1229 0x03, 0x0b, 0xc0, 0x39, 0x93, 0x56, 0x81, 0x0a, 0xfc, 0x78, 0xa8, 0x29, 0x42,
1230 0x5f, 0x69, 0xfb, 0xbc, 0x5b, 0xf2, 0xa6, 0x2a, 0xbe, 0x91, 0x2c, 0xfc, 0x89,
1231 0x69, 0x15, 0x18, 0x58, 0xe5, 0x02, 0x75, 0xf7, 0x2a, 0xb6, 0xa9, 0xfb, 0x47,
1232 0x6a, 0x6e, 0x0a, 0x9b, 0xe9, 0xdc };
1236 * A chain with two issuers, only one of whose dates is valid.
1238 static const BYTE chain10_0[] = {
1239 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1240 0x4a,0x30,0x3a,0x42,0xa2,0x5a,0xb3,0x93,0x4d,0x94,0x06,0xad,0x6d,0x1c,0x34,
1241 0xe6,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1242 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1243 0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1244 0x30,0x5a,0x17,0x0d,0x30,0x36,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1245 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1246 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1247 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1248 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1249 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1250 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1251 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1252 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1253 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1254 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1255 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1256 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1257 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1258 0x81,0x00,0x85,0x6e,0x35,0x2f,0x2c,0x51,0x4f,0xd6,0x2a,0xe4,0x9e,0xd0,0x4b,
1259 0xe6,0x90,0xfd,0xf7,0x20,0xad,0x76,0x3f,0x93,0xea,0x7f,0x0d,0x1f,0xb3,0x8e,
1260 0xfd,0xe0,0xe1,0xd6,0xd7,0x9c,0x7d,0x46,0x6b,0x15,0x5c,0xe6,0xc9,0x62,0x3b,
1261 0x70,0x4a,0x4b,0xb2,0x82,0xe3,0x55,0x0c,0xc4,0x90,0x44,0x06,0x6c,0x86,0x1c,
1262 0x6d,0x47,0x12,0xda,0x33,0x95,0x5d,0x98,0x43,0xcb,0x7c,0xfa,0x2b,0xee,0xc4,
1263 0x2d,0xc8,0x95,0x33,0x89,0x08,0x3f,0x9f,0x87,0xea,0x20,0x04,0xaf,0x58,0x4b,
1264 0x9d,0xc0,0x7c,0x0a,0x1b,0x05,0x31,0x3b,0xbb,0x13,0x58,0x2e,0x3f,0x61,0x6b,
1265 0x10,0xb4,0xeb,0xb9,0x1a,0x30,0xfd,0xea,0xca,0x29,0x99,0x5f,0x42,0x2b,0x00,
1266 0xb0,0x08,0xc3,0xf0,0xb6,0xd6,0x6b,0xf9,0x35,0x95 };
1267 static const BYTE chain10_1[] = {
1268 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1269 0xbf,0x99,0x4f,0x14,0x03,0x77,0x44,0xb8,0x49,0x02,0x70,0xa1,0xb8,0x9c,0xa7,
1270 0x24,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1271 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1272 0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1273 0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1274 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1275 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1276 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1277 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1278 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1279 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1280 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1281 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1282 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1283 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1284 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1285 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1286 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1287 0x81,0x00,0xa8,0xec,0x8c,0x34,0xe7,0x2c,0xdf,0x75,0x87,0xc4,0xf7,0xda,0x71,
1288 0x72,0x29,0xb2,0x48,0xa8,0x2a,0xec,0x7b,0x7d,0x19,0xb9,0x5f,0x1d,0xd9,0x91,
1289 0x2b,0xc4,0x28,0x7e,0xd6,0xb5,0x91,0x69,0xa5,0x8a,0x1a,0x1f,0x97,0x98,0x46,
1290 0x9d,0xdf,0x12,0xf6,0x45,0x62,0xad,0x60,0xb6,0xba,0xb0,0xfd,0xf5,0x9f,0xc6,
1291 0x98,0x05,0x4f,0x4d,0x48,0xdc,0xee,0x69,0xbe,0xb8,0xc4,0xc4,0xd7,0x1b,0xb1,
1292 0x1f,0x64,0xd6,0x45,0xa7,0xdb,0xb3,0x87,0x63,0x0f,0x54,0xe1,0x3a,0x6b,0x57,
1293 0x36,0xd7,0x68,0x65,0xcf,0xda,0x57,0x8d,0xcd,0x84,0x75,0x47,0x26,0x2c,0xef,
1294 0x1e,0x8f,0xc7,0x3b,0xee,0x5d,0x03,0xa6,0xdf,0x3a,0x20,0xb2,0xcc,0xc9,0x09,
1295 0x2c,0xfe,0x2b,0x79,0xb0,0xca,0x2c,0x9a,0x81,0x6b };
1296 static const BYTE chain7_1[] = {
1297 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
1298 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,
1299 0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,
1300 0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,
1301 0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,
1302 0x35,0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,
1303 0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,
1304 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,
1305 0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,
1306 0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,
1307 0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,
1308 0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,
1309 0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,
1310 0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,
1311 0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,
1312 0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,
1313 0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,
1314 0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1315 0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9f,0x69,0xfd,0x26,0xd5,0x4b,
1316 0xe0,0xab,0x12,0x21,0xb9,0xfc,0xf7,0xe0,0x0c,0x09,0x94,0xad,0x27,0xd7,0x9d,
1317 0xa3,0xcc,0x46,0x2a,0x25,0x9a,0x24,0xa7,0x31,0x58,0x78,0xf5,0xfc,0x30,0xe1,
1318 0x6d,0xfd,0x59,0xab,0xbe,0x69,0xa0,0xea,0xe3,0x7d,0x7a,0x7b,0xe5,0x85,0xeb,
1319 0x86,0x6a,0x84,0x3c,0x96,0x01,0x1a,0x70,0xa7,0xb8,0xcb,0xf2,0x11,0xe7,0x52,
1320 0x9c,0x58,0x2d,0xac,0x63,0xce,0x72,0x4b,0xad,0x62,0xa8,0x1d,0x75,0x96,0xe2,
1321 0x27,0xf5,0x6f,0xba,0x91,0xf8,0xf1,0xb0,0xbf,0x90,0x24,0x6d,0xba,0x5d,0xd7,
1322 0x39,0x63,0x3b,0x7c,0x04,0x5d,0x89,0x9d,0x1c,0xf2,0xf7,0xcc,0xdf,0x6e,0x8a,
1323 0x43,0xa9,0xdd,0x86,0x05,0xa2,0xf3,0x22,0x2d,0x1e,0x70,0xa1,0x59,0xd7,0xa5,
1326 static void testGetIssuerCert(void)
1329 PCCERT_CONTEXT parent, child, cert1, cert2;
1330 DWORD flags = 0xffffffff;
1331 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1332 CERT_STORE_CREATE_NEW_FLAG, NULL);
1334 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1336 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1337 expiredCert, sizeof(expiredCert), CERT_STORE_ADD_ALWAYS, NULL);
1338 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1341 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1342 childOfExpired, sizeof(childOfExpired), CERT_STORE_ADD_ALWAYS, &child);
1343 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1347 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, NULL);
1348 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, NULL);
1350 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, &flags);
1351 ok(!parent && GetLastError() == E_INVALIDARG,
1352 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1353 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, &flags);
1354 ok(!parent && GetLastError() == E_INVALIDARG,
1355 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1356 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1357 ok(!parent && GetLastError() == E_INVALIDARG,
1358 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1359 /* Confusing: the caller cannot set either of the
1360 * CERT_STORE_NO_*_FLAGs, as these are not checks,
1363 flags = CERT_STORE_NO_CRL_FLAG | CERT_STORE_NO_ISSUER_FLAG;
1364 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1365 ok(!parent && GetLastError() == E_INVALIDARG,
1366 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1367 /* Perform no checks */
1369 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1370 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1373 CertFreeCertificateContext(parent);
1374 /* Check revocation and signature only */
1375 flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG;
1376 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1377 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1379 /* Confusing: CERT_STORE_REVOCATION_FLAG succeeds when there is no CRL by
1380 * setting CERT_STORE_NO_CRL_FLAG.
1382 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
1383 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
1386 CertFreeCertificateContext(parent);
1387 /* Checking time validity is not productive, because while most Windows
1388 * versions return 0 (time valid) because the child is not expired,
1389 * Windows 2003 SP1 returns that it is expired. Thus the range of
1390 * possibilities is covered, and a test verifies nothing.
1393 CertFreeCertificateContext(child);
1394 CertCloseStore(store, 0);
1397 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1398 CERT_STORE_CREATE_NEW_FLAG, NULL);
1399 /* With only the child certificate, no issuer will be found */
1400 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1401 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1402 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1403 ok(parent == NULL, "Expected no issuer\n");
1404 /* Adding an issuer allows one (and only one) issuer to be found */
1405 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1406 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert1);
1407 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1408 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1409 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1410 ok(parent == NULL, "Expected only one issuer\n");
1411 /* Adding a second issuer allows two issuers to be found - and the second
1412 * issuer is found before the first, implying certs are added to the head
1415 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1416 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert2);
1417 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1418 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1419 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1420 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1421 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1422 ok(parent == NULL, "Expected no more than two issuers\n");
1423 CertFreeCertificateContext(child);
1424 CertFreeCertificateContext(cert1);
1425 CertFreeCertificateContext(cert2);
1426 CertCloseStore(store, 0);
1428 /* Repeat the test, reversing the order in which issuers are added,
1429 * to show it's order-dependent.
1431 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1432 CERT_STORE_CREATE_NEW_FLAG, NULL);
1433 /* With only the child certificate, no issuer will be found */
1434 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1435 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1436 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1437 ok(parent == NULL, "Expected no issuer\n");
1438 /* Adding an issuer allows one (and only one) issuer to be found */
1439 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1440 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert1);
1441 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1442 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1443 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1444 ok(parent == NULL, "Expected only one issuer\n");
1445 /* Adding a second issuer allows two issuers to be found - and the second
1446 * issuer is found before the first, implying certs are added to the head
1449 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1450 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert2);
1451 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1452 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1453 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1454 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1455 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1456 ok(parent == NULL, "Expected no more than two issuers\n");
1457 CertFreeCertificateContext(child);
1458 CertFreeCertificateContext(cert1);
1459 CertFreeCertificateContext(cert2);
1460 CertCloseStore(store, 0);
1463 static void testCryptHashCert(void)
1465 static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b,
1466 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07,
1468 static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee,
1469 0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8,
1471 static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:";
1474 DWORD hashLen = sizeof(hash);
1476 /* NULL buffer and nonzero length crashes
1477 ret = CryptHashCertificate(0, 0, 0, NULL, size, hash, &hashLen);
1478 empty hash length also crashes
1479 ret = CryptHashCertificate(0, 0, 0, buf, size, hash, NULL);
1481 /* Test empty hash */
1482 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), NULL,
1484 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1485 ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen);
1486 /* Test with empty buffer */
1487 ret = CryptHashCertificate(0, 0, 0, NULL, 0, hash, &hashLen);
1488 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1489 ok(!memcmp(hash, emptyHash, sizeof(emptyHash)),
1490 "Unexpected hash of nothing\n");
1491 /* Test a known value */
1492 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), hash,
1494 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1495 ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
1498 static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen,
1499 const BYTE *sig, unsigned int sigLen)
1502 BOOL ret = CryptCreateHash(csp, CALG_SHA1, 0, 0, &hash);
1504 ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
1508 DWORD mySigSize = sizeof(mySig);
1510 ret = CryptHashData(hash, toSign, toSignLen, 0);
1511 ok(ret, "CryptHashData failed: %08x\n", GetLastError());
1512 /* use the A variant so the test can run on Win9x */
1513 ret = CryptSignHashA(hash, AT_SIGNATURE, NULL, 0, mySig, &mySigSize);
1514 ok(ret, "CryptSignHash failed: %08x\n", GetLastError());
1517 ok(mySigSize == sigLen, "Expected sig length %d, got %d\n",
1519 ok(!memcmp(mySig, sig, sigLen), "Unexpected signature\n");
1521 CryptDestroyHash(hash);
1525 /* Tests signing the certificate described by toBeSigned with the CSP passed in,
1526 * using the algorithm with OID sigOID. The CSP is assumed to be empty, and a
1527 * keyset named AT_SIGNATURE will be added to it. The signing key will be
1528 * stored in *key, and the signature will be stored in sig. sigLen should be
1529 * at least 64 bytes.
1531 static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1532 LPCSTR sigOID, HCRYPTKEY *key, BYTE *sig, DWORD *sigLen)
1536 CRYPT_ALGORITHM_IDENTIFIER algoID = { NULL, { 0, NULL } };
1539 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1540 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, &size);
1541 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1542 NULL, NULL, NULL, &size);
1544 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1545 &algoID, NULL, NULL, &size);
1546 ok(!ret && GetLastError() == NTE_BAD_ALGID,
1547 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1548 algoID.pszObjId = (LPSTR)sigOID;
1549 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1550 &algoID, NULL, NULL, &size);
1551 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1552 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1553 ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData,
1554 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1555 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1556 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1558 /* No keys exist in the new CSP yet.. */
1559 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1560 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1561 ok(!ret && (GetLastError() == NTE_BAD_KEYSET || GetLastError() ==
1562 NTE_NO_KEY), "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %08x\n",
1564 ret = CryptGenKey(csp, AT_SIGNATURE, 0, key);
1565 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1568 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1569 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1570 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1571 ok(size <= *sigLen, "Expected size <= %d, got %d\n", *sigLen, size);
1574 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1575 toBeSigned->cbData, &algoID, NULL, sig, &size);
1576 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1580 verifySig(csp, toBeSigned->pbData, toBeSigned->cbData, sig,
1587 static void testVerifyCertSig(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1588 LPCSTR sigOID, const BYTE *sig, DWORD sigLen)
1590 CERT_SIGNED_CONTENT_INFO info;
1595 if (!pCryptVerifyCertificateSignatureEx)
1597 skip("no CryptVerifyCertificateSignatureEx support\n");
1600 if (!pCryptEncodeObjectEx)
1602 skip("no CryptEncodeObjectEx support\n");
1605 ret = pCryptVerifyCertificateSignatureEx(0, 0, 0, NULL, 0, NULL, 0, NULL);
1606 ok(!ret && GetLastError() == E_INVALIDARG,
1607 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1608 ret = pCryptVerifyCertificateSignatureEx(csp, 0, 0, NULL, 0, NULL, 0, NULL);
1609 ok(!ret && GetLastError() == E_INVALIDARG,
1610 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1611 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 0, NULL, 0,
1613 ok(!ret && GetLastError() == E_INVALIDARG,
1614 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1616 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1617 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, NULL, 0, NULL, 0, NULL);
1619 info.ToBeSigned.cbData = toBeSigned->cbData;
1620 info.ToBeSigned.pbData = toBeSigned->pbData;
1621 info.SignatureAlgorithm.pszObjId = (LPSTR)sigOID;
1622 info.SignatureAlgorithm.Parameters.cbData = 0;
1623 info.Signature.cbData = sigLen;
1624 info.Signature.pbData = (BYTE *)sig;
1625 info.Signature.cUnusedBits = 0;
1626 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT, &info,
1627 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&cert, &size);
1628 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1631 CRYPT_DATA_BLOB certBlob = { 0, NULL };
1632 PCERT_PUBLIC_KEY_INFO pubKeyInfo = NULL;
1634 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1635 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1636 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
1637 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
1638 certBlob.cbData = 1;
1639 certBlob.pbData = (void *)0xdeadbeef;
1640 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1641 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1642 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1643 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1644 certBlob.cbData = size;
1645 certBlob.pbData = cert;
1646 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1647 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1648 ok(!ret && GetLastError() == E_INVALIDARG,
1649 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1650 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1651 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1652 CRYPT_VERIFY_CERT_SIGN_ISSUER_NULL, NULL, 0, NULL);
1653 ok(!ret && GetLastError() == E_INVALIDARG,
1654 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1656 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1657 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1658 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, NULL, 0, NULL);
1660 CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
1661 (LPSTR)sigOID, 0, NULL, NULL, &size);
1662 pubKeyInfo = HeapAlloc(GetProcessHeap(), 0, size);
1665 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
1666 X509_ASN_ENCODING, (LPSTR)sigOID, 0, NULL, pubKeyInfo, &size);
1667 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
1670 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1671 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1672 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pubKeyInfo, 0, NULL);
1673 ok(ret, "CryptVerifyCertificateSignatureEx failed: %08x\n",
1676 HeapFree(GetProcessHeap(), 0, pubKeyInfo);
1682 static BYTE emptyCert[] = { 0x30, 0x00 };
1684 static void testCertSigs(void)
1687 CRYPT_DATA_BLOB toBeSigned = { sizeof(emptyCert), emptyCert };
1691 DWORD sigSize = sizeof(sig);
1693 /* Just in case a previous run failed, delete this thing */
1694 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1695 CRYPT_DELETEKEYSET);
1696 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1698 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1700 testSignCert(csp, &toBeSigned, szOID_RSA_SHA1RSA, &key, sig, &sigSize);
1701 testVerifyCertSig(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize);
1703 CryptDestroyKey(key);
1704 CryptReleaseContext(csp, 0);
1705 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1706 CRYPT_DELETEKEYSET);
1709 static const BYTE md5SignedEmptyCert[] = {
1710 0x30,0x56,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1711 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
1712 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
1713 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1714 0x0d,0x02,0x05,0x05,0x00,0x03,0x11,0x00,0xfb,0x0f,0x66,0x82,0x66,0xd9,0xe5,0xf8,
1715 0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
1716 static const BYTE md5SignedEmptyCertNoNull[] = {
1717 0x30,0x54,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1718 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
1719 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
1720 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1721 0x0d,0x02,0x05,0x03,0x11,0x00,0x04,0xd9,0xa5,0xe1,0x2b,0x55,0xa2,0xd8,0xf8,0xe5,
1722 0xd9,0x66,0x82,0x66,0x0f,0xfb };
1724 static void testSignAndEncodeCert(void)
1726 static char oid_rsa_md5rsa[] = szOID_RSA_MD5RSA;
1727 static char oid_rsa_md5[] = szOID_RSA_MD5;
1730 CRYPT_ALGORITHM_IDENTIFIER algID = { 0 };
1731 CERT_INFO info = { 0 };
1734 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1736 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1739 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, &algID, NULL, NULL,
1741 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1742 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1743 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, NULL, NULL,
1744 &algID, NULL, NULL, &size);
1745 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1746 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1747 ret = CryptSignAndEncodeCertificate(0, 0, 0, X509_CERT_TO_BE_SIGNED, NULL,
1748 &algID, NULL, NULL, &size);
1749 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1750 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1751 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1752 X509_CERT_TO_BE_SIGNED, NULL, &algID, NULL, NULL, &size);
1753 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1754 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1756 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1757 X509_CERT_TO_BE_SIGNED, &info, NULL, NULL, NULL, &size);
1759 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1760 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1761 ok(!ret && GetLastError() == NTE_BAD_ALGID,
1762 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1763 algID.pszObjId = oid_rsa_md5rsa;
1764 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1765 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1766 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1767 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1768 algID.pszObjId = oid_rsa_md5;
1769 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1770 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1771 ok(ret, "CryptSignAndEncodeCertificate failed: %08x\n", GetLastError());
1774 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
1778 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1779 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, buf, &size);
1780 ok(ret, "CryptSignAndEncodeCertificate failed: %08x\n",
1782 /* Tricky: because the NULL parameters may either be omitted or
1783 * included as an asn.1-encoded NULL (0x05,0x00), two different
1784 * values are allowed.
1786 ok(size == sizeof(md5SignedEmptyCert) ||
1787 size == sizeof(md5SignedEmptyCertNoNull), "Unexpected size %d\n",
1789 if (size == sizeof(md5SignedEmptyCert))
1790 ok(!memcmp(buf, md5SignedEmptyCert, size),
1791 "Unexpected value\n");
1792 else if (size == sizeof(md5SignedEmptyCertNoNull))
1793 ok(!memcmp(buf, md5SignedEmptyCertNoNull, size),
1794 "Unexpected value\n");
1795 HeapFree(GetProcessHeap(), 0, buf);
1800 static void testCreateSelfSignCert(void)
1802 PCCERT_CONTEXT context;
1803 CERT_NAME_BLOB name = { sizeof(subjectName), subjectName };
1807 CRYPT_KEY_PROV_INFO info;
1809 if (!pCertCreateSelfSignCertificate)
1811 skip("CertCreateSelfSignCertificate() is not available\n");
1816 context = pCertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL,
1818 * Calling this with no first parameter creates a new key container, which
1819 * lasts beyond the test, so I don't test that. Nb: the generated key
1821 context = pCertCreateSelfSignCertificate(0, &name, 0, NULL, NULL, NULL, NULL,
1826 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1827 CRYPT_DELETEKEYSET);
1828 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1830 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1832 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1834 ok(!context && GetLastError() == NTE_NO_KEY,
1835 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1836 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
1837 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1840 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1842 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1847 PCRYPT_KEY_PROV_INFO info;
1849 /* The context must have a key provider info property */
1850 ret = CertGetCertificateContextProperty(context,
1851 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1852 ok(ret && size, "Expected non-zero key provider info\n");
1855 info = HeapAlloc(GetProcessHeap(), 0, size);
1858 ret = CertGetCertificateContextProperty(context,
1859 CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1860 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1864 /* Sanity-check the key provider */
1865 ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1866 "Unexpected key container\n");
1867 ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1868 "Unexpected provider\n");
1869 ok(info->dwKeySpec == AT_SIGNATURE,
1870 "Expected AT_SIGNATURE, got %d\n", info->dwKeySpec);
1872 HeapFree(GetProcessHeap(), 0, info);
1876 CertFreeCertificateContext(context);
1879 CryptDestroyKey(key);
1882 CryptReleaseContext(csp, 0);
1883 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1884 CRYPT_DELETEKEYSET);
1886 /* do the same test with AT_KEYEXCHANGE and key info*/
1887 memset(&info,0,sizeof(info));
1888 info.dwProvType = PROV_RSA_FULL;
1889 info.dwKeySpec = AT_KEYEXCHANGE;
1890 info.pwszProvName = (LPWSTR) MS_DEF_PROV_W;
1891 info.pwszContainerName = cspNameW;
1892 context = pCertCreateSelfSignCertificate(0, &name, 0, &info, NULL, NULL,
1894 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1899 PCRYPT_KEY_PROV_INFO info;
1901 /* The context must have a key provider info property */
1902 ret = CertGetCertificateContextProperty(context,
1903 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1904 ok(ret && size, "Expected non-zero key provider info\n");
1907 info = HeapAlloc(GetProcessHeap(), 0, size);
1910 ret = CertGetCertificateContextProperty(context,
1911 CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1912 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1916 /* Sanity-check the key provider */
1917 ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1918 "Unexpected key container\n");
1919 ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1920 "Unexpected provider\n");
1921 ok(info->dwKeySpec == AT_KEYEXCHANGE,
1922 "Expected AT_KEYEXCHANGE, got %d\n", info->dwKeySpec);
1924 HeapFree(GetProcessHeap(), 0, info);
1928 CertFreeCertificateContext(context);
1931 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1932 CRYPT_DELETEKEYSET);
1935 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
1936 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
1938 static void testKeyUsage(void)
1941 PCCERT_CONTEXT context;
1944 /* Test base cases */
1945 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, NULL);
1946 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1947 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1949 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
1950 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1951 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1953 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
1954 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1955 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1957 ret = CertSetEnhancedKeyUsage(NULL, NULL);
1958 usage.cUsageIdentifier = 0;
1959 ret = CertSetEnhancedKeyUsage(NULL, &usage);
1961 /* Test with a cert with no enhanced key usage extension */
1962 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
1964 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
1968 static const char oid[] = "1.2.3.4";
1969 BYTE buf[sizeof(CERT_ENHKEY_USAGE) + 2 * (sizeof(LPSTR) + sizeof(oid))];
1970 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
1972 ret = CertGetEnhancedKeyUsage(context, 0, NULL, NULL);
1973 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1974 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1976 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &size);
1979 /* Windows 2000, ME, or later: even though it succeeded, we expect
1980 * CRYPT_E_NOT_FOUND, which indicates there is no enhanced key
1981 * usage set for this cert (which implies it's valid for all uses.)
1983 ok(GetLastError() == CRYPT_E_NOT_FOUND,
1984 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1985 ok(size == sizeof(CERT_ENHKEY_USAGE), "Wrong size %d\n", size);
1986 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
1987 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
1988 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
1989 pUsage->cUsageIdentifier);
1993 /* Windows NT, 95, or 98: it fails, and the last error is
1994 * CRYPT_E_NOT_FOUND.
1996 ok(GetLastError() == CRYPT_E_NOT_FOUND,
1997 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1999 /* I can add a usage identifier when no key usage has been set */
2000 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2001 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2004 ret = CertGetEnhancedKeyUsage(context,
2005 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2006 ok(ret && GetLastError() == 0,
2007 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2008 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2009 pUsage->cUsageIdentifier);
2010 if (pUsage->cUsageIdentifier)
2011 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2012 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2013 /* Now set an empty key usage */
2014 pUsage->cUsageIdentifier = 0;
2015 ret = CertSetEnhancedKeyUsage(context, pUsage);
2016 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2017 /* Shouldn't find it in the cert */
2019 ret = CertGetEnhancedKeyUsage(context,
2020 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2021 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2022 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2023 /* Should find it as an extended property */
2024 ret = CertGetEnhancedKeyUsage(context,
2025 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2026 ok(ret && GetLastError() == 0,
2027 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2028 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2029 pUsage->cUsageIdentifier);
2030 /* Should find it as either */
2031 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2032 ok(ret && GetLastError() == 0,
2033 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2034 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2035 pUsage->cUsageIdentifier);
2036 /* Add a usage identifier */
2037 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2038 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2041 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2042 ok(ret && GetLastError() == 0,
2043 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2044 ok(pUsage->cUsageIdentifier == 1, "Expected 1 identifier, got %d\n",
2045 pUsage->cUsageIdentifier);
2046 if (pUsage->cUsageIdentifier)
2047 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2048 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2049 /* Yep, I can re-add the same usage identifier */
2050 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2051 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2054 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2055 ok(ret && GetLastError() == 0,
2056 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2057 ok(pUsage->cUsageIdentifier == 2, "Expected 2 identifiers, got %d\n",
2058 pUsage->cUsageIdentifier);
2059 if (pUsage->cUsageIdentifier)
2060 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2061 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2062 if (pUsage->cUsageIdentifier >= 2)
2063 ok(!strcmp(pUsage->rgpszUsageIdentifier[1], oid),
2064 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[1]);
2065 /* Now set a NULL extended property--this deletes the property. */
2066 ret = CertSetEnhancedKeyUsage(context, NULL);
2067 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2068 SetLastError(0xbaadcafe);
2070 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2071 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2072 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2074 CertFreeCertificateContext(context);
2076 /* Now test with a cert with an enhanced key usage extension */
2077 context = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2078 sizeof(certWithUsage));
2079 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2084 DWORD bufSize = 0, i;
2086 /* The size may depend on what flags are used to query it, so I
2087 * realloc the buffer for each test.
2089 ret = CertGetEnhancedKeyUsage(context,
2090 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2091 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2092 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2095 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2097 /* Should find it in the cert */
2099 ret = CertGetEnhancedKeyUsage(context,
2100 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2101 ok(ret && GetLastError() == 0,
2102 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2103 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2104 pUsage->cUsageIdentifier);
2105 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2106 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2107 "Expected %s, got %s\n", keyUsages[i],
2108 pUsage->rgpszUsageIdentifier[i]);
2109 HeapFree(GetProcessHeap(), 0, buf);
2111 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2112 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2113 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2116 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2118 /* Should find it as either */
2120 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2121 /* In Windows, GetLastError returns CRYPT_E_NOT_FOUND not found
2122 * here, even though the return is successful and the usage id
2123 * count is positive. I don't enforce that here.
2126 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2127 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2128 pUsage->cUsageIdentifier);
2129 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2130 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2131 "Expected %s, got %s\n", keyUsages[i],
2132 pUsage->rgpszUsageIdentifier[i]);
2133 HeapFree(GetProcessHeap(), 0, buf);
2135 /* Shouldn't find it as an extended property */
2136 ret = CertGetEnhancedKeyUsage(context,
2137 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &size);
2138 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2139 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2140 /* Adding a usage identifier overrides the cert's usage!? */
2141 ret = CertAddEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2142 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2144 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2145 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2146 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2149 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2151 /* Should find it as either */
2153 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2155 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2156 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2157 pUsage->cUsageIdentifier);
2158 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], szOID_RSA_RSA),
2159 "Expected %s, got %s\n", szOID_RSA_RSA,
2160 pUsage->rgpszUsageIdentifier[0]);
2161 HeapFree(GetProcessHeap(), 0, buf);
2163 /* But querying the cert directly returns its usage */
2164 ret = CertGetEnhancedKeyUsage(context,
2165 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2166 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2167 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2170 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2173 ret = CertGetEnhancedKeyUsage(context,
2174 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2176 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2177 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2178 pUsage->cUsageIdentifier);
2179 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2180 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2181 "Expected %s, got %s\n", keyUsages[i],
2182 pUsage->rgpszUsageIdentifier[i]);
2183 HeapFree(GetProcessHeap(), 0, buf);
2185 /* And removing the only usage identifier in the extended property
2186 * results in the cert's key usage being found.
2188 ret = CertRemoveEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2189 ok(ret, "CertRemoveEnhancedKeyUsage failed: %08x\n", GetLastError());
2190 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2191 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2192 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2195 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2197 /* Should find it as either */
2199 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2201 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2202 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2203 pUsage->cUsageIdentifier);
2204 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2205 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2206 "Expected %s, got %s\n", keyUsages[i],
2207 pUsage->rgpszUsageIdentifier[i]);
2208 HeapFree(GetProcessHeap(), 0, buf);
2211 CertFreeCertificateContext(context);
2215 static const BYTE cert2WithUsage[] = {
2216 0x30,0x81,0x89,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2217 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2218 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2219 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2220 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2221 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2222 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x25,0x30,0x23,
2223 0x30,0x21,0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x17,0x30,0x15,0x06,
2224 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x2a,0x86,0x48,0x86,
2225 0xf7,0x0d,0x01,0x01,0x01 };
2227 static void testGetValidUsages(void)
2229 static const LPCSTR expectedOIDs[] = {
2230 "1.3.6.1.5.5.7.3.3",
2231 "1.3.6.1.5.5.7.3.2",
2232 "1.2.840.113549.1.1.1",
2234 static const LPCSTR expectedOIDs2[] = {
2235 "1.3.6.1.5.5.7.3.2",
2236 "1.2.840.113549.1.1.1",
2242 PCCERT_CONTEXT contexts[3];
2244 if (!pCertGetValidUsages)
2246 skip("CertGetValidUsages() is not available\n");
2251 ret = pCertGetValidUsages(0, NULL, NULL, NULL, NULL);
2252 ret = pCertGetValidUsages(0, NULL, NULL, NULL, &size);
2255 numOIDs = size = 0xdeadbeef;
2256 SetLastError(0xdeadbeef);
2257 ret = pCertGetValidUsages(1, &contexts[0], &numOIDs, NULL, &size);
2258 ok(ret, "CertGetValidUsages failed: %d\n", GetLastError());
2259 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2260 ok(size == 0, "Expected size 0, got %d\n", size);
2261 contexts[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2263 contexts[1] = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2264 sizeof(certWithUsage));
2265 contexts[2] = CertCreateCertificateContext(X509_ASN_ENCODING,
2266 cert2WithUsage, sizeof(cert2WithUsage));
2267 numOIDs = size = 0xdeadbeef;
2268 ret = pCertGetValidUsages(0, NULL, &numOIDs, NULL, &size);
2269 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2270 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2271 ok(size == 0, "Expected size 0, got %d\n", size);
2272 numOIDs = size = 0xdeadbeef;
2273 ret = pCertGetValidUsages(1, contexts, &numOIDs, NULL, &size);
2274 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2275 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2276 ok(size == 0, "Expected size 0, got %d\n", size);
2277 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, NULL, &size);
2278 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2279 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2280 ok(size, "Expected non-zero size\n");
2281 oids = HeapAlloc(GetProcessHeap(), 0, size);
2285 DWORD smallSize = 1;
2287 SetLastError(0xdeadbeef);
2288 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &smallSize);
2289 ok(!ret && GetLastError() == ERROR_MORE_DATA,
2290 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
2291 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2292 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2293 for (i = 0; i < numOIDs; i++)
2294 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2296 HeapFree(GetProcessHeap(), 0, oids);
2298 numOIDs = size = 0xdeadbeef;
2299 /* Oddly enough, this crashes when the number of contexts is not 1:
2300 ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2301 * but setting size to 0 allows it to succeed:
2304 ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2305 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2306 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2307 ok(size, "Expected non-zero size\n");
2308 oids = HeapAlloc(GetProcessHeap(), 0, size);
2313 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2314 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2315 for (i = 0; i < numOIDs; i++)
2316 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2318 HeapFree(GetProcessHeap(), 0, oids);
2320 numOIDs = 0xdeadbeef;
2322 ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, NULL, &size);
2323 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2324 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2325 ok(size, "Expected non-zero size\n");
2326 oids = HeapAlloc(GetProcessHeap(), 0, size);
2331 ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, oids, &size);
2332 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2333 for (i = 0; i < numOIDs; i++)
2334 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2336 HeapFree(GetProcessHeap(), 0, oids);
2338 numOIDs = 0xdeadbeef;
2340 ret = pCertGetValidUsages(3, contexts, &numOIDs, NULL, &size);
2341 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2342 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2343 ok(size, "Expected non-zero size\n");
2344 oids = HeapAlloc(GetProcessHeap(), 0, size);
2349 ret = pCertGetValidUsages(3, contexts, &numOIDs, oids, &size);
2350 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2351 for (i = 0; i < numOIDs; i++)
2352 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2354 HeapFree(GetProcessHeap(), 0, oids);
2356 CertFreeCertificateContext(contexts[0]);
2357 CertFreeCertificateContext(contexts[1]);
2358 CertFreeCertificateContext(contexts[2]);
2361 static void testCompareCertName(void)
2363 static BYTE bogus[] = { 1, 2, 3, 4 };
2364 static BYTE bogusPrime[] = { 0, 1, 2, 3, 4 };
2365 static BYTE emptyPrime[] = { 0x30, 0x00, 0x01 };
2367 CERT_NAME_BLOB blob1, blob2;
2370 ret = CertCompareCertificateName(0, NULL, NULL);
2372 /* An empty name checks against itself.. */
2373 blob1.pbData = emptyCert;
2374 blob1.cbData = sizeof(emptyCert);
2375 ret = CertCompareCertificateName(0, &blob1, &blob1);
2376 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2377 /* It doesn't have to be a valid encoded name.. */
2378 blob1.pbData = bogus;
2379 blob1.cbData = sizeof(bogus);
2380 ret = CertCompareCertificateName(0, &blob1, &blob1);
2381 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2382 /* Leading zeroes matter.. */
2383 blob2.pbData = bogusPrime;
2384 blob2.cbData = sizeof(bogusPrime);
2385 ret = CertCompareCertificateName(0, &blob1, &blob2);
2386 ok(!ret, "Expected failure\n");
2387 /* As do trailing extra bytes. */
2388 blob2.pbData = emptyPrime;
2389 blob2.cbData = sizeof(emptyPrime);
2390 ret = CertCompareCertificateName(0, &blob1, &blob2);
2391 ok(!ret, "Expected failure\n");
2394 static BYTE int1[] = { 0x88, 0xff, 0xff, 0xff };
2395 static BYTE int2[] = { 0x88, 0xff };
2396 static BYTE int3[] = { 0x23, 0xff };
2397 static BYTE int4[] = { 0x7f, 0x00 };
2398 static BYTE int5[] = { 0x7f };
2399 static BYTE int6[] = { 0x80, 0x00, 0x00, 0x00 };
2400 static BYTE int7[] = { 0x80, 0x00 };
2402 static struct IntBlobTest
2404 CRYPT_INTEGER_BLOB blob1;
2405 CRYPT_INTEGER_BLOB blob2;
2408 { { sizeof(int1), int1 }, { sizeof(int2), int2 }, TRUE },
2409 { { sizeof(int3), int3 }, { sizeof(int3), int3 }, TRUE },
2410 { { sizeof(int4), int4 }, { sizeof(int5), int5 }, TRUE },
2411 { { sizeof(int6), int6 }, { sizeof(int7), int7 }, TRUE },
2412 { { sizeof(int1), int1 }, { sizeof(int7), int7 }, FALSE },
2415 static void testCompareIntegerBlob(void)
2420 for (i = 0; i < sizeof(intBlobs) / sizeof(intBlobs[0]); i++)
2422 ret = CertCompareIntegerBlob(&intBlobs[i].blob1, &intBlobs[i].blob2);
2423 ok(ret == intBlobs[i].areEqual,
2424 "%d: expected blobs %s compare\n", i, intBlobs[i].areEqual ?
2429 static void testComparePublicKeyInfo(void)
2432 CERT_PUBLIC_KEY_INFO info1 = { { 0 } }, info2 = { { 0 } };
2433 static CHAR oid_rsa_rsa[] = szOID_RSA_RSA;
2434 static CHAR oid_rsa_sha1rsa[] = szOID_RSA_SHA1RSA;
2435 static CHAR oid_x957_dsa[] = szOID_X957_DSA;
2436 static BYTE bits1[] = { 1, 0 };
2437 static BYTE bits2[] = { 0 };
2438 static BYTE bits3[] = { 1 };
2441 ret = CertComparePublicKeyInfo(0, NULL, NULL);
2443 /* Empty public keys compare */
2444 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2445 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2446 /* Different OIDs appear to compare */
2447 info1.Algorithm.pszObjId = oid_rsa_rsa;
2448 info2.Algorithm.pszObjId = oid_rsa_sha1rsa;
2449 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2450 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2451 info2.Algorithm.pszObjId = oid_x957_dsa;
2452 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2453 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2454 info1.PublicKey.cbData = sizeof(bits1);
2455 info1.PublicKey.pbData = bits1;
2456 info1.PublicKey.cUnusedBits = 0;
2457 info2.PublicKey.cbData = sizeof(bits1);
2458 info2.PublicKey.pbData = bits1;
2459 info2.PublicKey.cUnusedBits = 0;
2460 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2461 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2462 /* Even though they compare in their used bits, these do not compare */
2463 info1.PublicKey.cbData = sizeof(bits2);
2464 info1.PublicKey.pbData = bits2;
2465 info1.PublicKey.cUnusedBits = 0;
2466 info2.PublicKey.cbData = sizeof(bits3);
2467 info2.PublicKey.pbData = bits3;
2468 info2.PublicKey.cUnusedBits = 1;
2469 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2470 /* Simple (non-comparing) case */
2471 ok(!ret, "Expected keys not to compare\n");
2472 info2.PublicKey.cbData = sizeof(bits1);
2473 info2.PublicKey.pbData = bits1;
2474 info2.PublicKey.cUnusedBits = 0;
2475 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2476 ok(!ret, "Expected keys not to compare\n");
2479 static void testHashPublicKeyInfo(void)
2482 CERT_PUBLIC_KEY_INFO info = { { 0 } };
2486 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, NULL);
2487 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, &info, NULL, NULL);
2489 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, &len);
2490 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2491 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2492 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, NULL, NULL, &len);
2493 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2494 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2495 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, NULL, &len);
2496 ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2497 ok(len == 16, "Expected hash size 16, got %d\n", len);
2500 static const BYTE emptyHash[] = { 0xb8,0x51,0x3a,0x31,0x0e,0x9f,0x40,
2501 0x36,0x9c,0x92,0x45,0x1b,0x9d,0xc8,0xf9,0xf6 };
2504 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, buf,
2506 ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2507 ok(!memcmp(buf, emptyHash, len), "Unexpected hash\n");
2511 static void testCompareCert(void)
2513 CERT_INFO info1 = { 0 }, info2 = { 0 };
2517 ret = CertCompareCertificate(X509_ASN_ENCODING, NULL, NULL);
2520 /* Certs with the same issuer and serial number are equal, even if they
2521 * differ in other respects (like subject).
2523 info1.SerialNumber.pbData = serialNum;
2524 info1.SerialNumber.cbData = sizeof(serialNum);
2525 info1.Issuer.pbData = subjectName;
2526 info1.Issuer.cbData = sizeof(subjectName);
2527 info1.Subject.pbData = subjectName2;
2528 info1.Subject.cbData = sizeof(subjectName2);
2529 info2.SerialNumber.pbData = serialNum;
2530 info2.SerialNumber.cbData = sizeof(serialNum);
2531 info2.Issuer.pbData = subjectName;
2532 info2.Issuer.cbData = sizeof(subjectName);
2533 info2.Subject.pbData = subjectName;
2534 info2.Subject.cbData = sizeof(subjectName);
2535 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2536 ok(ret, "Expected certs to be equal\n");
2538 info2.Issuer.pbData = subjectName2;
2539 info2.Issuer.cbData = sizeof(subjectName2);
2540 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2541 ok(!ret, "Expected certs not to be equal\n");
2544 static void testVerifySubjectCert(void)
2548 PCCERT_CONTEXT context1, context2;
2551 ret = CertVerifySubjectCertificateContext(NULL, NULL, NULL);
2554 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2555 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2557 flags = CERT_STORE_NO_CRL_FLAG;
2558 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2559 ok(!ret && GetLastError() == E_INVALIDARG,
2560 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2563 context1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2565 ret = CertVerifySubjectCertificateContext(NULL, context1, &flags);
2566 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2568 ret = CertVerifySubjectCertificateContext(context1, NULL, &flags);
2569 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2571 ret = CertVerifySubjectCertificateContext(context1, context1, &flags);
2572 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2575 context2 = CertCreateCertificateContext(X509_ASN_ENCODING,
2576 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject));
2577 SetLastError(0xdeadbeef);
2578 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2579 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2581 flags = CERT_STORE_REVOCATION_FLAG;
2582 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2583 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2585 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
2586 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
2588 flags = CERT_STORE_SIGNATURE_FLAG;
2589 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2590 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2592 ok(flags == CERT_STORE_SIGNATURE_FLAG,
2593 "Expected CERT_STORE_SIGNATURE_FLAG, got %08x\n", flags);
2594 CertFreeCertificateContext(context2);
2596 CertFreeCertificateContext(context1);
2599 static void testVerifyRevocation(void)
2602 CERT_REVOCATION_STATUS status = { 0 };
2603 PCCERT_CONTEXT cert = CertCreateCertificateContext(X509_ASN_ENCODING,
2604 bigCert, sizeof(bigCert));
2607 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL);
2609 SetLastError(0xdeadbeef);
2610 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2611 ok(!ret && GetLastError() == E_INVALIDARG,
2612 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2613 status.cbSize = sizeof(status);
2614 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2615 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2616 ret = CertVerifyRevocation(0, 2, 0, NULL, 0, NULL, &status);
2617 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2618 ret = CertVerifyRevocation(2, 0, 0, NULL, 0, NULL, &status);
2619 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2620 SetLastError(0xdeadbeef);
2621 ret = CertVerifyRevocation(0, 0, 1, (void **)&cert, 0, NULL, &status);
2622 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2623 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2624 SetLastError(0xdeadbeef);
2625 ret = CertVerifyRevocation(0, 2, 1, (void **)&cert, 0, NULL, &status);
2626 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2627 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2629 CertFreeCertificateContext(cert);
2632 static BYTE privKey[] = {
2633 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
2634 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
2635 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
2636 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
2637 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
2638 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
2639 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
2640 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
2641 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
2642 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
2643 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
2644 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
2645 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
2646 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
2647 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
2648 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
2649 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
2650 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
2651 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
2652 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
2653 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
2654 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
2655 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
2656 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
2658 static const BYTE selfSignedCert[] = {
2659 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2660 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
2661 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
2662 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
2663 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
2664 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
2665 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
2666 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
2667 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
2668 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
2669 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
2670 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
2671 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
2672 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
2673 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
2674 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
2675 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
2676 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
2677 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
2678 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
2679 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
2680 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
2681 0xa8, 0x76, 0x57, 0x92, 0x36 };
2683 static const BYTE exportedPublicKeyBlob[] = {
2684 0x06,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x31,0x00,0x02,0x00,0x00,
2685 0x01,0x00,0x01,0x00,0x79,0x10,0x1c,0xd0,0x6b,0x10,0x18,0x30,0x94,0x61,0xdc,0x0e,
2686 0xcb,0x96,0x4e,0x21,0x3f,0x79,0xcd,0xa9,0x17,0x62,0xbc,0xbb,0x61,0x4c,0xe0,0x75,
2687 0x38,0x6c,0xf3,0xde,0x60,0x86,0x03,0x97,0x65,0xeb,0x1e,0x6b,0xdb,0x53,0x85,0xad,
2688 0x68,0x21,0xf1,0x5d,0xe7,0x1f,0xe6,0x53,0xb4,0xbb,0x59,0x3e,0x14,0x27,0xb1,0x83,
2689 0xa7,0x3a,0x54,0xe2 };
2691 static const BYTE asnEncodedPublicKey[] = {
2692 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,
2693 0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
2694 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,
2695 0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
2696 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
2698 static void testAcquireCertPrivateKey(void)
2701 PCCERT_CONTEXT cert;
2703 DWORD size, keySpec;
2705 CRYPT_KEY_PROV_INFO keyProvInfo;
2707 WCHAR ms_def_prov_w[MAX_PATH];
2709 if (!pCryptAcquireCertificatePrivateKey)
2711 skip("CryptAcquireCertificatePrivateKey() is not available\n");
2715 lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
2717 keyProvInfo.pwszContainerName = cspNameW;
2718 keyProvInfo.pwszProvName = ms_def_prov_w;
2719 keyProvInfo.dwProvType = PROV_RSA_FULL;
2720 keyProvInfo.dwFlags = 0;
2721 keyProvInfo.cProvParam = 0;
2722 keyProvInfo.rgProvParam = NULL;
2723 keyProvInfo.dwKeySpec = AT_SIGNATURE;
2725 pCryptAcquireContextW(NULL, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
2726 CRYPT_DELETEKEYSET);
2728 cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
2729 sizeof(selfSignedCert));
2732 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL, NULL);
2733 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL,
2735 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, &keySpec,
2737 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, NULL, NULL);
2738 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, &keySpec,
2740 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, NULL, NULL, NULL);
2743 /* Missing private key */
2744 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, NULL, NULL);
2745 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2746 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2747 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2749 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2750 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2751 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2753 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2755 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2756 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2758 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
2760 ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
2761 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
2766 CERT_KEY_CONTEXT keyContext;
2768 /* Don't cache provider */
2769 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2770 &keySpec, &callerFree);
2771 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2773 ok(callerFree, "Expected callerFree to be TRUE\n");
2774 CryptReleaseContext(certCSP, 0);
2775 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2777 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2779 CryptReleaseContext(certCSP, 0);
2781 /* Use the key prov info's caching (there shouldn't be any) */
2782 ret = pCryptAcquireCertificatePrivateKey(cert,
2783 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2785 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2787 ok(callerFree, "Expected callerFree to be TRUE\n");
2788 CryptReleaseContext(certCSP, 0);
2790 /* Cache it (and check that it's cached) */
2791 ret = pCryptAcquireCertificatePrivateKey(cert,
2792 CRYPT_ACQUIRE_CACHE_FLAG, NULL, &certCSP, &keySpec, &callerFree);
2793 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2795 ok(!callerFree, "Expected callerFree to be FALSE\n");
2796 size = sizeof(keyContext);
2797 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2798 &keyContext, &size);
2799 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2802 /* Remove the cached provider */
2803 CryptReleaseContext(keyContext.hCryptProv, 0);
2804 CertSetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID, 0,
2806 /* Allow caching via the key prov info */
2807 keyProvInfo.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
2808 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2810 /* Now use the key prov info's caching */
2811 ret = pCryptAcquireCertificatePrivateKey(cert,
2812 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2814 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2816 ok(!callerFree, "Expected callerFree to be FALSE\n");
2817 size = sizeof(keyContext);
2818 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2819 &keyContext, &size);
2820 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2822 CryptReleaseContext(certCSP, 0);
2824 CryptDestroyKey(key);
2827 /* Some sanity-checking on public key exporting */
2828 ret = CryptImportPublicKeyInfo(csp, X509_ASN_ENCODING,
2829 &cert->pCertInfo->SubjectPublicKeyInfo, &key);
2830 ok(ret, "CryptImportPublicKeyInfo failed: %08x\n", GetLastError());
2833 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, NULL, &size);
2834 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
2837 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size), encodedKey;
2839 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, buf, &size);
2840 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
2841 ok(size == sizeof(exportedPublicKeyBlob), "Unexpected size %d\n",
2843 ok(!memcmp(buf, exportedPublicKeyBlob, size), "Unexpected value\n");
2844 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB,
2845 buf, CRYPT_ENCODE_ALLOC_FLAG, NULL, &encodedKey, &size);
2846 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2849 ok(size == sizeof(asnEncodedPublicKey), "Unexpected size %d\n",
2851 ok(!memcmp(encodedKey, asnEncodedPublicKey, size),
2852 "Unexpected value\n");
2853 LocalFree(encodedKey);
2855 HeapFree(GetProcessHeap(), 0, buf);
2857 CryptDestroyKey(key);
2859 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
2860 NULL, 0, NULL, NULL, &size);
2861 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
2864 PCERT_PUBLIC_KEY_INFO info = HeapAlloc(GetProcessHeap(), 0, size);
2866 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
2867 NULL, 0, NULL, info, &size);
2868 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
2871 ok(info->PublicKey.cbData == sizeof(asnEncodedPublicKey),
2872 "Unexpected size %d\n", info->PublicKey.cbData);
2873 ok(!memcmp(info->PublicKey.pbData, asnEncodedPublicKey,
2874 info->PublicKey.cbData), "Unexpected value\n");
2876 HeapFree(GetProcessHeap(), 0, info);
2879 CryptReleaseContext(csp, 0);
2880 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
2881 CRYPT_DELETEKEYSET);
2883 CertFreeCertificateContext(cert);
2886 static void testGetPublicKeyLength(void)
2888 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2889 static char oid_rsa_dh[] = szOID_RSA_DH;
2890 static char bogusOID[] = "1.2.3";
2892 CERT_PUBLIC_KEY_INFO info = { { 0 } };
2893 BYTE bogusKey[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
2894 BYTE key[] = { 0x30,0x0f,0x02,0x08,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2895 0x02,0x03,0x01,0x00,0x01 };
2898 ret = CertGetPublicKeyLength(0, NULL);
2900 /* With an empty public key info */
2901 SetLastError(0xdeadbeef);
2902 ret = CertGetPublicKeyLength(0, &info);
2903 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
2904 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
2905 ret, GetLastError());
2906 SetLastError(0xdeadbeef);
2907 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2908 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_EOD,
2909 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
2910 ret, GetLastError());
2911 /* With a nearly-empty public key info */
2912 info.Algorithm.pszObjId = oid_rsa_rsa;
2913 SetLastError(0xdeadbeef);
2914 ret = CertGetPublicKeyLength(0, &info);
2915 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
2916 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
2917 ret, GetLastError());
2918 SetLastError(0xdeadbeef);
2919 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2920 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_EOD,
2921 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
2922 ret, GetLastError());
2923 /* With a bogus key */
2924 info.PublicKey.cbData = sizeof(bogusKey);
2925 info.PublicKey.pbData = bogusKey;
2926 SetLastError(0xdeadbeef);
2927 ret = CertGetPublicKeyLength(0, &info);
2928 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
2929 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
2930 ret, GetLastError());
2931 SetLastError(0xdeadbeef);
2932 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2933 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_BADTAG,
2934 "Expected length 0 and CRYPT_E_ASN1_BADTAGTAG, got length %d, %08x\n",
2935 ret, GetLastError());
2936 /* With a believable RSA key but a bogus OID */
2937 info.Algorithm.pszObjId = bogusOID;
2938 info.PublicKey.cbData = sizeof(key);
2939 info.PublicKey.pbData = key;
2940 SetLastError(0xdeadbeef);
2941 ret = CertGetPublicKeyLength(0, &info);
2942 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
2943 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
2944 ret, GetLastError());
2945 SetLastError(0xdeadbeef);
2946 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2947 ok(ret == 56, "Expected length 56, got %d\n", ret);
2948 /* An RSA key with the DH OID */
2949 info.Algorithm.pszObjId = oid_rsa_dh;
2950 SetLastError(0xdeadbeef);
2951 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2952 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_BADTAG,
2953 "Expected length 0 and CRYPT_E_ASN1_BADTAG, got length %d, %08x\n",
2954 ret, GetLastError());
2955 /* With the RSA OID */
2956 info.Algorithm.pszObjId = oid_rsa_rsa;
2957 SetLastError(0xdeadbeef);
2958 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2959 ok(ret == 56, "Expected length 56, got %d\n", ret);
2964 init_function_pointers();
2967 testCertProperties();
2970 testGetSubjectCert();
2971 testGetIssuerCert();
2973 testCryptHashCert();
2975 testSignAndEncodeCert();
2976 testCreateSelfSignCert();
2978 testGetValidUsages();
2979 testCompareCertName();
2980 testCompareIntegerBlob();
2981 testComparePublicKeyInfo();
2982 testHashPublicKeyInfo();
2984 testVerifySubjectCert();
2985 testVerifyRevocation();
2986 testAcquireCertPrivateKey();
2987 testGetPublicKeyLength();