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 GetLastError() == E_INVALIDARG),
165 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n",
167 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
168 bigCert, sizeof(bigCert), 0, NULL);
169 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
170 GetLastError() == E_INVALIDARG),
171 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n",
174 /* Weird--can add a cert to the NULL store (does this have special
178 ret = CertAddEncodedCertificateToStore(0, X509_ASN_ENCODING, bigCert,
179 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
180 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
183 CertFreeCertificateContext(context);
185 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
186 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
187 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
189 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
190 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
191 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
193 /* This has the same name as bigCert, so finding isn't done by name */
194 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
195 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, &context);
196 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
198 ok(context != NULL, "Expected a context\n");
201 CRYPT_DATA_BLOB hash = { sizeof(bigCert2Hash), bigCert2Hash };
203 /* Duplicate (AddRef) the context so we can still use it after
204 * deleting it from the store.
206 CertDuplicateCertificateContext(context);
207 CertDeleteCertificateFromStore(context);
208 /* Set the same hash as bigCert2, and try to readd it */
209 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID,
211 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
213 ret = CertAddCertificateContextToStore(store, context,
214 CERT_STORE_ADD_NEW, NULL);
215 /* The failure is a bit odd (CRYPT_E_ASN1_BADTAG), so just check
218 ok(!ret, "Expected failure\n");
219 CertFreeCertificateContext(context);
221 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
223 ok(context != NULL, "Expected a context\n");
226 /* Try to readd bigCert2 to the store */
227 ret = CertAddCertificateContextToStore(store, context,
228 CERT_STORE_ADD_NEW, NULL);
229 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
230 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
231 CertFreeCertificateContext(context);
234 /* Adding a cert with the same issuer name and serial number (but
235 * different subject) as an existing cert succeeds.
238 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
239 bigCert2WithDifferentSerial, sizeof(bigCert2WithDifferentSerial),
240 CERT_STORE_ADD_NEW, &context);
241 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
244 CertDeleteCertificateFromStore(context);
246 /* Adding a cert with the same subject name and serial number (but
247 * different issuer) as an existing cert succeeds.
250 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
251 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject),
252 CERT_STORE_ADD_NEW, &context);
253 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
256 CertDeleteCertificateFromStore(context);
258 /* Adding a cert with the same issuer name and serial number (but
259 * different otherwise) as an existing cert succeeds.
262 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
263 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer),
264 CERT_STORE_ADD_NEW, &context);
265 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
268 CertDeleteCertificateFromStore(context);
270 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
271 CERT_STORE_CREATE_NEW_FLAG, NULL);
272 ok(collection != NULL, "CertOpenStore failed: %08x\n", GetLastError());
273 if (collection && pCertAddStoreToCollection)
275 /* Add store to the collection, but disable updates */
276 pCertAddStoreToCollection(collection, store, 0, 0);
278 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
280 ok(context != NULL, "Expected a context\n");
283 /* Try to readd bigCert2 to the collection */
284 ret = CertAddCertificateContextToStore(collection, context,
285 CERT_STORE_ADD_NEW, NULL);
286 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
287 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
288 /* Replacing an existing certificate context is allowed, even
289 * though updates to the collection aren't..
291 ret = CertAddCertificateContextToStore(collection, context,
292 CERT_STORE_ADD_REPLACE_EXISTING, NULL);
293 ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
295 /* use the existing certificate and ask for a copy of the context*/
297 ret = CertAddCertificateContextToStore(collection, context,
298 CERT_STORE_ADD_USE_EXISTING, ©Context);
299 ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
301 ok(copyContext != NULL, "Expected on output a non NULL copyContext\n");
303 CertFreeCertificateContext(copyContext);
304 /* but adding a new certificate isn't allowed. */
305 ret = CertAddCertificateContextToStore(collection, context,
306 CERT_STORE_ADD_ALWAYS, NULL);
307 ok(!ret && GetLastError() == E_ACCESSDENIED,
308 "Expected E_ACCESSDENIED, got %08x\n", GetLastError());
309 CertFreeCertificateContext(context);
312 CertCloseStore(collection, 0);
315 CertCloseStore(store, 0);
318 static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
319 PCCERT_CONTEXT context, DWORD propID)
321 BYTE hash[20] = { 0 }, hashProperty[20];
324 DWORD dwSizeWithNull;
326 memset(hash, 0, sizeof(hash));
327 memset(hashProperty, 0, sizeof(hashProperty));
329 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
330 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
331 ret = CertGetCertificateContextProperty(context, propID, NULL,
333 ok(ret, "algID %08x, propID %d: CertGetCertificateContextProperty failed: %08x\n",
334 algID, propID, GetLastError());
335 ret = CertGetCertificateContextProperty(context, propID, hashProperty,
337 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
339 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
341 ok(size == dwSizeWithNull, "Unexpected length of hash for property: received %d instead of %d\n",
342 dwSizeWithNull,size);
345 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e','m','p',0 };
346 static const BYTE v1CertWithPubKey[] = {
347 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
348 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
349 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
350 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
351 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
352 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
353 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
354 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
355 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
356 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
358 static const BYTE v1CertWithSubjectKeyId[] = {
359 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
360 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
361 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
362 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
363 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
364 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
365 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
366 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
367 0x4c,0x61,0x6e,0x67,0x00 };
368 static const BYTE subjectKeyId[] = {
369 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
371 static void testCertProperties(void)
373 PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
374 bigCert, sizeof(bigCert));
375 DWORD propID, numProps, access, size;
377 BYTE hash[20] = { 0 }, hashProperty[20];
378 CRYPT_DATA_BLOB blob;
379 CERT_KEY_CONTEXT keyContext;
381 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
387 propID = CertEnumCertificateContextProperties(NULL, 0);
393 propID = CertEnumCertificateContextProperties(context, propID);
396 } while (propID != 0);
397 ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
399 /* Tests with a NULL cert context. Prop ID 0 fails.. */
400 ret = CertSetCertificateContextProperty(NULL, 0, 0, NULL);
401 ok(!ret && GetLastError() == E_INVALIDARG,
402 "Expected E_INVALIDARG, got %08x\n", GetLastError());
403 /* while this just crashes.
404 ret = CertSetCertificateContextProperty(NULL,
405 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
408 ret = CertSetCertificateContextProperty(context, 0, 0, NULL);
409 ok(!ret && GetLastError() == E_INVALIDARG,
410 "Expected E_INVALIDARG, got %08x\n", GetLastError());
411 /* Can't set the cert property directly, this crashes.
412 ret = CertSetCertificateContextProperty(context,
413 CERT_CERT_PROP_ID, 0, bigCert2);
417 ret = CertGetCertificateContextProperty(context,
418 CERT_ACCESS_STATE_PROP_ID, 0, NULL);
419 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
421 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
426 ret = CertGetCertificateContextProperty(context,
427 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
428 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
429 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
430 /* And, an implicit property */
431 size = sizeof(access);
432 ret = CertGetCertificateContextProperty(context,
433 CERT_ACCESS_STATE_PROP_ID, &access, &size);
434 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
436 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
437 "Didn't expect a persisted cert\n");
438 /* Trying to set this "read only" property crashes.
439 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
440 ret = CertSetCertificateContextProperty(context,
441 CERT_ACCESS_STATE_PROP_ID, 0, &access);
444 /* Can I set the hash to an invalid hash? */
446 blob.cbData = sizeof(hash);
447 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
449 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
451 size = sizeof(hashProperty);
452 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
453 hashProperty, &size);
454 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
455 /* Delete the (bogus) hash, and get the real one */
456 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
458 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
460 checkHash(bigCert, sizeof(bigCert), CALG_SHA1, context,
463 /* Now that the hash property is set, we should get one property when
469 propID = CertEnumCertificateContextProperties(context, propID);
472 } while (propID != 0);
473 ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
475 /* Check a few other implicit properties */
476 checkHash(bigCert, sizeof(bigCert), CALG_MD5, context,
477 CERT_MD5_HASH_PROP_ID);
479 context->pCertInfo->Subject.pbData,
480 context->pCertInfo->Subject.cbData,
481 CALG_MD5, context, CERT_SUBJECT_NAME_MD5_HASH_PROP_ID);
483 context->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
484 context->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
485 CALG_MD5, context, CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID);
487 /* Test key contexts and handles and such */
489 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
491 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
492 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
493 size = sizeof(CERT_KEY_CONTEXT);
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 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
500 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
501 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
502 /* Key context with an invalid size */
503 keyContext.cbSize = 0;
504 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
506 ok(!ret && GetLastError() == E_INVALIDARG,
507 "Expected E_INVALIDARG, got %08x\n", GetLastError());
508 size = sizeof(keyContext);
509 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
511 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
512 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
513 keyContext.cbSize = sizeof(keyContext);
514 keyContext.hCryptProv = 0;
515 keyContext.dwKeySpec = AT_SIGNATURE;
516 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
518 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
519 /* Now that that's set, the key prov handle property is also gettable.
521 size = sizeof(DWORD);
522 ret = CertGetCertificateContextProperty(context,
523 CERT_KEY_PROV_HANDLE_PROP_ID, &keyContext.hCryptProv, &size);
524 ok(ret, "Expected to get the CERT_KEY_PROV_HANDLE_PROP_ID, got %08x\n",
526 /* Remove the key prov handle property.. */
527 ret = CertSetCertificateContextProperty(context,
528 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
529 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
531 /* and the key context's CSP is set to NULL. */
532 size = sizeof(keyContext);
533 ret = CertGetCertificateContextProperty(context,
534 CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
535 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
537 ok(keyContext.hCryptProv == 0, "Expected no hCryptProv\n");
539 /* According to MSDN the subject key id can be stored as a property,
540 * as a subject key extension, or as the SHA1 hash of the public key,
541 * but this cert has none of them:
543 ret = CertGetCertificateContextProperty(context,
544 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
545 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
546 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
547 CertFreeCertificateContext(context);
548 /* This cert does have a public key, but its subject key identifier still
549 * isn't available: */
550 context = CertCreateCertificateContext(X509_ASN_ENCODING,
551 v1CertWithPubKey, sizeof(v1CertWithPubKey));
552 ret = CertGetCertificateContextProperty(context,
553 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
554 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
555 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
556 CertFreeCertificateContext(context);
557 /* This cert with a subject key extension can have its key identifier
558 * property retrieved:
560 context = CertCreateCertificateContext(X509_ASN_ENCODING,
561 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId));
562 ret = CertGetCertificateContextProperty(context,
563 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
564 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
567 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
571 ret = CertGetCertificateContextProperty(context,
572 CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
573 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
575 ok(!memcmp(buf, subjectKeyId, size), "Unexpected subject key id\n");
576 HeapFree(GetProcessHeap(), 0, buf);
579 CertFreeCertificateContext(context);
582 static void testDupCert(void)
585 PCCERT_CONTEXT context, dupContext;
588 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
589 CERT_STORE_CREATE_NEW_FLAG, NULL);
590 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
594 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
595 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
596 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
598 ok(context != NULL, "Expected a valid cert context\n");
601 ok(context->cbCertEncoded == sizeof(bigCert),
602 "Wrong cert size %d\n", context->cbCertEncoded);
603 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)),
604 "Unexpected encoded cert in context\n");
605 ok(context->hCertStore == store, "Unexpected store\n");
607 dupContext = CertDuplicateCertificateContext(context);
608 ok(dupContext != NULL, "Expected valid duplicate\n");
609 /* Not only is it a duplicate, it's identical: the address is the
612 ok(dupContext == context, "Expected identical context addresses\n");
613 CertFreeCertificateContext(dupContext);
614 CertFreeCertificateContext(context);
616 CertCloseStore(store, 0);
619 static BYTE subjectName3[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
620 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x52, 0x6f, 0x62, 0x20, 0x20, 0x4c, 0x61,
622 static const BYTE iTunesCert0[] = {
623 0x30,0x82,0x03,0xc4,0x30,0x82,0x03,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
624 0x47,0xbf,0x19,0x95,0xdf,0x8d,0x52,0x46,0x43,0xf7,0xdb,0x6d,0x48,0x0d,0x31,
625 0xa4,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
626 0x00,0x30,0x81,0x8b,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
627 0x5a,0x41,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0c,0x57,0x65,
628 0x73,0x74,0x65,0x72,0x6e,0x20,0x43,0x61,0x70,0x65,0x31,0x14,0x30,0x12,0x06,
629 0x03,0x55,0x04,0x07,0x13,0x0b,0x44,0x75,0x72,0x62,0x61,0x6e,0x76,0x69,0x6c,
630 0x6c,0x65,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x0a,0x13,0x06,0x54,0x68,
631 0x61,0x77,0x74,0x65,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14,
632 0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
633 0x61,0x74,0x69,0x6f,0x6e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13,
634 0x16,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
635 0x6d,0x70,0x69,0x6e,0x67,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x33,0x31,
636 0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x33,0x31,
637 0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x53,0x31,0x0b,0x30,
638 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,
639 0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
640 0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,
641 0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,0x6d,0x65,0x20,
642 0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,0x76,0x69,0x63,
643 0x65,0x73,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,
644 0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,
645 0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa9,0xca,0xb2,0xa4,0xcc,0xcd,0x20,
646 0xaf,0x0a,0x7d,0x89,0xac,0x87,0x75,0xf0,0xb4,0x4e,0xf1,0xdf,0xc1,0x0f,0xbf,
647 0x67,0x61,0xbd,0xa3,0x64,0x1c,0xda,0xbb,0xf9,0xca,0x33,0xab,0x84,0x30,0x89,
648 0x58,0x7e,0x8c,0xdb,0x6b,0xdd,0x36,0x9e,0x0f,0xbf,0xd1,0xec,0x78,0xf2,0x77,
649 0xa6,0x7e,0x6f,0x3c,0xbf,0x93,0xaf,0x0d,0xba,0x68,0xf4,0x6c,0x94,0xca,0xbd,
650 0x52,0x2d,0xab,0x48,0x3d,0xf5,0xb6,0xd5,0x5d,0x5f,0x1b,0x02,0x9f,0xfa,0x2f,
651 0x6b,0x1e,0xa4,0xf7,0xa3,0x9a,0xa6,0x1a,0xc8,0x02,0xe1,0x7f,0x4c,0x52,0xe3,
652 0x0e,0x60,0xec,0x40,0x1c,0x7e,0xb9,0x0d,0xde,0x3f,0xc7,0xb4,0xdf,0x87,0xbd,
653 0x5f,0x7a,0x6a,0x31,0x2e,0x03,0x99,0x81,0x13,0xa8,0x47,0x20,0xce,0x31,0x73,
654 0x0d,0x57,0x2d,0xcd,0x78,0x34,0x33,0x95,0x12,0x99,0x12,0xb9,0xde,0x68,0x2f,
655 0xaa,0xe6,0xe3,0xc2,0x8a,0x8c,0x2a,0xc3,0x8b,0x21,0x87,0x66,0xbd,0x83,0x58,
656 0x57,0x6f,0x75,0xbf,0x3c,0xaa,0x26,0x87,0x5d,0xca,0x10,0x15,0x3c,0x9f,0x84,
657 0xea,0x54,0xc1,0x0a,0x6e,0xc4,0xfe,0xc5,0x4a,0xdd,0xb9,0x07,0x11,0x97,0x22,
658 0x7c,0xdb,0x3e,0x27,0xd1,0x1e,0x78,0xec,0x9f,0x31,0xc9,0xf1,0xe6,0x22,0x19,
659 0xdb,0xc4,0xb3,0x47,0x43,0x9a,0x1a,0x5f,0xa0,0x1e,0x90,0xe4,0x5e,0xf5,0xee,
660 0x7c,0xf1,0x7d,0xab,0x62,0x01,0x8f,0xf5,0x4d,0x0b,0xde,0xd0,0x22,0x56,0xa8,
661 0x95,0xcd,0xae,0x88,0x76,0xae,0xee,0xba,0x0d,0xf3,0xe4,0x4d,0xd9,0xa0,0xfb,
662 0x68,0xa0,0xae,0x14,0x3b,0xb3,0x87,0xc1,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,
663 0x81,0xdb,0x30,0x81,0xd8,0x30,0x34,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
664 0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
665 0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,
666 0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,
667 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
668 0xff,0x02,0x01,0x00,0x30,0x41,0x06,0x03,0x55,0x1d,0x1f,0x04,0x3a,0x30,0x38,
669 0x30,0x36,0xa0,0x34,0xa0,0x32,0x86,0x30,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
670 0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,
671 0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
672 0x6d,0x70,0x69,0x6e,0x67,0x43,0x41,0x2e,0x63,0x72,0x6c,0x30,0x13,0x06,0x03,
673 0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
674 0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,
675 0x02,0x01,0x06,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,0x04,0x1d,0x30,0x1b,0xa4,
676 0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0c,0x54,
677 0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,0x33,0x30,0x0d,0x06,0x09,
678 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,
679 0x4a,0x6b,0xf9,0xea,0x58,0xc2,0x44,0x1c,0x31,0x89,0x79,0x99,0x2b,0x96,0xbf,
680 0x82,0xac,0x01,0xd6,0x1c,0x4c,0xcd,0xb0,0x8a,0x58,0x6e,0xdf,0x08,0x29,0xa3,
681 0x5e,0xc8,0xca,0x93,0x13,0xe7,0x04,0x52,0x0d,0xef,0x47,0x27,0x2f,0x00,0x38,
682 0xb0,0xe4,0xc9,0x93,0x4e,0x9a,0xd4,0x22,0x62,0x15,0xf7,0x3f,0x37,0x21,0x4f,
683 0x70,0x31,0x80,0xf1,0x8b,0x38,0x87,0xb3,0xe8,0xe8,0x97,0x00,0xfe,0xcf,0x55,
684 0x96,0x4e,0x24,0xd2,0xa9,0x27,0x4e,0x7a,0xae,0xb7,0x61,0x41,0xf3,0x2a,0xce,
685 0xe7,0xc9,0xd9,0x5e,0xdd,0xbb,0x2b,0x85,0x3e,0xb5,0x9d,0xb5,0xd9,0xe1,0x57,
686 0xff,0xbe,0xb4,0xc5,0x7e,0xf5,0xcf,0x0c,0x9e,0xf0,0x97,0xfe,0x2b,0xd3,0x3b,
687 0x52,0x1b,0x1b,0x38,0x27,0xf7,0x3f,0x4a };
688 static const BYTE iTunesCert1[] = {
689 0x30,0x82,0x03,0xff,0x30,0x82,0x02,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
690 0x0d,0xe9,0x2b,0xf0,0xd4,0xd8,0x29,0x88,0x18,0x32,0x05,0x09,0x5e,0x9a,0x76,
691 0x88,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
692 0x00,0x30,0x53,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
693 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
694 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,
695 0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
696 0x20,0x54,0x69,0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,
697 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,
698 0x30,0x33,0x31,0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
699 0x30,0x38,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x57,
700 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,
701 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,
702 0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2f,0x30,0x2d,0x06,0x03,0x55,
703 0x04,0x03,0x13,0x26,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,
704 0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,
705 0x76,0x69,0x63,0x65,0x73,0x20,0x53,0x69,0x67,0x6e,0x65,0x72,0x30,0x82,0x01,
706 0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
707 0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,
708 0xb2,0x50,0x28,0x48,0xdd,0xd3,0x68,0x7a,0x84,0x18,0x44,0x66,0x75,0x5d,0x7e,
709 0xc4,0xb8,0x9f,0x63,0x26,0xff,0x3d,0x43,0x9c,0x7c,0x11,0x38,0x10,0x25,0x55,
710 0x73,0xd9,0x75,0x27,0x69,0xfd,0x4e,0xb9,0x20,0x5c,0xd3,0x0a,0xf9,0xa0,0x1b,
711 0x2a,0xed,0x55,0x56,0x21,0x61,0xd8,0x1e,0xdb,0xe4,0xbc,0x33,0x6b,0xc7,0xef,
712 0xdd,0xa3,0x37,0x65,0x8e,0x1b,0x93,0x0c,0xb6,0x53,0x1e,0x5c,0x7c,0x66,0x35,
713 0x5f,0x05,0x8a,0x45,0xfe,0x76,0x4e,0xdf,0x53,0x80,0xa2,0x81,0x20,0x9d,0xae,
714 0x88,0x5c,0xa2,0x08,0xf7,0xe5,0x30,0xf9,0xee,0x22,0x37,0x4c,0x42,0x0a,0xce,
715 0xdf,0xc6,0x1f,0xc4,0xd6,0x55,0xe9,0x81,0x3f,0xb5,0x52,0xa3,0x2c,0xaa,0x01,
716 0x7a,0xf2,0xa2,0xaa,0x8d,0x35,0xfe,0x9f,0xe6,0x5d,0x6a,0x05,0x9f,0x3d,0x6b,
717 0xe3,0xbf,0x96,0xc0,0xfe,0xcc,0x60,0xf9,0x40,0xe7,0x07,0xa0,0x44,0xeb,0x81,
718 0x51,0x6e,0xa5,0x2a,0xf2,0xb6,0x8a,0x10,0x28,0xed,0x8f,0xdc,0x06,0xa0,0x86,
719 0x50,0x9a,0x7b,0x4a,0x08,0x0d,0x30,0x1d,0xca,0x10,0x9e,0x6b,0xf7,0xe9,0x58,
720 0xae,0x04,0xa9,0x40,0x99,0xb2,0x28,0xe8,0x8f,0x16,0xac,0x3c,0xe3,0x53,0x6f,
721 0x4b,0xd3,0x35,0x9d,0xb5,0x6f,0x64,0x1d,0xb3,0x96,0x2c,0xbb,0x3d,0xe7,0x79,
722 0xeb,0x6d,0x7a,0xf9,0x16,0xe6,0x26,0xad,0xaf,0xef,0x99,0x53,0xb7,0x40,0x2c,
723 0x95,0xb8,0x79,0xaa,0xfe,0xd4,0x52,0xab,0x29,0x74,0x7e,0x42,0xec,0x39,0x1e,
724 0xa2,0x6a,0x16,0xe6,0x59,0xbb,0x24,0x68,0xd8,0x00,0x80,0x43,0x10,0x87,0x80,
725 0x6b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xca,0x30,0x81,0xc7,0x30,0x34,0x06,
726 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,
727 0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,
728 0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
729 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
730 0xff,0x04,0x02,0x30,0x00,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30,
731 0x2a,0x30,0x28,0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,
732 0x2f,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,
733 0x6f,0x6d,0x2f,0x74,0x73,0x73,0x2d,0x63,0x61,0x2e,0x63,0x72,0x6c,0x30,0x16,
734 0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,
735 0x06,0x01,0x05,0x05,0x07,0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
736 0x01,0xff,0x04,0x04,0x03,0x02,0x06,0xc0,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,
737 0x04,0x1d,0x30,0x1b,0xa4,0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,
738 0x04,0x03,0x13,0x0c,0x54,0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,
739 0x34,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
740 0x00,0x03,0x82,0x01,0x01,0x00,0x87,0x78,0x70,0xda,0x4e,0x52,0x01,0x20,0x5b,
741 0xe0,0x79,0xc9,0x82,0x30,0xc4,0xfd,0xb9,0x19,0x96,0xbd,0x91,0x00,0xc3,0xbd,
742 0xcd,0xcd,0xc6,0xf4,0x0e,0xd8,0xff,0xf9,0x4d,0xc0,0x33,0x62,0x30,0x11,0xc5,
743 0xf5,0x74,0x1b,0xd4,0x92,0xde,0x5f,0x9c,0x20,0x13,0xb1,0x7c,0x45,0xbe,0x50,
744 0xcd,0x83,0xe7,0x80,0x17,0x83,0xa7,0x27,0x93,0x67,0x13,0x46,0xfb,0xca,0xb8,
745 0x98,0x41,0x03,0xcc,0x9b,0x51,0x5b,0x05,0x8b,0x7f,0xa8,0x6f,0xf3,0x1b,0x50,
746 0x1b,0x24,0x2e,0xf2,0x69,0x8d,0x6c,0x22,0xf7,0xbb,0xca,0x16,0x95,0xed,0x0c,
747 0x74,0xc0,0x68,0x77,0xd9,0xeb,0x99,0x62,0x87,0xc1,0x73,0x90,0xf8,0x89,0x74,
748 0x7a,0x23,0xab,0xa3,0x98,0x7b,0x97,0xb1,0xf7,0x8f,0x29,0x71,0x4d,0x2e,0x75,
749 0x1b,0x48,0x41,0xda,0xf0,0xb5,0x0d,0x20,0x54,0xd6,0x77,0xa0,0x97,0x82,0x63,
750 0x69,0xfd,0x09,0xcf,0x8a,0xf0,0x75,0xbb,0x09,0x9b,0xd9,0xf9,0x11,0x55,0x26,
751 0x9a,0x61,0x32,0xbe,0x7a,0x02,0xb0,0x7b,0x86,0xbe,0xa2,0xc3,0x8b,0x22,0x2c,
752 0x78,0xd1,0x35,0x76,0xbc,0x92,0x73,0x5c,0xf9,0xb9,0xe6,0x4c,0x15,0x0a,0x23,
753 0xcc,0xe4,0xd2,0xd4,0x34,0x2e,0x49,0x40,0x15,0x3c,0x0f,0x60,0x7a,0x24,0xc6,
754 0xa5,0x66,0xef,0x96,0xcf,0x70,0xeb,0x3e,0xe7,0xf4,0x0d,0x7e,0xdc,0xd1,0x7c,
755 0xa3,0x76,0x71,0x69,0xc1,0x9c,0x4f,0x47,0x30,0x35,0x21,0xb1,0xa2,0xaf,0x1a,
756 0x62,0x3c,0x2b,0xd9,0x8e,0xaa,0x2a,0x07,0x7b,0xd8,0x18,0xb3,0x5c,0x7b,0xe2,
757 0x9d,0xa5,0x6f,0xfe,0x3c,0x89,0xad };
758 static const BYTE iTunesCert2[] = {
759 0x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
760 0x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75,
761 0xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
762 0x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
763 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
764 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,
765 0x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,
766 0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,
767 0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,
768 0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x34,0x30,
769 0x37,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30,
770 0x37,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,
771 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,
772 0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
773 0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b,
774 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,
775 0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,
776 0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,
777 0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,
778 0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,
779 0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,
780 0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,
781 0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,0x53,0x69,
782 0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,0x20,0x43,0x41,0x30,0x82,
783 0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,
784 0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,
785 0x00,0xbe,0xbc,0xee,0xbc,0x7e,0xef,0x83,0xeb,0xe0,0x37,0x4f,0xfb,0x03,0x10,
786 0x38,0xbe,0x08,0xd2,0x8c,0x7d,0x9d,0xfa,0x92,0x7f,0x19,0x0c,0xc2,0x6b,0xee,
787 0x42,0x52,0x8c,0xde,0xd3,0x1c,0x48,0x13,0x25,0xea,0xc1,0x63,0x7a,0xf9,0x51,
788 0x65,0xee,0xd3,0xaa,0x3b,0xf5,0xf0,0x94,0x9c,0x2b,0xfb,0xf2,0x66,0xd4,0x24,
789 0xda,0xf7,0xf5,0x9f,0x6e,0x19,0x39,0x36,0xbc,0xd0,0xa3,0x76,0x08,0x1e,0x22,
790 0x27,0x24,0x6c,0x38,0x91,0x27,0xe2,0x84,0x49,0xae,0x1b,0x8a,0xa1,0xfd,0x25,
791 0x82,0x2c,0x10,0x30,0xe8,0x71,0xab,0x28,0xe8,0x77,0x4a,0x51,0xf1,0xec,0xcd,
792 0xf8,0xf0,0x54,0xd4,0x6f,0xc0,0xe3,0x6d,0x0a,0x8f,0xd9,0xd8,0x64,0x8d,0x63,
793 0xb2,0x2d,0x4e,0x27,0xf6,0x85,0x0e,0xfe,0x6d,0xe3,0x29,0x99,0xe2,0x85,0x47,
794 0x7c,0x2d,0x86,0x7f,0xe8,0x57,0x8f,0xad,0x67,0xc2,0x33,0x32,0x91,0x13,0x20,
795 0xfc,0xa9,0x23,0x14,0x9a,0x6d,0xc2,0x84,0x4b,0x76,0x68,0x04,0xd5,0x71,0x2c,
796 0x5d,0x21,0xfa,0x88,0x0d,0x26,0xfd,0x1f,0x2d,0x91,0x2b,0xe7,0x01,0x55,0x4d,
797 0xf2,0x6d,0x35,0x28,0x82,0xdf,0xd9,0x6b,0x5c,0xb6,0xd6,0xd9,0xaa,0x81,0xfd,
798 0x5f,0xcd,0x83,0xba,0x63,0x9d,0xd0,0x22,0xfc,0xa9,0x3b,0x42,0x69,0xb2,0x8e,
799 0x3a,0xb5,0xbc,0xb4,0x9e,0x0f,0x5e,0xc4,0xea,0x2c,0x82,0x8b,0x28,0xfd,0x53,
800 0x08,0x96,0xdd,0xb5,0x01,0x20,0xd1,0xf9,0xa5,0x18,0xe7,0xc0,0xee,0x51,0x70,
801 0x37,0xe1,0xb6,0x05,0x48,0x52,0x48,0x6f,0x38,0xea,0xc3,0xe8,0x6c,0x7b,0x44,
802 0x84,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xa0,0x30,0x82,0x01,0x9c,
803 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
804 0x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,
805 0x3b,0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,
806 0x03,0x30,0x2a,0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
807 0x16,0x1c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,
808 0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,
809 0x30,0x31,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24,
810 0xa0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,
811 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63,
812 0x61,0x33,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16,
813 0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2b,
814 0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
815 0x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48,
816 0x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x01,0x30,0x29,0x06,
817 0x03,0x55,0x1d,0x11,0x04,0x22,0x30,0x20,0xa4,0x1e,0x30,0x1c,0x31,0x1a,0x30,
818 0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6c,0x61,0x73,0x73,0x33,0x43,
819 0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x34,0x33,0x30,0x1d,0x06,0x03,0x55,
820 0x1d,0x0e,0x04,0x16,0x04,0x14,0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,
821 0x36,0x7c,0x68,0xcf,0x5b,0x78,0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x81,0x80,0x06,
822 0x03,0x55,0x1d,0x23,0x04,0x79,0x30,0x77,0xa1,0x63,0xa4,0x61,0x30,0x5f,0x31,
823 0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,
824 0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
825 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,
826 0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6c,
827 0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,
828 0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,
829 0x72,0x69,0x74,0x79,0x82,0x10,0x70,0xba,0xe4,0x1d,0x10,0xd9,0x29,0x34,0xb6,
830 0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
831 0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xae,0x3a,0x17,0xb8,
832 0x4a,0x7b,0x55,0xfa,0x64,0x55,0xec,0x40,0xa4,0xed,0x49,0x41,0x90,0x99,0x9c,
833 0x89,0xbc,0xaf,0x2e,0x1d,0xca,0x78,0x23,0xf9,0x1c,0x19,0x0f,0x7f,0xeb,0x68,
834 0xbc,0x32,0xd9,0x88,0x38,0xde,0xdc,0x3f,0xd3,0x89,0xb4,0x3f,0xb1,0x82,0x96,
835 0xf1,0xa4,0x5a,0xba,0xed,0x2e,0x26,0xd3,0xde,0x7c,0x01,0x6e,0x00,0x0a,0x00,
836 0xa4,0x06,0x92,0x11,0x48,0x09,0x40,0xf9,0x1c,0x18,0x79,0x67,0x23,0x24,0xe0,
837 0xbb,0xd5,0xe1,0x50,0xae,0x1b,0xf5,0x0e,0xdd,0xe0,0x2e,0x81,0xcd,0x80,0xa3,
838 0x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88,
839 0x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f,
840 0x5e,0xf6,0x7a,0xb5 };
841 static const BYTE iTunesCert3[] = {
842 0x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
843 0x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6,
844 0x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
845 0x00,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
846 0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,
847 0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,
848 0x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
849 0x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,
850 0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,
851 0x73,0x20,0x6f,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,
852 0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
853 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,
854 0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,
855 0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,
856 0x6f,0x64,0x65,0x20,0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,
857 0x34,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x31,0x37,0x30,
858 0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x38,0x30,0x31,0x32,0x32,0x32,
859 0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,
860 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
861 0x08,0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x12,
862 0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,
863 0x69,0x6e,0x6f,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0a,0x14,0x14,0x41,
864 0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x2c,0x20,
865 0x49,0x6e,0x63,0x2e,0x31,0x3e,0x30,0x3c,0x06,0x03,0x55,0x04,0x0b,0x13,0x35,
866 0x44,0x69,0x67,0x69,0x74,0x61,0x6c,0x20,0x49,0x44,0x20,0x43,0x6c,0x61,0x73,
867 0x73,0x20,0x33,0x20,0x2d,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
868 0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x56,0x61,0x6c,0x69,0x64,
869 0x61,0x74,0x69,0x6f,0x6e,0x20,0x76,0x32,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,
870 0x04,0x03,0x14,0x14,0x41,0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,
871 0x74,0x65,0x72,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x30,0x81,0x9f,0x30,0x0d,0x06,
872 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,
873 0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xd3,0xab,0x3b,0x7f,0xec,0x48,0x84,
874 0xce,0xa8,0x1a,0x12,0xf3,0x3c,0x87,0xcb,0x24,0x58,0x96,0x02,0x87,0x66,0x49,
875 0xeb,0x89,0xee,0x79,0x44,0x70,0x8d,0xe7,0xd4,0x1f,0x30,0x92,0xc0,0x9c,0x35,
876 0x78,0xc0,0xaf,0x1c,0xb6,0x28,0xd3,0xe0,0xe0,0x9d,0xd3,0x49,0x76,0x73,0x57,
877 0x19,0x4d,0x8d,0x70,0x85,0x64,0x4d,0x1d,0xc6,0x02,0x3e,0xe5,0x2c,0x66,0x07,
878 0xd2,0x27,0x4b,0xd6,0xc8,0x3c,0x93,0xb6,0x15,0x0c,0xde,0x5b,0xd7,0x93,0xdd,
879 0xbe,0x85,0x62,0x34,0x17,0x8a,0x05,0x60,0xf0,0x8a,0x1c,0x5a,0x40,0x21,0x8d,
880 0x51,0x6c,0xb0,0x62,0xd8,0xb5,0xd4,0xf9,0xb1,0xd0,0x58,0x7a,0x7a,0x82,0x55,
881 0xb3,0xf9,0x53,0x71,0xde,0xd2,0xc9,0x37,0x8c,0xf6,0x5a,0x1f,0x2d,0xcd,0x7c,
882 0x67,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30,
883 0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06,0x03,0x55,
884 0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x40,0x06,0x03,
885 0x55,0x1d,0x1f,0x04,0x39,0x30,0x37,0x30,0x35,0xa0,0x33,0xa0,0x31,0x86,0x2f,
886 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,
887 0x34,0x2d,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,
888 0x63,0x6f,0x6d,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2e,0x63,
889 0x72,0x6c,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b,0x30,0x39,
890 0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,0x03,0x30,0x2a,
891 0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1c,0x68,
892 0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,
893 0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x30,0x13,0x06,
894 0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
895 0x07,0x03,0x03,0x30,0x75,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
896 0x04,0x69,0x30,0x67,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,
897 0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,
898 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x3f,0x06,
899 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x33,0x68,0x74,0x74,0x70,
900 0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,
901 0x61,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,
902 0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,0x61,0x2e,0x63,
903 0x65,0x72,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
904 0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,0x36,0x7c,0x68,0xcf,0x5b,0x78,
905 0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,
906 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x04,0x10,0x30,0x16,0x06,0x0a,0x2b,0x06,
907 0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x1b,0x04,0x08,0x30,0x06,0x01,0x01,0x00,
908 0x01,0x01,0xff,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
909 0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6a,0xa6,0x06,0xd0,0x33,0x18,0x64,
910 0xe2,0x69,0x82,0xee,0x6e,0x36,0x9e,0x9d,0x9a,0x0e,0x18,0xa8,0xac,0x9d,0x10,
911 0xed,0x01,0x3c,0xb9,0x61,0x04,0x62,0xf3,0x85,0x8f,0xcc,0x4f,0x2c,0x66,0x35,
912 0x54,0x25,0x45,0x8d,0x95,0x1c,0xd2,0x33,0xbe,0x2e,0xdd,0x7f,0x74,0xaf,0x03,
913 0x7b,0x86,0x63,0xb0,0xc9,0xe6,0xbd,0xc7,0x8e,0xde,0x03,0x18,0x98,0x82,0xc3,
914 0xbb,0xf8,0x15,0x99,0x1a,0xa9,0xdd,0xb9,0x5d,0xb9,0xbd,0x53,0x95,0x25,0x76,
915 0xfb,0x5c,0x53,0x90,0xea,0x01,0x0a,0xa0,0xb1,0xbf,0x09,0x1b,0x97,0x8f,0x40,
916 0xfa,0x85,0x12,0x74,0x01,0xdb,0xf6,0xdb,0x09,0xd6,0x5f,0x4f,0xd7,0x17,0xb4,
917 0xbf,0x9e,0x2f,0x86,0x52,0x5d,0x70,0x24,0x52,0x32,0x1e,0xa5,0x1d,0x39,0x8b,
918 0x66,0xf6,0xba,0x9b,0x69,0x8e,0x12,0x60,0xdb,0xb6,0xcf,0xe6,0x0d,0xd6,0x1c,
919 0x8f,0xd4,0x5b,0x4b,0x00,0xde,0x21,0x93,0xfb,0x6e,0xc7,0x3d,0xb4,0x66,0x0d,
920 0x29,0x0c,0x4e,0xe9,0x3f,0x94,0xd6,0xd6,0xdc,0xec,0xf8,0x53,0x3b,0x62,0xd5,
921 0x97,0x50,0x53,0x84,0x17,0xfe,0xe2,0xed,0x4c,0x23,0x0a,0x49,0xce,0x5b,0xe9,
922 0x70,0x31,0xc1,0x04,0x02,0x02,0x6c,0xb8,0x52,0xcd,0xc7,0x4e,0x70,0xb4,0x13,
923 0xd7,0xe0,0x92,0xba,0x44,0x1a,0x10,0x4c,0x6e,0x45,0xc6,0x86,0x04,0xc6,0x64,
924 0xd3,0x9c,0x6e,0xc1,0x9c,0xac,0x74,0x3d,0x77,0x06,0x5e,0x28,0x28,0x5c,0xf5,
925 0xe0,0x9c,0x19,0xd8,0xba,0x74,0x81,0x2d,0x67,0x77,0x93,0x8d,0xbf,0xd2,0x52,
926 0x00,0xe6,0xa5,0x38,0x4e,0x2e,0x73,0x66,0x7a };
927 static BYTE iTunesIssuer[] = {
928 0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
929 0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,
930 0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
931 0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,
932 0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
933 0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,
934 0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,
935 0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,0x73,
936 0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,
937 0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,
938 0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,
939 0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,
940 0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
941 0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,
942 0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,
944 static BYTE iTunesSerialNum[] = {
945 0x8d,0xf6,0x6a,0xdf,0xd2,0x40,0xfe,0xb6,0xa6,0x61,0x9b,0x9b,
946 0xe0,0xa0,0x1a,0x0f };
948 static void testFindCert(void)
951 PCCERT_CONTEXT context = NULL, subject;
953 CERT_INFO certInfo = { 0 };
954 CRYPT_HASH_BLOB blob;
955 BYTE otherSerialNumber[] = { 2 };
957 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
958 CERT_STORE_CREATE_NEW_FLAG, NULL);
959 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
963 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
964 bigCert, sizeof(bigCert), CERT_STORE_ADD_NEW, NULL);
965 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
967 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
968 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
969 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
971 /* This has the same name as bigCert */
972 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
973 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
974 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
978 context = CertFindCertificateInStore(NULL, 0, 0, 0, NULL, NULL);
981 /* Check first cert's there, by issuer */
982 certInfo.Subject.pbData = subjectName;
983 certInfo.Subject.cbData = sizeof(subjectName);
984 certInfo.SerialNumber.pbData = serialNum;
985 certInfo.SerialNumber.cbData = sizeof(serialNum);
986 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
987 CERT_FIND_ISSUER_NAME, &certInfo.Subject, NULL);
988 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
992 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
993 CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
994 ok(context != NULL, "Expected more than one cert\n");
997 context = CertFindCertificateInStore(store, X509_ASN_ENCODING,
998 0, CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
999 ok(context == NULL, "Expected precisely two certs\n");
1003 /* Check second cert's there as well, by subject name */
1004 certInfo.Subject.pbData = subjectName2;
1005 certInfo.Subject.cbData = sizeof(subjectName2);
1006 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1007 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, NULL);
1008 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1012 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1013 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, context);
1014 ok(context == NULL, "Expected one cert only\n");
1017 /* Strange but true: searching for the subject cert requires you to set
1018 * the issuer, not the subject
1020 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1021 CERT_FIND_SUBJECT_CERT, &certInfo.Subject, NULL);
1022 ok(context == NULL, "Expected no certificate\n");
1023 certInfo.Subject.pbData = NULL;
1024 certInfo.Subject.cbData = 0;
1025 certInfo.Issuer.pbData = subjectName2;
1026 certInfo.Issuer.cbData = sizeof(subjectName2);
1027 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1028 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1029 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1033 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1034 CERT_FIND_SUBJECT_CERT, &certInfo.Subject, context);
1035 ok(context == NULL, "Expected one cert only\n");
1037 /* A non-matching serial number will not match. */
1038 certInfo.SerialNumber.pbData = otherSerialNumber;
1039 certInfo.SerialNumber.cbData = sizeof(otherSerialNumber);
1040 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1041 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1042 ok(context == NULL, "Expected no match\n");
1043 /* No serial number will not match */
1044 certInfo.SerialNumber.cbData = 0;
1045 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1046 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1047 ok(context == NULL, "Expected no match\n");
1048 /* A serial number still won't match if the name doesn't */
1049 certInfo.SerialNumber.pbData = serialNum;
1050 certInfo.SerialNumber.cbData = sizeof(serialNum);
1051 certInfo.Issuer.pbData = subjectName3;
1052 certInfo.Issuer.cbData = sizeof(subjectName3);
1053 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1054 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1055 ok(context == NULL, "Expected no match\n");
1057 /* The nice thing about hashes, they're unique */
1058 blob.pbData = bigCertHash;
1059 blob.cbData = sizeof(bigCertHash);
1060 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1061 CERT_FIND_SHA1_HASH, &blob, NULL);
1062 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1066 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1067 CERT_FIND_SHA1_HASH, &certInfo.Subject, context);
1068 ok(context == NULL, "Expected one cert only\n");
1071 CertCloseStore(store, 0);
1073 /* Another subject cert search, using iTunes's certs */
1074 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1075 CERT_STORE_CREATE_NEW_FLAG, NULL);
1076 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1077 iTunesCert0, sizeof(iTunesCert0), CERT_STORE_ADD_NEW, NULL);
1078 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1080 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1081 iTunesCert1, sizeof(iTunesCert1), CERT_STORE_ADD_NEW, NULL);
1082 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1084 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1085 iTunesCert2, sizeof(iTunesCert2), CERT_STORE_ADD_NEW, NULL);
1086 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1088 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1089 iTunesCert3, sizeof(iTunesCert3), CERT_STORE_ADD_NEW, &subject);
1090 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1093 /* The certInfo's issuer does not match any subject, but the serial
1094 * number does match a cert whose issuer matches certInfo's issuer.
1095 * This yields a match.
1097 certInfo.SerialNumber.cbData = sizeof(iTunesSerialNum);
1098 certInfo.SerialNumber.pbData = iTunesSerialNum;
1099 certInfo.Issuer.cbData = sizeof(iTunesIssuer);
1100 certInfo.Issuer.pbData = iTunesIssuer;
1101 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1102 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1103 ok(context != NULL, "Expected a match\n");
1106 ret = CertCompareCertificateName(context->dwCertEncodingType,
1107 &certInfo.Issuer, &context->pCertInfo->Subject);
1108 ok(!ret, "Expected subject name not to match\n");
1109 ret = CertCompareCertificateName(context->dwCertEncodingType,
1110 &certInfo.Issuer, &context->pCertInfo->Issuer);
1111 ok(ret, "Expected issuer name to match\n");
1112 ret = CertCompareIntegerBlob(&certInfo.SerialNumber,
1113 &context->pCertInfo->SerialNumber);
1114 ok(ret, "Expected serial number to match\n");
1115 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1116 CERT_FIND_SUBJECT_CERT, &certInfo, context);
1117 ok(context == NULL, "Expected one cert only\n");
1120 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1121 CERT_FIND_ISSUER_OF, subject, NULL);
1122 ok(context != NULL, "Expected an issuer\n");
1125 PCCERT_CONTEXT none = CertFindCertificateInStore(store,
1126 X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_OF, context, NULL);
1128 ok(!none, "Expected no parent of issuer\n");
1129 CertFreeCertificateContext(context);
1131 CertFreeCertificateContext(subject);
1132 CertCloseStore(store, 0);
1135 static void testGetSubjectCert(void)
1138 PCCERT_CONTEXT context1, context2;
1139 CERT_INFO info = { 0 };
1142 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1143 CERT_STORE_CREATE_NEW_FLAG, NULL);
1144 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1148 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1149 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1150 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1152 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1153 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, &context1);
1154 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1156 ok(context1 != NULL, "Expected a context\n");
1157 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1158 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1159 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1162 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1164 ok(!context2 && GetLastError() == E_INVALIDARG,
1165 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1166 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1168 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1169 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1170 info.SerialNumber.cbData = sizeof(serialNum);
1171 info.SerialNumber.pbData = serialNum;
1172 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1174 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1175 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1176 info.Issuer.cbData = sizeof(subjectName2);
1177 info.Issuer.pbData = subjectName2;
1178 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1180 ok(context2 != NULL,
1181 "CertGetSubjectCertificateFromStore failed: %08x\n", GetLastError());
1182 /* Not only should this find a context, but it should be the same
1183 * (same address) as context1.
1185 ok(context1 == context2, "Expected identical context addresses\n");
1186 CertFreeCertificateContext(context2);
1188 CertFreeCertificateContext(context1);
1189 CertCloseStore(store, 0);
1192 /* This expires in 1970 or so */
1193 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
1194 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
1195 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
1196 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1197 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1198 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1199 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
1200 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
1201 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1202 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1203 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1204 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
1205 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
1206 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
1207 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
1208 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
1209 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
1210 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
1211 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
1212 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
1213 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
1214 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
1215 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
1216 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
1217 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
1219 /* This expires in 2036 or so */
1220 static const BYTE childOfExpired[] = { 0x30, 0x81, 0xcc, 0x30, 0x78, 0xa0,
1221 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
1222 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d,
1223 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63,
1224 0x40, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e,
1225 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x35, 0x30, 0x35,
1226 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x35,
1227 0x30, 0x35, 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x30, 0x15, 0x31, 0x13,
1228 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e,
1229 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03,
1230 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
1231 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x20, 0x3b, 0xdb, 0x4d, 0x67, 0x50,
1232 0xec, 0x73, 0x9d, 0xf9, 0x85, 0x5d, 0x18, 0xe9, 0xb4, 0x98, 0xe3, 0x31, 0xb7,
1233 0x03, 0x0b, 0xc0, 0x39, 0x93, 0x56, 0x81, 0x0a, 0xfc, 0x78, 0xa8, 0x29, 0x42,
1234 0x5f, 0x69, 0xfb, 0xbc, 0x5b, 0xf2, 0xa6, 0x2a, 0xbe, 0x91, 0x2c, 0xfc, 0x89,
1235 0x69, 0x15, 0x18, 0x58, 0xe5, 0x02, 0x75, 0xf7, 0x2a, 0xb6, 0xa9, 0xfb, 0x47,
1236 0x6a, 0x6e, 0x0a, 0x9b, 0xe9, 0xdc };
1240 * A chain with two issuers, only one of whose dates is valid.
1242 static const BYTE chain10_0[] = {
1243 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1244 0x4a,0x30,0x3a,0x42,0xa2,0x5a,0xb3,0x93,0x4d,0x94,0x06,0xad,0x6d,0x1c,0x34,
1245 0xe6,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1246 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1247 0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1248 0x30,0x5a,0x17,0x0d,0x30,0x36,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1249 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1250 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1251 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1252 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1253 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1254 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1255 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1256 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1257 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1258 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1259 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1260 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1261 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1262 0x81,0x00,0x85,0x6e,0x35,0x2f,0x2c,0x51,0x4f,0xd6,0x2a,0xe4,0x9e,0xd0,0x4b,
1263 0xe6,0x90,0xfd,0xf7,0x20,0xad,0x76,0x3f,0x93,0xea,0x7f,0x0d,0x1f,0xb3,0x8e,
1264 0xfd,0xe0,0xe1,0xd6,0xd7,0x9c,0x7d,0x46,0x6b,0x15,0x5c,0xe6,0xc9,0x62,0x3b,
1265 0x70,0x4a,0x4b,0xb2,0x82,0xe3,0x55,0x0c,0xc4,0x90,0x44,0x06,0x6c,0x86,0x1c,
1266 0x6d,0x47,0x12,0xda,0x33,0x95,0x5d,0x98,0x43,0xcb,0x7c,0xfa,0x2b,0xee,0xc4,
1267 0x2d,0xc8,0x95,0x33,0x89,0x08,0x3f,0x9f,0x87,0xea,0x20,0x04,0xaf,0x58,0x4b,
1268 0x9d,0xc0,0x7c,0x0a,0x1b,0x05,0x31,0x3b,0xbb,0x13,0x58,0x2e,0x3f,0x61,0x6b,
1269 0x10,0xb4,0xeb,0xb9,0x1a,0x30,0xfd,0xea,0xca,0x29,0x99,0x5f,0x42,0x2b,0x00,
1270 0xb0,0x08,0xc3,0xf0,0xb6,0xd6,0x6b,0xf9,0x35,0x95 };
1271 static const BYTE chain10_1[] = {
1272 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1273 0xbf,0x99,0x4f,0x14,0x03,0x77,0x44,0xb8,0x49,0x02,0x70,0xa1,0xb8,0x9c,0xa7,
1274 0x24,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1275 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1276 0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1277 0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1278 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1279 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1280 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1281 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1282 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1283 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1284 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1285 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1286 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1287 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1288 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1289 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1290 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1291 0x81,0x00,0xa8,0xec,0x8c,0x34,0xe7,0x2c,0xdf,0x75,0x87,0xc4,0xf7,0xda,0x71,
1292 0x72,0x29,0xb2,0x48,0xa8,0x2a,0xec,0x7b,0x7d,0x19,0xb9,0x5f,0x1d,0xd9,0x91,
1293 0x2b,0xc4,0x28,0x7e,0xd6,0xb5,0x91,0x69,0xa5,0x8a,0x1a,0x1f,0x97,0x98,0x46,
1294 0x9d,0xdf,0x12,0xf6,0x45,0x62,0xad,0x60,0xb6,0xba,0xb0,0xfd,0xf5,0x9f,0xc6,
1295 0x98,0x05,0x4f,0x4d,0x48,0xdc,0xee,0x69,0xbe,0xb8,0xc4,0xc4,0xd7,0x1b,0xb1,
1296 0x1f,0x64,0xd6,0x45,0xa7,0xdb,0xb3,0x87,0x63,0x0f,0x54,0xe1,0x3a,0x6b,0x57,
1297 0x36,0xd7,0x68,0x65,0xcf,0xda,0x57,0x8d,0xcd,0x84,0x75,0x47,0x26,0x2c,0xef,
1298 0x1e,0x8f,0xc7,0x3b,0xee,0x5d,0x03,0xa6,0xdf,0x3a,0x20,0xb2,0xcc,0xc9,0x09,
1299 0x2c,0xfe,0x2b,0x79,0xb0,0xca,0x2c,0x9a,0x81,0x6b };
1300 static const BYTE chain7_1[] = {
1301 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
1302 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,
1303 0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,
1304 0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,
1305 0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,
1306 0x35,0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,
1307 0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,
1308 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,
1309 0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,
1310 0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,
1311 0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,
1312 0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,
1313 0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,
1314 0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,
1315 0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,
1316 0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,
1317 0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,
1318 0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1319 0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9f,0x69,0xfd,0x26,0xd5,0x4b,
1320 0xe0,0xab,0x12,0x21,0xb9,0xfc,0xf7,0xe0,0x0c,0x09,0x94,0xad,0x27,0xd7,0x9d,
1321 0xa3,0xcc,0x46,0x2a,0x25,0x9a,0x24,0xa7,0x31,0x58,0x78,0xf5,0xfc,0x30,0xe1,
1322 0x6d,0xfd,0x59,0xab,0xbe,0x69,0xa0,0xea,0xe3,0x7d,0x7a,0x7b,0xe5,0x85,0xeb,
1323 0x86,0x6a,0x84,0x3c,0x96,0x01,0x1a,0x70,0xa7,0xb8,0xcb,0xf2,0x11,0xe7,0x52,
1324 0x9c,0x58,0x2d,0xac,0x63,0xce,0x72,0x4b,0xad,0x62,0xa8,0x1d,0x75,0x96,0xe2,
1325 0x27,0xf5,0x6f,0xba,0x91,0xf8,0xf1,0xb0,0xbf,0x90,0x24,0x6d,0xba,0x5d,0xd7,
1326 0x39,0x63,0x3b,0x7c,0x04,0x5d,0x89,0x9d,0x1c,0xf2,0xf7,0xcc,0xdf,0x6e,0x8a,
1327 0x43,0xa9,0xdd,0x86,0x05,0xa2,0xf3,0x22,0x2d,0x1e,0x70,0xa1,0x59,0xd7,0xa5,
1330 static void testGetIssuerCert(void)
1333 PCCERT_CONTEXT parent, child, cert1, cert2;
1334 DWORD flags = 0xffffffff;
1335 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1336 CERT_STORE_CREATE_NEW_FLAG, NULL);
1338 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1340 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1341 expiredCert, sizeof(expiredCert), CERT_STORE_ADD_ALWAYS, NULL);
1342 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1345 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1346 childOfExpired, sizeof(childOfExpired), CERT_STORE_ADD_ALWAYS, &child);
1347 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1351 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, NULL);
1352 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, NULL);
1354 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, &flags);
1355 ok(!parent && GetLastError() == E_INVALIDARG,
1356 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1357 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, &flags);
1358 ok(!parent && GetLastError() == E_INVALIDARG,
1359 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1360 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1361 ok(!parent && GetLastError() == E_INVALIDARG,
1362 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1363 /* Confusing: the caller cannot set either of the
1364 * CERT_STORE_NO_*_FLAGs, as these are not checks,
1367 flags = CERT_STORE_NO_CRL_FLAG | CERT_STORE_NO_ISSUER_FLAG;
1368 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1369 ok(!parent && GetLastError() == E_INVALIDARG,
1370 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1371 /* Perform no checks */
1373 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1374 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1377 CertFreeCertificateContext(parent);
1378 /* Check revocation and signature only */
1379 flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG;
1380 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1381 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1383 /* Confusing: CERT_STORE_REVOCATION_FLAG succeeds when there is no CRL by
1384 * setting CERT_STORE_NO_CRL_FLAG.
1386 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
1387 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
1390 CertFreeCertificateContext(parent);
1391 /* Checking time validity is not productive, because while most Windows
1392 * versions return 0 (time valid) because the child is not expired,
1393 * Windows 2003 SP1 returns that it is expired. Thus the range of
1394 * possibilities is covered, and a test verifies nothing.
1397 CertFreeCertificateContext(child);
1398 CertCloseStore(store, 0);
1401 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1402 CERT_STORE_CREATE_NEW_FLAG, NULL);
1403 /* With only the child certificate, no issuer will be found */
1404 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1405 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1406 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1407 ok(parent == NULL, "Expected no issuer\n");
1408 /* Adding an issuer allows one (and only one) issuer to be found */
1409 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1410 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert1);
1411 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1412 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1413 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1414 ok(parent == NULL, "Expected only one issuer\n");
1415 /* Adding a second issuer allows two issuers to be found - and the second
1416 * issuer is found before the first, implying certs are added to the head
1419 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1420 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert2);
1421 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1422 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1423 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1424 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1425 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1426 ok(parent == NULL, "Expected no more than two issuers\n");
1427 CertFreeCertificateContext(child);
1428 CertFreeCertificateContext(cert1);
1429 CertFreeCertificateContext(cert2);
1430 CertCloseStore(store, 0);
1432 /* Repeat the test, reversing the order in which issuers are added,
1433 * to show it's order-dependent.
1435 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1436 CERT_STORE_CREATE_NEW_FLAG, NULL);
1437 /* With only the child certificate, no issuer will be found */
1438 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1439 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1440 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1441 ok(parent == NULL, "Expected no issuer\n");
1442 /* Adding an issuer allows one (and only one) issuer to be found */
1443 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1444 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert1);
1445 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1446 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1447 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1448 ok(parent == NULL, "Expected only one issuer\n");
1449 /* Adding a second issuer allows two issuers to be found - and the second
1450 * issuer is found before the first, implying certs are added to the head
1453 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1454 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert2);
1455 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1456 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1457 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1458 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1459 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1460 ok(parent == NULL, "Expected no more than two issuers\n");
1461 CertFreeCertificateContext(child);
1462 CertFreeCertificateContext(cert1);
1463 CertFreeCertificateContext(cert2);
1464 CertCloseStore(store, 0);
1467 static void testCryptHashCert(void)
1469 static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b,
1470 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07,
1472 static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee,
1473 0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8,
1475 static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:";
1478 DWORD hashLen = sizeof(hash);
1480 /* NULL buffer and nonzero length crashes
1481 ret = CryptHashCertificate(0, 0, 0, NULL, size, hash, &hashLen);
1482 empty hash length also crashes
1483 ret = CryptHashCertificate(0, 0, 0, buf, size, hash, NULL);
1485 /* Test empty hash */
1486 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), NULL,
1488 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1489 ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen);
1490 /* Test with empty buffer */
1491 ret = CryptHashCertificate(0, 0, 0, NULL, 0, hash, &hashLen);
1492 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1493 ok(!memcmp(hash, emptyHash, sizeof(emptyHash)),
1494 "Unexpected hash of nothing\n");
1495 /* Test a known value */
1496 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), hash,
1498 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1499 ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
1502 static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen,
1503 const BYTE *sig, unsigned int sigLen)
1506 BOOL ret = CryptCreateHash(csp, CALG_SHA1, 0, 0, &hash);
1508 ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
1512 DWORD mySigSize = sizeof(mySig);
1514 ret = CryptHashData(hash, toSign, toSignLen, 0);
1515 ok(ret, "CryptHashData failed: %08x\n", GetLastError());
1516 /* use the A variant so the test can run on Win9x */
1517 ret = CryptSignHashA(hash, AT_SIGNATURE, NULL, 0, mySig, &mySigSize);
1518 ok(ret, "CryptSignHash failed: %08x\n", GetLastError());
1521 ok(mySigSize == sigLen, "Expected sig length %d, got %d\n",
1523 ok(!memcmp(mySig, sig, sigLen), "Unexpected signature\n");
1525 CryptDestroyHash(hash);
1529 /* Tests signing the certificate described by toBeSigned with the CSP passed in,
1530 * using the algorithm with OID sigOID. The CSP is assumed to be empty, and a
1531 * keyset named AT_SIGNATURE will be added to it. The signing key will be
1532 * stored in *key, and the signature will be stored in sig. sigLen should be
1533 * at least 64 bytes.
1535 static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1536 LPCSTR sigOID, HCRYPTKEY *key, BYTE *sig, DWORD *sigLen)
1540 CRYPT_ALGORITHM_IDENTIFIER algoID = { NULL, { 0, NULL } };
1543 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1544 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, &size);
1545 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1546 NULL, NULL, NULL, &size);
1548 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1549 &algoID, NULL, NULL, &size);
1550 ok(!ret && GetLastError() == NTE_BAD_ALGID,
1551 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1552 algoID.pszObjId = (LPSTR)sigOID;
1553 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1554 &algoID, NULL, NULL, &size);
1555 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1556 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1558 ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData,
1559 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1560 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1561 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1564 /* No keys exist in the new CSP yet.. */
1565 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1566 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1567 ok(!ret && (GetLastError() == NTE_BAD_KEYSET || GetLastError() ==
1568 NTE_NO_KEY), "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %08x\n",
1570 ret = CryptGenKey(csp, AT_SIGNATURE, 0, key);
1571 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1574 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1575 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1576 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1577 ok(size <= *sigLen, "Expected size <= %d, got %d\n", *sigLen, size);
1580 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1581 toBeSigned->cbData, &algoID, NULL, sig, &size);
1582 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1586 verifySig(csp, toBeSigned->pbData, toBeSigned->cbData, sig,
1593 static void testVerifyCertSig(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1594 LPCSTR sigOID, const BYTE *sig, DWORD sigLen)
1596 CERT_SIGNED_CONTENT_INFO info;
1601 if (!pCryptVerifyCertificateSignatureEx)
1603 skip("no CryptVerifyCertificateSignatureEx support\n");
1606 if (!pCryptEncodeObjectEx)
1608 skip("no CryptEncodeObjectEx support\n");
1611 ret = pCryptVerifyCertificateSignatureEx(0, 0, 0, NULL, 0, NULL, 0, NULL);
1612 ok(!ret && GetLastError() == E_INVALIDARG,
1613 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1614 ret = pCryptVerifyCertificateSignatureEx(csp, 0, 0, NULL, 0, NULL, 0, NULL);
1615 ok(!ret && GetLastError() == E_INVALIDARG,
1616 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1617 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 0, NULL, 0,
1619 ok(!ret && GetLastError() == E_INVALIDARG,
1620 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1622 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1623 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, NULL, 0, NULL, 0, NULL);
1625 info.ToBeSigned.cbData = toBeSigned->cbData;
1626 info.ToBeSigned.pbData = toBeSigned->pbData;
1627 info.SignatureAlgorithm.pszObjId = (LPSTR)sigOID;
1628 info.SignatureAlgorithm.Parameters.cbData = 0;
1629 info.Signature.cbData = sigLen;
1630 info.Signature.pbData = (BYTE *)sig;
1631 info.Signature.cUnusedBits = 0;
1632 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT, &info,
1633 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&cert, &size);
1634 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1637 CRYPT_DATA_BLOB certBlob = { 0, NULL };
1638 PCERT_PUBLIC_KEY_INFO pubKeyInfo = NULL;
1640 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1641 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1642 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
1643 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
1644 certBlob.cbData = 1;
1645 certBlob.pbData = (void *)0xdeadbeef;
1646 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1647 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1648 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1649 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1650 certBlob.cbData = size;
1651 certBlob.pbData = cert;
1652 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1653 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1654 ok(!ret && GetLastError() == E_INVALIDARG,
1655 "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_NULL, NULL, 0, NULL);
1659 ok(!ret && GetLastError() == E_INVALIDARG,
1660 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1662 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1663 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1664 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, NULL, 0, NULL);
1666 CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
1667 (LPSTR)sigOID, 0, NULL, NULL, &size);
1668 pubKeyInfo = HeapAlloc(GetProcessHeap(), 0, size);
1671 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
1672 X509_ASN_ENCODING, (LPSTR)sigOID, 0, NULL, pubKeyInfo, &size);
1673 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
1676 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1677 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1678 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pubKeyInfo, 0, NULL);
1679 ok(ret, "CryptVerifyCertificateSignatureEx failed: %08x\n",
1682 HeapFree(GetProcessHeap(), 0, pubKeyInfo);
1688 static BYTE emptyCert[] = { 0x30, 0x00 };
1690 static void testCertSigs(void)
1693 CRYPT_DATA_BLOB toBeSigned = { sizeof(emptyCert), emptyCert };
1697 DWORD sigSize = sizeof(sig);
1699 /* Just in case a previous run failed, delete this thing */
1700 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1701 CRYPT_DELETEKEYSET);
1702 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1704 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1706 testSignCert(csp, &toBeSigned, szOID_RSA_SHA1RSA, &key, sig, &sigSize);
1707 testVerifyCertSig(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize);
1709 CryptDestroyKey(key);
1710 CryptReleaseContext(csp, 0);
1711 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1712 CRYPT_DELETEKEYSET);
1715 static const BYTE md5SignedEmptyCert[] = {
1716 0x30,0x56,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1717 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
1718 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
1719 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1720 0x0d,0x02,0x05,0x05,0x00,0x03,0x11,0x00,0xfb,0x0f,0x66,0x82,0x66,0xd9,0xe5,0xf8,
1721 0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
1722 static const BYTE md5SignedEmptyCertNoNull[] = {
1723 0x30,0x54,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1724 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
1725 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
1726 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1727 0x0d,0x02,0x05,0x03,0x11,0x00,0x04,0xd9,0xa5,0xe1,0x2b,0x55,0xa2,0xd8,0xf8,0xe5,
1728 0xd9,0x66,0x82,0x66,0x0f,0xfb };
1730 static void testSignAndEncodeCert(void)
1732 static char oid_rsa_md5rsa[] = szOID_RSA_MD5RSA;
1733 static char oid_rsa_md5[] = szOID_RSA_MD5;
1736 CRYPT_ALGORITHM_IDENTIFIER algID = { 0 };
1737 CERT_INFO info = { 0 };
1740 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1742 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1745 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, &algID, NULL, NULL,
1747 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1748 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1749 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, NULL, NULL,
1750 &algID, NULL, NULL, &size);
1751 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1752 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1753 ret = CryptSignAndEncodeCertificate(0, 0, 0, X509_CERT_TO_BE_SIGNED, NULL,
1754 &algID, NULL, NULL, &size);
1755 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1756 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1757 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1758 X509_CERT_TO_BE_SIGNED, NULL, &algID, NULL, NULL, &size);
1759 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1760 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1762 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1763 X509_CERT_TO_BE_SIGNED, &info, NULL, NULL, NULL, &size);
1765 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1766 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1767 ok(!ret && GetLastError() == NTE_BAD_ALGID,
1768 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1769 algID.pszObjId = oid_rsa_md5rsa;
1770 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1771 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1772 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1773 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1775 algID.pszObjId = oid_rsa_md5;
1776 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1777 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1778 ok(ret, "CryptSignAndEncodeCertificate failed: %08x\n", GetLastError());
1781 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
1785 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1786 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, buf, &size);
1787 ok(ret, "CryptSignAndEncodeCertificate failed: %08x\n",
1789 /* Tricky: because the NULL parameters may either be omitted or
1790 * included as an asn.1-encoded NULL (0x05,0x00), two different
1791 * values are allowed.
1793 ok(size == sizeof(md5SignedEmptyCert) ||
1794 size == sizeof(md5SignedEmptyCertNoNull), "Unexpected size %d\n",
1796 if (size == sizeof(md5SignedEmptyCert))
1797 ok(!memcmp(buf, md5SignedEmptyCert, size),
1798 "Unexpected value\n");
1799 else if (size == sizeof(md5SignedEmptyCertNoNull))
1800 ok(!memcmp(buf, md5SignedEmptyCertNoNull, size),
1801 "Unexpected value\n");
1802 HeapFree(GetProcessHeap(), 0, buf);
1807 static void testCreateSelfSignCert(void)
1809 PCCERT_CONTEXT context;
1810 CERT_NAME_BLOB name = { sizeof(subjectName), subjectName };
1814 CRYPT_KEY_PROV_INFO info;
1816 if (!pCertCreateSelfSignCertificate)
1818 skip("CertCreateSelfSignCertificate() is not available\n");
1823 context = pCertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL,
1825 * Calling this with no first parameter creates a new key container, which
1826 * lasts beyond the test, so I don't test that. Nb: the generated key
1828 context = pCertCreateSelfSignCertificate(0, &name, 0, NULL, NULL, NULL, NULL,
1833 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1834 CRYPT_DELETEKEYSET);
1835 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1837 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1839 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1841 ok(!context && GetLastError() == NTE_NO_KEY,
1842 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1843 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
1844 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1847 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1849 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1854 PCRYPT_KEY_PROV_INFO info;
1856 /* The context must have a key provider info property */
1857 ret = CertGetCertificateContextProperty(context,
1858 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1859 ok(ret && size, "Expected non-zero key provider info\n");
1862 info = HeapAlloc(GetProcessHeap(), 0, size);
1865 ret = CertGetCertificateContextProperty(context,
1866 CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1867 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1871 /* Sanity-check the key provider */
1872 ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1873 "Unexpected key container\n");
1874 ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1875 "Unexpected provider\n");
1876 ok(info->dwKeySpec == AT_SIGNATURE,
1877 "Expected AT_SIGNATURE, got %d\n", info->dwKeySpec);
1879 HeapFree(GetProcessHeap(), 0, info);
1883 CertFreeCertificateContext(context);
1886 CryptDestroyKey(key);
1889 CryptReleaseContext(csp, 0);
1890 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1891 CRYPT_DELETEKEYSET);
1893 /* do the same test with AT_KEYEXCHANGE and key info*/
1894 memset(&info,0,sizeof(info));
1895 info.dwProvType = PROV_RSA_FULL;
1896 info.dwKeySpec = AT_KEYEXCHANGE;
1897 info.pwszProvName = (LPWSTR) MS_DEF_PROV_W;
1898 info.pwszContainerName = cspNameW;
1899 context = pCertCreateSelfSignCertificate(0, &name, 0, &info, NULL, NULL,
1901 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1906 PCRYPT_KEY_PROV_INFO info;
1908 /* The context must have a key provider info property */
1909 ret = CertGetCertificateContextProperty(context,
1910 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1911 ok(ret && size, "Expected non-zero key provider info\n");
1914 info = HeapAlloc(GetProcessHeap(), 0, size);
1917 ret = CertGetCertificateContextProperty(context,
1918 CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1919 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1923 /* Sanity-check the key provider */
1924 ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1925 "Unexpected key container\n");
1926 ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1927 "Unexpected provider\n");
1928 ok(info->dwKeySpec == AT_KEYEXCHANGE,
1929 "Expected AT_KEYEXCHANGE, got %d\n", info->dwKeySpec);
1931 HeapFree(GetProcessHeap(), 0, info);
1935 CertFreeCertificateContext(context);
1938 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
1939 CRYPT_DELETEKEYSET);
1942 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
1943 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
1945 static void testKeyUsage(void)
1948 PCCERT_CONTEXT context;
1951 /* Test base cases */
1952 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, NULL);
1953 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1954 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1956 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
1957 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1958 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1960 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
1961 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1962 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1964 ret = CertSetEnhancedKeyUsage(NULL, NULL);
1965 usage.cUsageIdentifier = 0;
1966 ret = CertSetEnhancedKeyUsage(NULL, &usage);
1968 /* Test with a cert with no enhanced key usage extension */
1969 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
1971 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
1975 static const char oid[] = "1.2.3.4";
1976 BYTE buf[sizeof(CERT_ENHKEY_USAGE) + 2 * (sizeof(LPSTR) + sizeof(oid))];
1977 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
1979 ret = CertGetEnhancedKeyUsage(context, 0, NULL, NULL);
1980 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1981 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
1983 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &size);
1986 /* Windows 2000, ME, or later: even though it succeeded, we expect
1987 * CRYPT_E_NOT_FOUND, which indicates there is no enhanced key
1988 * usage set for this cert (which implies it's valid for all uses.)
1990 ok(GetLastError() == CRYPT_E_NOT_FOUND,
1991 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1992 ok(size == sizeof(CERT_ENHKEY_USAGE), "Wrong size %d\n", size);
1993 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
1994 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
1995 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
1996 pUsage->cUsageIdentifier);
2000 /* Windows NT, 95, or 98: it fails, and the last error is
2001 * CRYPT_E_NOT_FOUND.
2003 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2004 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2006 /* I can add a usage identifier when no key usage has been set */
2007 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2008 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2011 ret = CertGetEnhancedKeyUsage(context,
2012 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2013 ok(ret && GetLastError() == 0,
2014 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2015 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2016 pUsage->cUsageIdentifier);
2017 if (pUsage->cUsageIdentifier)
2018 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2019 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2020 /* Now set an empty key usage */
2021 pUsage->cUsageIdentifier = 0;
2022 ret = CertSetEnhancedKeyUsage(context, pUsage);
2023 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2024 /* Shouldn't find it in the cert */
2026 ret = CertGetEnhancedKeyUsage(context,
2027 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2028 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2029 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2030 /* Should find it as an extended property */
2031 ret = CertGetEnhancedKeyUsage(context,
2032 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2033 ok(ret && GetLastError() == 0,
2034 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2035 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2036 pUsage->cUsageIdentifier);
2037 /* Should find it as either */
2038 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2039 ok(ret && GetLastError() == 0,
2040 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2041 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2042 pUsage->cUsageIdentifier);
2043 /* Add a usage identifier */
2044 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2045 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2048 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2049 ok(ret && GetLastError() == 0,
2050 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2051 ok(pUsage->cUsageIdentifier == 1, "Expected 1 identifier, got %d\n",
2052 pUsage->cUsageIdentifier);
2053 if (pUsage->cUsageIdentifier)
2054 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2055 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2056 /* Re-adding the same usage identifier succeeds, though it only adds
2057 * a duplicate usage identifier on versions prior to Vista
2059 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2060 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2063 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2064 ok(ret && GetLastError() == 0,
2065 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2066 ok(pUsage->cUsageIdentifier == 1 || pUsage->cUsageIdentifier == 2,
2067 "Expected 1 or 2 identifiers, got %d\n", pUsage->cUsageIdentifier);
2068 if (pUsage->cUsageIdentifier)
2069 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2070 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2071 if (pUsage->cUsageIdentifier >= 2)
2072 ok(!strcmp(pUsage->rgpszUsageIdentifier[1], oid),
2073 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[1]);
2074 /* Now set a NULL extended property--this deletes the property. */
2075 ret = CertSetEnhancedKeyUsage(context, NULL);
2076 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2077 SetLastError(0xbaadcafe);
2079 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2080 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2081 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2083 CertFreeCertificateContext(context);
2085 /* Now test with a cert with an enhanced key usage extension */
2086 context = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2087 sizeof(certWithUsage));
2088 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2093 DWORD bufSize = 0, i;
2095 /* The size may depend on what flags are used to query it, so I
2096 * realloc the buffer for each test.
2098 ret = CertGetEnhancedKeyUsage(context,
2099 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2100 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2101 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2104 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2106 /* Should find it in the cert */
2108 ret = CertGetEnhancedKeyUsage(context,
2109 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2110 ok(ret && GetLastError() == 0,
2111 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2112 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2113 pUsage->cUsageIdentifier);
2114 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2115 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2116 "Expected %s, got %s\n", keyUsages[i],
2117 pUsage->rgpszUsageIdentifier[i]);
2118 HeapFree(GetProcessHeap(), 0, buf);
2120 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2121 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2122 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2125 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2127 /* Should find it as either */
2129 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2130 /* In Windows, GetLastError returns CRYPT_E_NOT_FOUND not found
2131 * here, even though the return is successful and the usage id
2132 * count is positive. I don't enforce that here.
2135 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2136 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2137 pUsage->cUsageIdentifier);
2138 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2139 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2140 "Expected %s, got %s\n", keyUsages[i],
2141 pUsage->rgpszUsageIdentifier[i]);
2142 HeapFree(GetProcessHeap(), 0, buf);
2144 /* Shouldn't find it as an extended property */
2145 ret = CertGetEnhancedKeyUsage(context,
2146 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &size);
2147 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2148 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2149 /* Adding a usage identifier overrides the cert's usage!? */
2150 ret = CertAddEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2151 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2153 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2154 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2155 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2158 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2160 /* Should find it as either */
2162 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2164 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2165 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2166 pUsage->cUsageIdentifier);
2167 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], szOID_RSA_RSA),
2168 "Expected %s, got %s\n", szOID_RSA_RSA,
2169 pUsage->rgpszUsageIdentifier[0]);
2170 HeapFree(GetProcessHeap(), 0, buf);
2172 /* But querying the cert directly returns its usage */
2173 ret = CertGetEnhancedKeyUsage(context,
2174 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2175 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2176 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2179 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2182 ret = CertGetEnhancedKeyUsage(context,
2183 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2185 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2186 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2187 pUsage->cUsageIdentifier);
2188 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2189 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2190 "Expected %s, got %s\n", keyUsages[i],
2191 pUsage->rgpszUsageIdentifier[i]);
2192 HeapFree(GetProcessHeap(), 0, buf);
2194 /* And removing the only usage identifier in the extended property
2195 * results in the cert's key usage being found.
2197 ret = CertRemoveEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2198 ok(ret, "CertRemoveEnhancedKeyUsage failed: %08x\n", GetLastError());
2199 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2200 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2201 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2204 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2206 /* Should find it as either */
2208 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2210 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2211 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2212 pUsage->cUsageIdentifier);
2213 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2214 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2215 "Expected %s, got %s\n", keyUsages[i],
2216 pUsage->rgpszUsageIdentifier[i]);
2217 HeapFree(GetProcessHeap(), 0, buf);
2220 CertFreeCertificateContext(context);
2224 static const BYTE cert2WithUsage[] = {
2225 0x30,0x81,0x89,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2226 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2227 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2228 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2229 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2230 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2231 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x25,0x30,0x23,
2232 0x30,0x21,0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x17,0x30,0x15,0x06,
2233 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x2a,0x86,0x48,0x86,
2234 0xf7,0x0d,0x01,0x01,0x01 };
2236 static void testGetValidUsages(void)
2238 static const LPCSTR expectedOIDs[] = {
2239 "1.3.6.1.5.5.7.3.3",
2240 "1.3.6.1.5.5.7.3.2",
2241 "1.2.840.113549.1.1.1",
2243 static const LPCSTR expectedOIDs2[] = {
2244 "1.3.6.1.5.5.7.3.2",
2245 "1.2.840.113549.1.1.1",
2251 PCCERT_CONTEXT contexts[3];
2253 if (!pCertGetValidUsages)
2255 skip("CertGetValidUsages() is not available\n");
2260 ret = pCertGetValidUsages(0, NULL, NULL, NULL, NULL);
2261 ret = pCertGetValidUsages(0, NULL, NULL, NULL, &size);
2264 numOIDs = size = 0xdeadbeef;
2265 SetLastError(0xdeadbeef);
2266 ret = pCertGetValidUsages(1, &contexts[0], &numOIDs, NULL, &size);
2267 ok(ret, "CertGetValidUsages failed: %d\n", GetLastError());
2268 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2269 ok(size == 0, "Expected size 0, got %d\n", size);
2270 contexts[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2272 contexts[1] = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2273 sizeof(certWithUsage));
2274 contexts[2] = CertCreateCertificateContext(X509_ASN_ENCODING,
2275 cert2WithUsage, sizeof(cert2WithUsage));
2276 numOIDs = size = 0xdeadbeef;
2277 ret = pCertGetValidUsages(0, NULL, &numOIDs, NULL, &size);
2278 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2279 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2280 ok(size == 0, "Expected size 0, got %d\n", size);
2281 numOIDs = size = 0xdeadbeef;
2282 ret = pCertGetValidUsages(1, contexts, &numOIDs, NULL, &size);
2283 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2284 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2285 ok(size == 0, "Expected size 0, got %d\n", size);
2286 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, NULL, &size);
2287 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2288 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2289 ok(size, "Expected non-zero size\n");
2290 oids = HeapAlloc(GetProcessHeap(), 0, size);
2294 DWORD smallSize = 1;
2296 SetLastError(0xdeadbeef);
2297 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &smallSize);
2298 ok(!ret && GetLastError() == ERROR_MORE_DATA,
2299 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
2300 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2301 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2302 for (i = 0; i < numOIDs; i++)
2303 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2305 HeapFree(GetProcessHeap(), 0, oids);
2307 numOIDs = size = 0xdeadbeef;
2308 /* Oddly enough, this crashes when the number of contexts is not 1:
2309 ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2310 * but setting size to 0 allows it to succeed:
2313 ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2314 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2315 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2316 ok(size, "Expected non-zero size\n");
2317 oids = HeapAlloc(GetProcessHeap(), 0, size);
2322 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2323 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2324 for (i = 0; i < numOIDs; i++)
2325 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2327 HeapFree(GetProcessHeap(), 0, oids);
2329 numOIDs = 0xdeadbeef;
2331 ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, NULL, &size);
2332 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2333 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2334 ok(size, "Expected non-zero size\n");
2335 oids = HeapAlloc(GetProcessHeap(), 0, size);
2340 ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, oids, &size);
2341 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2342 for (i = 0; i < numOIDs; i++)
2343 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2345 HeapFree(GetProcessHeap(), 0, oids);
2347 numOIDs = 0xdeadbeef;
2349 ret = pCertGetValidUsages(3, contexts, &numOIDs, NULL, &size);
2350 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2351 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2352 ok(size, "Expected non-zero size\n");
2353 oids = HeapAlloc(GetProcessHeap(), 0, size);
2358 ret = pCertGetValidUsages(3, contexts, &numOIDs, oids, &size);
2359 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2360 for (i = 0; i < numOIDs; i++)
2361 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2363 HeapFree(GetProcessHeap(), 0, oids);
2365 CertFreeCertificateContext(contexts[0]);
2366 CertFreeCertificateContext(contexts[1]);
2367 CertFreeCertificateContext(contexts[2]);
2370 static void testCompareCertName(void)
2372 static BYTE bogus[] = { 1, 2, 3, 4 };
2373 static BYTE bogusPrime[] = { 0, 1, 2, 3, 4 };
2374 static BYTE emptyPrime[] = { 0x30, 0x00, 0x01 };
2376 CERT_NAME_BLOB blob1, blob2;
2379 ret = CertCompareCertificateName(0, NULL, NULL);
2381 /* An empty name checks against itself.. */
2382 blob1.pbData = emptyCert;
2383 blob1.cbData = sizeof(emptyCert);
2384 ret = CertCompareCertificateName(0, &blob1, &blob1);
2385 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2386 /* It doesn't have to be a valid encoded name.. */
2387 blob1.pbData = bogus;
2388 blob1.cbData = sizeof(bogus);
2389 ret = CertCompareCertificateName(0, &blob1, &blob1);
2390 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2391 /* Leading zeroes matter.. */
2392 blob2.pbData = bogusPrime;
2393 blob2.cbData = sizeof(bogusPrime);
2394 ret = CertCompareCertificateName(0, &blob1, &blob2);
2395 ok(!ret, "Expected failure\n");
2396 /* As do trailing extra bytes. */
2397 blob2.pbData = emptyPrime;
2398 blob2.cbData = sizeof(emptyPrime);
2399 ret = CertCompareCertificateName(0, &blob1, &blob2);
2400 ok(!ret, "Expected failure\n");
2403 static BYTE int1[] = { 0x88, 0xff, 0xff, 0xff };
2404 static BYTE int2[] = { 0x88, 0xff };
2405 static BYTE int3[] = { 0x23, 0xff };
2406 static BYTE int4[] = { 0x7f, 0x00 };
2407 static BYTE int5[] = { 0x7f };
2408 static BYTE int6[] = { 0x80, 0x00, 0x00, 0x00 };
2409 static BYTE int7[] = { 0x80, 0x00 };
2411 static struct IntBlobTest
2413 CRYPT_INTEGER_BLOB blob1;
2414 CRYPT_INTEGER_BLOB blob2;
2417 { { sizeof(int1), int1 }, { sizeof(int2), int2 }, TRUE },
2418 { { sizeof(int3), int3 }, { sizeof(int3), int3 }, TRUE },
2419 { { sizeof(int4), int4 }, { sizeof(int5), int5 }, TRUE },
2420 { { sizeof(int6), int6 }, { sizeof(int7), int7 }, TRUE },
2421 { { sizeof(int1), int1 }, { sizeof(int7), int7 }, FALSE },
2424 static void testCompareIntegerBlob(void)
2429 for (i = 0; i < sizeof(intBlobs) / sizeof(intBlobs[0]); i++)
2431 ret = CertCompareIntegerBlob(&intBlobs[i].blob1, &intBlobs[i].blob2);
2432 ok(ret == intBlobs[i].areEqual,
2433 "%d: expected blobs %s compare\n", i, intBlobs[i].areEqual ?
2438 static void testComparePublicKeyInfo(void)
2441 CERT_PUBLIC_KEY_INFO info1 = { { 0 } }, info2 = { { 0 } };
2442 static CHAR oid_rsa_rsa[] = szOID_RSA_RSA;
2443 static CHAR oid_rsa_sha1rsa[] = szOID_RSA_SHA1RSA;
2444 static CHAR oid_x957_dsa[] = szOID_X957_DSA;
2445 static BYTE bits1[] = { 1, 0 };
2446 static BYTE bits2[] = { 0 };
2447 static BYTE bits3[] = { 1 };
2450 ret = CertComparePublicKeyInfo(0, NULL, NULL);
2452 /* Empty public keys compare */
2453 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2454 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2455 /* Different OIDs appear to compare */
2456 info1.Algorithm.pszObjId = oid_rsa_rsa;
2457 info2.Algorithm.pszObjId = oid_rsa_sha1rsa;
2458 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2459 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2460 info2.Algorithm.pszObjId = oid_x957_dsa;
2461 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2462 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2463 info1.PublicKey.cbData = sizeof(bits1);
2464 info1.PublicKey.pbData = bits1;
2465 info1.PublicKey.cUnusedBits = 0;
2466 info2.PublicKey.cbData = sizeof(bits1);
2467 info2.PublicKey.pbData = bits1;
2468 info2.PublicKey.cUnusedBits = 0;
2469 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2470 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2471 /* Even though they compare in their used bits, these do not compare */
2472 info1.PublicKey.cbData = sizeof(bits2);
2473 info1.PublicKey.pbData = bits2;
2474 info1.PublicKey.cUnusedBits = 0;
2475 info2.PublicKey.cbData = sizeof(bits3);
2476 info2.PublicKey.pbData = bits3;
2477 info2.PublicKey.cUnusedBits = 1;
2478 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2479 /* Simple (non-comparing) case */
2480 ok(!ret, "Expected keys not to compare\n");
2481 info2.PublicKey.cbData = sizeof(bits1);
2482 info2.PublicKey.pbData = bits1;
2483 info2.PublicKey.cUnusedBits = 0;
2484 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2485 ok(!ret, "Expected keys not to compare\n");
2488 static void testHashPublicKeyInfo(void)
2491 CERT_PUBLIC_KEY_INFO info = { { 0 } };
2495 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, NULL);
2496 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, &info, NULL, NULL);
2498 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, &len);
2499 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2500 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2501 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, NULL, NULL, &len);
2502 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2503 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2504 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, NULL, &len);
2505 ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2506 ok(len == 16, "Expected hash size 16, got %d\n", len);
2509 static const BYTE emptyHash[] = { 0xb8,0x51,0x3a,0x31,0x0e,0x9f,0x40,
2510 0x36,0x9c,0x92,0x45,0x1b,0x9d,0xc8,0xf9,0xf6 };
2513 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, buf,
2515 ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2516 ok(!memcmp(buf, emptyHash, len), "Unexpected hash\n");
2520 static void testCompareCert(void)
2522 CERT_INFO info1 = { 0 }, info2 = { 0 };
2526 ret = CertCompareCertificate(X509_ASN_ENCODING, NULL, NULL);
2529 /* Certs with the same issuer and serial number are equal, even if they
2530 * differ in other respects (like subject).
2532 info1.SerialNumber.pbData = serialNum;
2533 info1.SerialNumber.cbData = sizeof(serialNum);
2534 info1.Issuer.pbData = subjectName;
2535 info1.Issuer.cbData = sizeof(subjectName);
2536 info1.Subject.pbData = subjectName2;
2537 info1.Subject.cbData = sizeof(subjectName2);
2538 info2.SerialNumber.pbData = serialNum;
2539 info2.SerialNumber.cbData = sizeof(serialNum);
2540 info2.Issuer.pbData = subjectName;
2541 info2.Issuer.cbData = sizeof(subjectName);
2542 info2.Subject.pbData = subjectName;
2543 info2.Subject.cbData = sizeof(subjectName);
2544 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2545 ok(ret, "Expected certs to be equal\n");
2547 info2.Issuer.pbData = subjectName2;
2548 info2.Issuer.cbData = sizeof(subjectName2);
2549 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2550 ok(!ret, "Expected certs not to be equal\n");
2553 static void testVerifySubjectCert(void)
2557 PCCERT_CONTEXT context1, context2;
2560 ret = CertVerifySubjectCertificateContext(NULL, NULL, NULL);
2563 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2564 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2566 flags = CERT_STORE_NO_CRL_FLAG;
2567 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2568 ok(!ret && GetLastError() == E_INVALIDARG,
2569 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2572 context1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2574 ret = CertVerifySubjectCertificateContext(NULL, context1, &flags);
2575 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2577 ret = CertVerifySubjectCertificateContext(context1, NULL, &flags);
2578 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2580 ret = CertVerifySubjectCertificateContext(context1, context1, &flags);
2581 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2584 context2 = CertCreateCertificateContext(X509_ASN_ENCODING,
2585 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject));
2586 SetLastError(0xdeadbeef);
2587 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2588 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2590 flags = CERT_STORE_REVOCATION_FLAG;
2591 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2592 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2594 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
2595 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
2597 flags = CERT_STORE_SIGNATURE_FLAG;
2598 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2599 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2601 ok(flags == CERT_STORE_SIGNATURE_FLAG,
2602 "Expected CERT_STORE_SIGNATURE_FLAG, got %08x\n", flags);
2603 CertFreeCertificateContext(context2);
2605 CertFreeCertificateContext(context1);
2608 static void testVerifyRevocation(void)
2611 CERT_REVOCATION_STATUS status = { 0 };
2612 PCCERT_CONTEXT cert = CertCreateCertificateContext(X509_ASN_ENCODING,
2613 bigCert, sizeof(bigCert));
2616 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL);
2618 SetLastError(0xdeadbeef);
2619 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2620 ok(!ret && GetLastError() == E_INVALIDARG,
2621 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2622 status.cbSize = sizeof(status);
2623 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2624 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2625 ret = CertVerifyRevocation(0, 2, 0, NULL, 0, NULL, &status);
2626 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2627 ret = CertVerifyRevocation(2, 0, 0, NULL, 0, NULL, &status);
2628 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2629 SetLastError(0xdeadbeef);
2630 ret = CertVerifyRevocation(0, 0, 1, (void **)&cert, 0, NULL, &status);
2631 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2632 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2633 SetLastError(0xdeadbeef);
2634 ret = CertVerifyRevocation(0, 2, 1, (void **)&cert, 0, NULL, &status);
2635 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2636 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2638 CertFreeCertificateContext(cert);
2641 static BYTE privKey[] = {
2642 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
2643 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
2644 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
2645 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
2646 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
2647 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
2648 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
2649 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
2650 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
2651 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
2652 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
2653 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
2654 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
2655 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
2656 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
2657 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
2658 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
2659 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
2660 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
2661 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
2662 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
2663 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
2664 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
2665 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
2667 static const BYTE selfSignedCert[] = {
2668 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2669 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
2670 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
2671 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
2672 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
2673 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
2674 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
2675 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
2676 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
2677 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
2678 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
2679 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
2680 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
2681 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
2682 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
2683 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
2684 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
2685 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
2686 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
2687 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
2688 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
2689 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
2690 0xa8, 0x76, 0x57, 0x92, 0x36 };
2692 static const BYTE exportedPublicKeyBlob[] = {
2693 0x06,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x31,0x00,0x02,0x00,0x00,
2694 0x01,0x00,0x01,0x00,0x79,0x10,0x1c,0xd0,0x6b,0x10,0x18,0x30,0x94,0x61,0xdc,0x0e,
2695 0xcb,0x96,0x4e,0x21,0x3f,0x79,0xcd,0xa9,0x17,0x62,0xbc,0xbb,0x61,0x4c,0xe0,0x75,
2696 0x38,0x6c,0xf3,0xde,0x60,0x86,0x03,0x97,0x65,0xeb,0x1e,0x6b,0xdb,0x53,0x85,0xad,
2697 0x68,0x21,0xf1,0x5d,0xe7,0x1f,0xe6,0x53,0xb4,0xbb,0x59,0x3e,0x14,0x27,0xb1,0x83,
2698 0xa7,0x3a,0x54,0xe2 };
2700 static const BYTE asnEncodedPublicKey[] = {
2701 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,
2702 0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
2703 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,
2704 0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
2705 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
2707 static void testAcquireCertPrivateKey(void)
2710 PCCERT_CONTEXT cert;
2712 DWORD size, keySpec;
2714 CRYPT_KEY_PROV_INFO keyProvInfo;
2716 WCHAR ms_def_prov_w[MAX_PATH];
2718 if (!pCryptAcquireCertificatePrivateKey)
2720 skip("CryptAcquireCertificatePrivateKey() is not available\n");
2724 lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
2726 keyProvInfo.pwszContainerName = cspNameW;
2727 keyProvInfo.pwszProvName = ms_def_prov_w;
2728 keyProvInfo.dwProvType = PROV_RSA_FULL;
2729 keyProvInfo.dwFlags = 0;
2730 keyProvInfo.cProvParam = 0;
2731 keyProvInfo.rgProvParam = NULL;
2732 keyProvInfo.dwKeySpec = AT_SIGNATURE;
2734 pCryptAcquireContextW(NULL, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
2735 CRYPT_DELETEKEYSET);
2737 cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
2738 sizeof(selfSignedCert));
2741 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL, NULL);
2742 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL,
2744 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, &keySpec,
2746 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, NULL, NULL);
2747 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, &keySpec,
2749 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, NULL, NULL, NULL);
2752 /* Missing private key */
2753 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, NULL, NULL);
2754 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2755 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2756 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2758 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2759 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2760 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2762 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2764 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2765 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2767 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
2769 ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
2770 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
2775 CERT_KEY_CONTEXT keyContext;
2777 /* Don't cache provider */
2778 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2779 &keySpec, &callerFree);
2780 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2782 ok(callerFree, "Expected callerFree to be TRUE\n");
2783 CryptReleaseContext(certCSP, 0);
2784 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2786 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2788 CryptReleaseContext(certCSP, 0);
2790 /* Use the key prov info's caching (there shouldn't be any) */
2791 ret = pCryptAcquireCertificatePrivateKey(cert,
2792 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2794 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2796 ok(callerFree, "Expected callerFree to be TRUE\n");
2797 CryptReleaseContext(certCSP, 0);
2799 /* Cache it (and check that it's cached) */
2800 ret = pCryptAcquireCertificatePrivateKey(cert,
2801 CRYPT_ACQUIRE_CACHE_FLAG, NULL, &certCSP, &keySpec, &callerFree);
2802 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2804 ok(!callerFree, "Expected callerFree to be FALSE\n");
2805 size = sizeof(keyContext);
2806 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2807 &keyContext, &size);
2808 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2811 /* Remove the cached provider */
2812 CryptReleaseContext(keyContext.hCryptProv, 0);
2813 CertSetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID, 0,
2815 /* Allow caching via the key prov info */
2816 keyProvInfo.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
2817 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2819 /* Now use the key prov info's caching */
2820 ret = pCryptAcquireCertificatePrivateKey(cert,
2821 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2823 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2825 ok(!callerFree, "Expected callerFree to be FALSE\n");
2826 size = sizeof(keyContext);
2827 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2828 &keyContext, &size);
2829 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2831 CryptReleaseContext(certCSP, 0);
2833 CryptDestroyKey(key);
2836 /* Some sanity-checking on public key exporting */
2837 ret = CryptImportPublicKeyInfo(csp, X509_ASN_ENCODING,
2838 &cert->pCertInfo->SubjectPublicKeyInfo, &key);
2839 ok(ret, "CryptImportPublicKeyInfo failed: %08x\n", GetLastError());
2842 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, NULL, &size);
2843 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
2846 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size), encodedKey;
2848 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, buf, &size);
2849 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
2850 ok(size == sizeof(exportedPublicKeyBlob), "Unexpected size %d\n",
2852 ok(!memcmp(buf, exportedPublicKeyBlob, size), "Unexpected value\n");
2853 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB,
2854 buf, CRYPT_ENCODE_ALLOC_FLAG, NULL, &encodedKey, &size);
2855 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2858 ok(size == sizeof(asnEncodedPublicKey), "Unexpected size %d\n",
2860 ok(!memcmp(encodedKey, asnEncodedPublicKey, size),
2861 "Unexpected value\n");
2862 LocalFree(encodedKey);
2864 HeapFree(GetProcessHeap(), 0, buf);
2866 CryptDestroyKey(key);
2868 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
2869 NULL, 0, NULL, NULL, &size);
2870 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
2873 PCERT_PUBLIC_KEY_INFO info = HeapAlloc(GetProcessHeap(), 0, size);
2875 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
2876 NULL, 0, NULL, info, &size);
2877 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
2880 ok(info->PublicKey.cbData == sizeof(asnEncodedPublicKey),
2881 "Unexpected size %d\n", info->PublicKey.cbData);
2882 ok(!memcmp(info->PublicKey.pbData, asnEncodedPublicKey,
2883 info->PublicKey.cbData), "Unexpected value\n");
2885 HeapFree(GetProcessHeap(), 0, info);
2888 CryptReleaseContext(csp, 0);
2889 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
2890 CRYPT_DELETEKEYSET);
2892 CertFreeCertificateContext(cert);
2895 static void testGetPublicKeyLength(void)
2897 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2898 static char oid_rsa_dh[] = szOID_RSA_DH;
2899 static char bogusOID[] = "1.2.3";
2901 CERT_PUBLIC_KEY_INFO info = { { 0 } };
2902 BYTE bogusKey[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
2903 BYTE key[] = { 0x30,0x0f,0x02,0x08,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2904 0x02,0x03,0x01,0x00,0x01 };
2907 ret = CertGetPublicKeyLength(0, NULL);
2909 /* With an empty public key info */
2910 SetLastError(0xdeadbeef);
2911 ret = CertGetPublicKeyLength(0, &info);
2912 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
2913 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
2914 ret, GetLastError());
2915 SetLastError(0xdeadbeef);
2916 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2917 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_EOD,
2918 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
2919 ret, GetLastError());
2920 /* With a nearly-empty public key info */
2921 info.Algorithm.pszObjId = oid_rsa_rsa;
2922 SetLastError(0xdeadbeef);
2923 ret = CertGetPublicKeyLength(0, &info);
2924 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
2925 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
2926 ret, GetLastError());
2927 SetLastError(0xdeadbeef);
2928 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2929 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_EOD,
2930 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
2931 ret, GetLastError());
2932 /* With a bogus key */
2933 info.PublicKey.cbData = sizeof(bogusKey);
2934 info.PublicKey.pbData = bogusKey;
2935 SetLastError(0xdeadbeef);
2936 ret = CertGetPublicKeyLength(0, &info);
2937 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
2938 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
2939 ret, GetLastError());
2940 SetLastError(0xdeadbeef);
2941 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2942 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_BADTAG,
2943 "Expected length 0 and CRYPT_E_ASN1_BADTAGTAG, got length %d, %08x\n",
2944 ret, GetLastError());
2945 /* With a believable RSA key but a bogus OID */
2946 info.Algorithm.pszObjId = bogusOID;
2947 info.PublicKey.cbData = sizeof(key);
2948 info.PublicKey.pbData = key;
2949 SetLastError(0xdeadbeef);
2950 ret = CertGetPublicKeyLength(0, &info);
2951 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
2952 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
2953 ret, GetLastError());
2954 SetLastError(0xdeadbeef);
2955 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2956 ok(ret == 56, "Expected length 56, got %d\n", ret);
2957 /* An RSA key with the DH OID */
2958 info.Algorithm.pszObjId = oid_rsa_dh;
2959 SetLastError(0xdeadbeef);
2960 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2961 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_BADTAG,
2962 "Expected length 0 and CRYPT_E_ASN1_BADTAG, got length %d, %08x\n",
2963 ret, GetLastError());
2964 /* With the RSA OID */
2965 info.Algorithm.pszObjId = oid_rsa_rsa;
2966 SetLastError(0xdeadbeef);
2967 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
2968 ok(ret == 56, "Expected length 56, got %d\n", ret);
2973 init_function_pointers();
2976 testCertProperties();
2979 testGetSubjectCert();
2980 testGetIssuerCert();
2982 testCryptHashCert();
2984 testSignAndEncodeCert();
2985 testCreateSelfSignCert();
2987 testGetValidUsages();
2988 testCompareCertName();
2989 testCompareIntegerBlob();
2990 testComparePublicKeyInfo();
2991 testHashPublicKeyInfo();
2993 testVerifySubjectCert();
2994 testVerifyRevocation();
2995 testAcquireCertPrivateKey();
2996 testGetPublicKeyLength();