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 * pCryptAcquireContextA)
41 (HCRYPTPROV *, LPCSTR, LPCSTR, 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, CryptAcquireContextA)
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.
160 * Both tests crash on some win9x boxes.
164 ret = CertAddEncodedCertificateToStore(0, X509_ASN_ENCODING, bigCert,
165 sizeof(bigCert), 0, NULL);
166 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
167 GetLastError() == E_INVALIDARG),
168 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n",
170 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
171 bigCert, sizeof(bigCert), 0, NULL);
172 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
173 GetLastError() == E_INVALIDARG),
174 "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n",
178 /* Weird--can add a cert to the NULL store (does this have special
182 ret = CertAddEncodedCertificateToStore(0, X509_ASN_ENCODING, bigCert,
183 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
184 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
187 CertFreeCertificateContext(context);
189 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
190 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
191 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
193 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
194 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
195 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
197 /* This has the same name as bigCert, so finding isn't done by name */
198 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
199 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, &context);
200 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
202 ok(context != NULL, "Expected a context\n");
205 CRYPT_DATA_BLOB hash = { sizeof(bigCert2Hash), bigCert2Hash };
207 /* Duplicate (AddRef) the context so we can still use it after
208 * deleting it from the store.
210 CertDuplicateCertificateContext(context);
211 CertDeleteCertificateFromStore(context);
212 /* Set the same hash as bigCert2, and try to readd it */
213 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID,
215 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
217 ret = CertAddCertificateContextToStore(store, context,
218 CERT_STORE_ADD_NEW, NULL);
219 /* The failure is a bit odd (CRYPT_E_ASN1_BADTAG), so just check
222 ok(!ret, "Expected failure\n");
223 CertFreeCertificateContext(context);
225 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
227 ok(context != NULL, "Expected a context\n");
230 /* Try to readd bigCert2 to the store */
231 ret = CertAddCertificateContextToStore(store, context,
232 CERT_STORE_ADD_NEW, NULL);
233 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
234 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
235 CertFreeCertificateContext(context);
238 /* Adding a cert with the same issuer name and serial number (but
239 * different subject) as an existing cert succeeds.
242 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
243 bigCert2WithDifferentSerial, sizeof(bigCert2WithDifferentSerial),
244 CERT_STORE_ADD_NEW, &context);
245 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
248 CertDeleteCertificateFromStore(context);
250 /* Adding a cert with the same subject name and serial number (but
251 * different issuer) as an existing cert succeeds.
254 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
255 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject),
256 CERT_STORE_ADD_NEW, &context);
257 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
260 CertDeleteCertificateFromStore(context);
262 /* Adding a cert with the same issuer name and serial number (but
263 * different otherwise) as an existing cert succeeds.
266 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
267 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer),
268 CERT_STORE_ADD_NEW, &context);
269 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
272 CertDeleteCertificateFromStore(context);
274 collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
275 CERT_STORE_CREATE_NEW_FLAG, NULL);
276 ok(collection != NULL, "CertOpenStore failed: %08x\n", GetLastError());
277 if (collection && pCertAddStoreToCollection)
279 /* Add store to the collection, but disable updates */
280 pCertAddStoreToCollection(collection, store, 0, 0);
282 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
284 ok(context != NULL, "Expected a context\n");
287 /* Try to readd bigCert2 to the collection */
288 ret = CertAddCertificateContextToStore(collection, context,
289 CERT_STORE_ADD_NEW, NULL);
290 ok(!ret && GetLastError() == CRYPT_E_EXISTS,
291 "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
292 /* Replacing an existing certificate context is allowed, even
293 * though updates to the collection aren't..
295 ret = CertAddCertificateContextToStore(collection, context,
296 CERT_STORE_ADD_REPLACE_EXISTING, NULL);
297 ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
299 /* use the existing certificate and ask for a copy of the context*/
301 ret = CertAddCertificateContextToStore(collection, context,
302 CERT_STORE_ADD_USE_EXISTING, ©Context);
303 ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
305 ok(copyContext != NULL, "Expected on output a non NULL copyContext\n");
307 CertFreeCertificateContext(copyContext);
308 /* but adding a new certificate isn't allowed. */
309 ret = CertAddCertificateContextToStore(collection, context,
310 CERT_STORE_ADD_ALWAYS, NULL);
311 ok(!ret && GetLastError() == E_ACCESSDENIED,
312 "Expected E_ACCESSDENIED, got %08x\n", GetLastError());
313 CertFreeCertificateContext(context);
316 CertCloseStore(collection, 0);
319 CertCloseStore(store, 0);
322 static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
323 PCCERT_CONTEXT context, DWORD propID)
325 BYTE hash[20] = { 0 }, hashProperty[20];
328 DWORD dwSizeWithNull;
330 memset(hash, 0, sizeof(hash));
331 memset(hashProperty, 0, sizeof(hashProperty));
333 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
334 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
335 ret = CertGetCertificateContextProperty(context, propID, NULL,
337 ok(ret, "algID %08x, propID %d: CertGetCertificateContextProperty failed: %08x\n",
338 algID, propID, GetLastError());
339 ret = CertGetCertificateContextProperty(context, propID, hashProperty,
341 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
343 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
345 ok(size == dwSizeWithNull, "Unexpected length of hash for property: received %d instead of %d\n",
346 dwSizeWithNull,size);
349 static CHAR cspNameA[] = "WineCryptTemp";
350 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e','m','p',0 };
351 static const BYTE v1CertWithPubKey[] = {
352 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
353 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
354 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
355 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
356 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
357 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
358 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
359 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
360 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
361 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
363 static const BYTE v1CertWithSubjectKeyId[] = {
364 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
365 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
366 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
367 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
368 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
369 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
370 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
371 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
372 0x4c,0x61,0x6e,0x67,0x00 };
373 static const BYTE subjectKeyId[] = {
374 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
375 static const BYTE selfSignedCert[] = {
376 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
377 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
378 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
379 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
380 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
381 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
382 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
383 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
384 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
385 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
386 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
387 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
388 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
389 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
390 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
391 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
392 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
393 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
394 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
395 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
396 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
397 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
398 0xa8, 0x76, 0x57, 0x92, 0x36 };
399 static const BYTE selfSignedSignatureHash[] = { 0x07,0x5a,0x3e,0xfd,0x0d,0xf6,
400 0x88,0xeb,0x00,0x64,0xbd,0xc9,0xd6,0xea,0x0a,0x7c,0xcc,0x24,0xdb,0x5d };
402 static void testCertProperties(void)
404 PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
405 bigCert, sizeof(bigCert));
406 DWORD propID, numProps, access, size;
408 BYTE hash[20] = { 0 }, hashProperty[20];
409 CRYPT_DATA_BLOB blob;
410 CERT_KEY_CONTEXT keyContext;
412 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
418 propID = CertEnumCertificateContextProperties(NULL, 0);
424 propID = CertEnumCertificateContextProperties(context, propID);
427 } while (propID != 0);
428 ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
430 /* Tests with a NULL cert context. Prop ID 0 fails.. */
431 ret = CertSetCertificateContextProperty(NULL, 0, 0, NULL);
432 ok(!ret && GetLastError() == E_INVALIDARG,
433 "Expected E_INVALIDARG, got %08x\n", GetLastError());
434 /* while this just crashes.
435 ret = CertSetCertificateContextProperty(NULL,
436 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
439 ret = CertSetCertificateContextProperty(context, 0, 0, NULL);
440 ok(!ret && GetLastError() == E_INVALIDARG,
441 "Expected E_INVALIDARG, got %08x\n", GetLastError());
442 /* Can't set the cert property directly, this crashes.
443 ret = CertSetCertificateContextProperty(context,
444 CERT_CERT_PROP_ID, 0, bigCert2);
448 ret = CertGetCertificateContextProperty(context,
449 CERT_ACCESS_STATE_PROP_ID, 0, NULL);
450 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
452 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
457 ret = CertGetCertificateContextProperty(context,
458 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
459 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
460 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
461 /* And, an implicit property */
462 size = sizeof(access);
463 ret = CertGetCertificateContextProperty(context,
464 CERT_ACCESS_STATE_PROP_ID, &access, &size);
465 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
467 ok(!(access & CERT_ACCESS_STATE_WRITE_PERSIST_FLAG),
468 "Didn't expect a persisted cert\n");
469 /* Trying to set this "read only" property crashes.
470 access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
471 ret = CertSetCertificateContextProperty(context,
472 CERT_ACCESS_STATE_PROP_ID, 0, &access);
475 /* Can I set the hash to an invalid hash? */
477 blob.cbData = sizeof(hash);
478 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
480 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
482 size = sizeof(hashProperty);
483 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
484 hashProperty, &size);
485 ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
486 /* Delete the (bogus) hash, and get the real one */
487 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
489 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
491 checkHash(bigCert, sizeof(bigCert), CALG_SHA1, context,
494 /* Now that the hash property is set, we should get one property when
500 propID = CertEnumCertificateContextProperties(context, propID);
503 } while (propID != 0);
504 ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
506 /* Check a few other implicit properties */
507 checkHash(bigCert, sizeof(bigCert), CALG_MD5, context,
508 CERT_MD5_HASH_PROP_ID);
510 /* Getting the signature hash fails with this bogus certificate */
512 ret = CertGetCertificateContextProperty(context,
513 CERT_SIGNATURE_HASH_PROP_ID, NULL, &size);
515 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
516 GetLastError() == CRYPT_E_NOT_FOUND ||
517 GetLastError() == OSS_DATA_ERROR), /* win9x */
518 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
520 /* Test key contexts and handles and such */
522 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
524 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
525 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
526 size = sizeof(CERT_KEY_CONTEXT);
527 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
529 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
530 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
531 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
533 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
534 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
535 /* Key context with an invalid size */
536 keyContext.cbSize = 0;
537 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
539 ok(!ret && GetLastError() == E_INVALIDARG,
540 "Expected E_INVALIDARG, got %08x\n", GetLastError());
541 size = sizeof(keyContext);
542 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
544 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
545 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
546 keyContext.cbSize = sizeof(keyContext);
547 keyContext.hCryptProv = 0;
548 keyContext.dwKeySpec = AT_SIGNATURE;
549 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
551 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
552 /* Now that that's set, the key prov handle property is also gettable.
554 size = sizeof(keyContext.hCryptProv);
555 ret = CertGetCertificateContextProperty(context,
556 CERT_KEY_PROV_HANDLE_PROP_ID, &keyContext.hCryptProv, &size);
557 ok(ret, "Expected to get the CERT_KEY_PROV_HANDLE_PROP_ID, got %08x\n",
559 /* Remove the key prov handle property.. */
560 ret = CertSetCertificateContextProperty(context,
561 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
562 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
564 /* and the key context's CSP is set to NULL. */
565 size = sizeof(keyContext);
566 ret = CertGetCertificateContextProperty(context,
567 CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
568 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
570 ok(keyContext.hCryptProv == 0, "Expected no hCryptProv\n");
572 /* According to MSDN the subject key id can be stored as a property,
573 * as a subject key extension, or as the SHA1 hash of the public key,
574 * but this cert has none of them:
576 ret = CertGetCertificateContextProperty(context,
577 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
578 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
579 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
580 CertFreeCertificateContext(context);
581 /* This cert does have a public key, but its subject key identifier still
582 * isn't available: */
583 context = CertCreateCertificateContext(X509_ASN_ENCODING,
584 v1CertWithPubKey, sizeof(v1CertWithPubKey));
585 ret = CertGetCertificateContextProperty(context,
586 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
587 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
588 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
589 CertFreeCertificateContext(context);
590 /* This cert with a subject key extension can have its key identifier
591 * property retrieved:
593 context = CertCreateCertificateContext(X509_ASN_ENCODING,
594 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId));
595 ret = CertGetCertificateContextProperty(context,
596 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
597 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
600 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
604 ret = CertGetCertificateContextProperty(context,
605 CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
606 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
608 ok(!memcmp(buf, subjectKeyId, size), "Unexpected subject key id\n");
609 HeapFree(GetProcessHeap(), 0, buf);
612 CertFreeCertificateContext(context);
614 context = CertCreateCertificateContext(X509_ASN_ENCODING,
615 selfSignedCert, sizeof(selfSignedCert));
616 /* Getting the signature hash of a valid (self-signed) cert succeeds */
618 ret = CertGetCertificateContextProperty(context,
619 CERT_SIGNATURE_HASH_PROP_ID, NULL, &size);
620 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
621 ok(size == sizeof(selfSignedSignatureHash), "unexpected size %d\n", size);
622 ret = CertGetCertificateContextProperty(context,
623 CERT_SIGNATURE_HASH_PROP_ID, hashProperty, &size);
625 ok(!memcmp(hashProperty, selfSignedSignatureHash, size),
626 "unexpected value\n");
627 CertFreeCertificateContext(context);
630 static void testDupCert(void)
633 PCCERT_CONTEXT context, dupContext;
636 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
637 CERT_STORE_CREATE_NEW_FLAG, NULL);
638 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
642 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
643 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
644 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
646 ok(context != NULL, "Expected a valid cert context\n");
649 ok(context->cbCertEncoded == sizeof(bigCert),
650 "Wrong cert size %d\n", context->cbCertEncoded);
651 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)),
652 "Unexpected encoded cert in context\n");
653 ok(context->hCertStore == store, "Unexpected store\n");
655 dupContext = CertDuplicateCertificateContext(context);
656 ok(dupContext != NULL, "Expected valid duplicate\n");
657 /* Not only is it a duplicate, it's identical: the address is the
660 ok(dupContext == context, "Expected identical context addresses\n");
661 CertFreeCertificateContext(dupContext);
662 CertFreeCertificateContext(context);
664 CertCloseStore(store, 0);
666 SetLastError(0xdeadbeef);
667 context = CertDuplicateCertificateContext(NULL);
668 ok(context == NULL, "Expected context to be NULL\n");
671 static BYTE subjectName3[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
672 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x52, 0x6f, 0x62, 0x20, 0x20, 0x4c, 0x61,
674 static const BYTE iTunesCert0[] = {
675 0x30,0x82,0x03,0xc4,0x30,0x82,0x03,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
676 0x47,0xbf,0x19,0x95,0xdf,0x8d,0x52,0x46,0x43,0xf7,0xdb,0x6d,0x48,0x0d,0x31,
677 0xa4,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
678 0x00,0x30,0x81,0x8b,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
679 0x5a,0x41,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0c,0x57,0x65,
680 0x73,0x74,0x65,0x72,0x6e,0x20,0x43,0x61,0x70,0x65,0x31,0x14,0x30,0x12,0x06,
681 0x03,0x55,0x04,0x07,0x13,0x0b,0x44,0x75,0x72,0x62,0x61,0x6e,0x76,0x69,0x6c,
682 0x6c,0x65,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x0a,0x13,0x06,0x54,0x68,
683 0x61,0x77,0x74,0x65,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14,
684 0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
685 0x61,0x74,0x69,0x6f,0x6e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13,
686 0x16,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
687 0x6d,0x70,0x69,0x6e,0x67,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x33,0x31,
688 0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x33,0x31,
689 0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x53,0x31,0x0b,0x30,
690 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,
691 0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
692 0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,
693 0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,0x6d,0x65,0x20,
694 0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,0x76,0x69,0x63,
695 0x65,0x73,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,
696 0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,
697 0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa9,0xca,0xb2,0xa4,0xcc,0xcd,0x20,
698 0xaf,0x0a,0x7d,0x89,0xac,0x87,0x75,0xf0,0xb4,0x4e,0xf1,0xdf,0xc1,0x0f,0xbf,
699 0x67,0x61,0xbd,0xa3,0x64,0x1c,0xda,0xbb,0xf9,0xca,0x33,0xab,0x84,0x30,0x89,
700 0x58,0x7e,0x8c,0xdb,0x6b,0xdd,0x36,0x9e,0x0f,0xbf,0xd1,0xec,0x78,0xf2,0x77,
701 0xa6,0x7e,0x6f,0x3c,0xbf,0x93,0xaf,0x0d,0xba,0x68,0xf4,0x6c,0x94,0xca,0xbd,
702 0x52,0x2d,0xab,0x48,0x3d,0xf5,0xb6,0xd5,0x5d,0x5f,0x1b,0x02,0x9f,0xfa,0x2f,
703 0x6b,0x1e,0xa4,0xf7,0xa3,0x9a,0xa6,0x1a,0xc8,0x02,0xe1,0x7f,0x4c,0x52,0xe3,
704 0x0e,0x60,0xec,0x40,0x1c,0x7e,0xb9,0x0d,0xde,0x3f,0xc7,0xb4,0xdf,0x87,0xbd,
705 0x5f,0x7a,0x6a,0x31,0x2e,0x03,0x99,0x81,0x13,0xa8,0x47,0x20,0xce,0x31,0x73,
706 0x0d,0x57,0x2d,0xcd,0x78,0x34,0x33,0x95,0x12,0x99,0x12,0xb9,0xde,0x68,0x2f,
707 0xaa,0xe6,0xe3,0xc2,0x8a,0x8c,0x2a,0xc3,0x8b,0x21,0x87,0x66,0xbd,0x83,0x58,
708 0x57,0x6f,0x75,0xbf,0x3c,0xaa,0x26,0x87,0x5d,0xca,0x10,0x15,0x3c,0x9f,0x84,
709 0xea,0x54,0xc1,0x0a,0x6e,0xc4,0xfe,0xc5,0x4a,0xdd,0xb9,0x07,0x11,0x97,0x22,
710 0x7c,0xdb,0x3e,0x27,0xd1,0x1e,0x78,0xec,0x9f,0x31,0xc9,0xf1,0xe6,0x22,0x19,
711 0xdb,0xc4,0xb3,0x47,0x43,0x9a,0x1a,0x5f,0xa0,0x1e,0x90,0xe4,0x5e,0xf5,0xee,
712 0x7c,0xf1,0x7d,0xab,0x62,0x01,0x8f,0xf5,0x4d,0x0b,0xde,0xd0,0x22,0x56,0xa8,
713 0x95,0xcd,0xae,0x88,0x76,0xae,0xee,0xba,0x0d,0xf3,0xe4,0x4d,0xd9,0xa0,0xfb,
714 0x68,0xa0,0xae,0x14,0x3b,0xb3,0x87,0xc1,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,
715 0x81,0xdb,0x30,0x81,0xd8,0x30,0x34,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
716 0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
717 0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,
718 0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,
719 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
720 0xff,0x02,0x01,0x00,0x30,0x41,0x06,0x03,0x55,0x1d,0x1f,0x04,0x3a,0x30,0x38,
721 0x30,0x36,0xa0,0x34,0xa0,0x32,0x86,0x30,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
722 0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,
723 0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
724 0x6d,0x70,0x69,0x6e,0x67,0x43,0x41,0x2e,0x63,0x72,0x6c,0x30,0x13,0x06,0x03,
725 0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
726 0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,
727 0x02,0x01,0x06,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,0x04,0x1d,0x30,0x1b,0xa4,
728 0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0c,0x54,
729 0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,0x33,0x30,0x0d,0x06,0x09,
730 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,
731 0x4a,0x6b,0xf9,0xea,0x58,0xc2,0x44,0x1c,0x31,0x89,0x79,0x99,0x2b,0x96,0xbf,
732 0x82,0xac,0x01,0xd6,0x1c,0x4c,0xcd,0xb0,0x8a,0x58,0x6e,0xdf,0x08,0x29,0xa3,
733 0x5e,0xc8,0xca,0x93,0x13,0xe7,0x04,0x52,0x0d,0xef,0x47,0x27,0x2f,0x00,0x38,
734 0xb0,0xe4,0xc9,0x93,0x4e,0x9a,0xd4,0x22,0x62,0x15,0xf7,0x3f,0x37,0x21,0x4f,
735 0x70,0x31,0x80,0xf1,0x8b,0x38,0x87,0xb3,0xe8,0xe8,0x97,0x00,0xfe,0xcf,0x55,
736 0x96,0x4e,0x24,0xd2,0xa9,0x27,0x4e,0x7a,0xae,0xb7,0x61,0x41,0xf3,0x2a,0xce,
737 0xe7,0xc9,0xd9,0x5e,0xdd,0xbb,0x2b,0x85,0x3e,0xb5,0x9d,0xb5,0xd9,0xe1,0x57,
738 0xff,0xbe,0xb4,0xc5,0x7e,0xf5,0xcf,0x0c,0x9e,0xf0,0x97,0xfe,0x2b,0xd3,0x3b,
739 0x52,0x1b,0x1b,0x38,0x27,0xf7,0x3f,0x4a };
740 static const BYTE iTunesCert1[] = {
741 0x30,0x82,0x03,0xff,0x30,0x82,0x02,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
742 0x0d,0xe9,0x2b,0xf0,0xd4,0xd8,0x29,0x88,0x18,0x32,0x05,0x09,0x5e,0x9a,0x76,
743 0x88,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
744 0x00,0x30,0x53,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
745 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
746 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,
747 0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
748 0x20,0x54,0x69,0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,
749 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,
750 0x30,0x33,0x31,0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
751 0x30,0x38,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x57,
752 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,
753 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,
754 0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2f,0x30,0x2d,0x06,0x03,0x55,
755 0x04,0x03,0x13,0x26,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,
756 0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,
757 0x76,0x69,0x63,0x65,0x73,0x20,0x53,0x69,0x67,0x6e,0x65,0x72,0x30,0x82,0x01,
758 0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
759 0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,
760 0xb2,0x50,0x28,0x48,0xdd,0xd3,0x68,0x7a,0x84,0x18,0x44,0x66,0x75,0x5d,0x7e,
761 0xc4,0xb8,0x9f,0x63,0x26,0xff,0x3d,0x43,0x9c,0x7c,0x11,0x38,0x10,0x25,0x55,
762 0x73,0xd9,0x75,0x27,0x69,0xfd,0x4e,0xb9,0x20,0x5c,0xd3,0x0a,0xf9,0xa0,0x1b,
763 0x2a,0xed,0x55,0x56,0x21,0x61,0xd8,0x1e,0xdb,0xe4,0xbc,0x33,0x6b,0xc7,0xef,
764 0xdd,0xa3,0x37,0x65,0x8e,0x1b,0x93,0x0c,0xb6,0x53,0x1e,0x5c,0x7c,0x66,0x35,
765 0x5f,0x05,0x8a,0x45,0xfe,0x76,0x4e,0xdf,0x53,0x80,0xa2,0x81,0x20,0x9d,0xae,
766 0x88,0x5c,0xa2,0x08,0xf7,0xe5,0x30,0xf9,0xee,0x22,0x37,0x4c,0x42,0x0a,0xce,
767 0xdf,0xc6,0x1f,0xc4,0xd6,0x55,0xe9,0x81,0x3f,0xb5,0x52,0xa3,0x2c,0xaa,0x01,
768 0x7a,0xf2,0xa2,0xaa,0x8d,0x35,0xfe,0x9f,0xe6,0x5d,0x6a,0x05,0x9f,0x3d,0x6b,
769 0xe3,0xbf,0x96,0xc0,0xfe,0xcc,0x60,0xf9,0x40,0xe7,0x07,0xa0,0x44,0xeb,0x81,
770 0x51,0x6e,0xa5,0x2a,0xf2,0xb6,0x8a,0x10,0x28,0xed,0x8f,0xdc,0x06,0xa0,0x86,
771 0x50,0x9a,0x7b,0x4a,0x08,0x0d,0x30,0x1d,0xca,0x10,0x9e,0x6b,0xf7,0xe9,0x58,
772 0xae,0x04,0xa9,0x40,0x99,0xb2,0x28,0xe8,0x8f,0x16,0xac,0x3c,0xe3,0x53,0x6f,
773 0x4b,0xd3,0x35,0x9d,0xb5,0x6f,0x64,0x1d,0xb3,0x96,0x2c,0xbb,0x3d,0xe7,0x79,
774 0xeb,0x6d,0x7a,0xf9,0x16,0xe6,0x26,0xad,0xaf,0xef,0x99,0x53,0xb7,0x40,0x2c,
775 0x95,0xb8,0x79,0xaa,0xfe,0xd4,0x52,0xab,0x29,0x74,0x7e,0x42,0xec,0x39,0x1e,
776 0xa2,0x6a,0x16,0xe6,0x59,0xbb,0x24,0x68,0xd8,0x00,0x80,0x43,0x10,0x87,0x80,
777 0x6b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xca,0x30,0x81,0xc7,0x30,0x34,0x06,
778 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,
779 0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,
780 0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
781 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
782 0xff,0x04,0x02,0x30,0x00,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30,
783 0x2a,0x30,0x28,0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,
784 0x2f,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,
785 0x6f,0x6d,0x2f,0x74,0x73,0x73,0x2d,0x63,0x61,0x2e,0x63,0x72,0x6c,0x30,0x16,
786 0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,
787 0x06,0x01,0x05,0x05,0x07,0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
788 0x01,0xff,0x04,0x04,0x03,0x02,0x06,0xc0,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,
789 0x04,0x1d,0x30,0x1b,0xa4,0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,
790 0x04,0x03,0x13,0x0c,0x54,0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,
791 0x34,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
792 0x00,0x03,0x82,0x01,0x01,0x00,0x87,0x78,0x70,0xda,0x4e,0x52,0x01,0x20,0x5b,
793 0xe0,0x79,0xc9,0x82,0x30,0xc4,0xfd,0xb9,0x19,0x96,0xbd,0x91,0x00,0xc3,0xbd,
794 0xcd,0xcd,0xc6,0xf4,0x0e,0xd8,0xff,0xf9,0x4d,0xc0,0x33,0x62,0x30,0x11,0xc5,
795 0xf5,0x74,0x1b,0xd4,0x92,0xde,0x5f,0x9c,0x20,0x13,0xb1,0x7c,0x45,0xbe,0x50,
796 0xcd,0x83,0xe7,0x80,0x17,0x83,0xa7,0x27,0x93,0x67,0x13,0x46,0xfb,0xca,0xb8,
797 0x98,0x41,0x03,0xcc,0x9b,0x51,0x5b,0x05,0x8b,0x7f,0xa8,0x6f,0xf3,0x1b,0x50,
798 0x1b,0x24,0x2e,0xf2,0x69,0x8d,0x6c,0x22,0xf7,0xbb,0xca,0x16,0x95,0xed,0x0c,
799 0x74,0xc0,0x68,0x77,0xd9,0xeb,0x99,0x62,0x87,0xc1,0x73,0x90,0xf8,0x89,0x74,
800 0x7a,0x23,0xab,0xa3,0x98,0x7b,0x97,0xb1,0xf7,0x8f,0x29,0x71,0x4d,0x2e,0x75,
801 0x1b,0x48,0x41,0xda,0xf0,0xb5,0x0d,0x20,0x54,0xd6,0x77,0xa0,0x97,0x82,0x63,
802 0x69,0xfd,0x09,0xcf,0x8a,0xf0,0x75,0xbb,0x09,0x9b,0xd9,0xf9,0x11,0x55,0x26,
803 0x9a,0x61,0x32,0xbe,0x7a,0x02,0xb0,0x7b,0x86,0xbe,0xa2,0xc3,0x8b,0x22,0x2c,
804 0x78,0xd1,0x35,0x76,0xbc,0x92,0x73,0x5c,0xf9,0xb9,0xe6,0x4c,0x15,0x0a,0x23,
805 0xcc,0xe4,0xd2,0xd4,0x34,0x2e,0x49,0x40,0x15,0x3c,0x0f,0x60,0x7a,0x24,0xc6,
806 0xa5,0x66,0xef,0x96,0xcf,0x70,0xeb,0x3e,0xe7,0xf4,0x0d,0x7e,0xdc,0xd1,0x7c,
807 0xa3,0x76,0x71,0x69,0xc1,0x9c,0x4f,0x47,0x30,0x35,0x21,0xb1,0xa2,0xaf,0x1a,
808 0x62,0x3c,0x2b,0xd9,0x8e,0xaa,0x2a,0x07,0x7b,0xd8,0x18,0xb3,0x5c,0x7b,0xe2,
809 0x9d,0xa5,0x6f,0xfe,0x3c,0x89,0xad };
810 static const BYTE iTunesCert2[] = {
811 0x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
812 0x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75,
813 0xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
814 0x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
815 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
816 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,
817 0x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,
818 0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,
819 0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,
820 0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x34,0x30,
821 0x37,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30,
822 0x37,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,
823 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,
824 0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
825 0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b,
826 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,
827 0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,
828 0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,
829 0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,
830 0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,
831 0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,
832 0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,
833 0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,0x53,0x69,
834 0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,0x20,0x43,0x41,0x30,0x82,
835 0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,
836 0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,
837 0x00,0xbe,0xbc,0xee,0xbc,0x7e,0xef,0x83,0xeb,0xe0,0x37,0x4f,0xfb,0x03,0x10,
838 0x38,0xbe,0x08,0xd2,0x8c,0x7d,0x9d,0xfa,0x92,0x7f,0x19,0x0c,0xc2,0x6b,0xee,
839 0x42,0x52,0x8c,0xde,0xd3,0x1c,0x48,0x13,0x25,0xea,0xc1,0x63,0x7a,0xf9,0x51,
840 0x65,0xee,0xd3,0xaa,0x3b,0xf5,0xf0,0x94,0x9c,0x2b,0xfb,0xf2,0x66,0xd4,0x24,
841 0xda,0xf7,0xf5,0x9f,0x6e,0x19,0x39,0x36,0xbc,0xd0,0xa3,0x76,0x08,0x1e,0x22,
842 0x27,0x24,0x6c,0x38,0x91,0x27,0xe2,0x84,0x49,0xae,0x1b,0x8a,0xa1,0xfd,0x25,
843 0x82,0x2c,0x10,0x30,0xe8,0x71,0xab,0x28,0xe8,0x77,0x4a,0x51,0xf1,0xec,0xcd,
844 0xf8,0xf0,0x54,0xd4,0x6f,0xc0,0xe3,0x6d,0x0a,0x8f,0xd9,0xd8,0x64,0x8d,0x63,
845 0xb2,0x2d,0x4e,0x27,0xf6,0x85,0x0e,0xfe,0x6d,0xe3,0x29,0x99,0xe2,0x85,0x47,
846 0x7c,0x2d,0x86,0x7f,0xe8,0x57,0x8f,0xad,0x67,0xc2,0x33,0x32,0x91,0x13,0x20,
847 0xfc,0xa9,0x23,0x14,0x9a,0x6d,0xc2,0x84,0x4b,0x76,0x68,0x04,0xd5,0x71,0x2c,
848 0x5d,0x21,0xfa,0x88,0x0d,0x26,0xfd,0x1f,0x2d,0x91,0x2b,0xe7,0x01,0x55,0x4d,
849 0xf2,0x6d,0x35,0x28,0x82,0xdf,0xd9,0x6b,0x5c,0xb6,0xd6,0xd9,0xaa,0x81,0xfd,
850 0x5f,0xcd,0x83,0xba,0x63,0x9d,0xd0,0x22,0xfc,0xa9,0x3b,0x42,0x69,0xb2,0x8e,
851 0x3a,0xb5,0xbc,0xb4,0x9e,0x0f,0x5e,0xc4,0xea,0x2c,0x82,0x8b,0x28,0xfd,0x53,
852 0x08,0x96,0xdd,0xb5,0x01,0x20,0xd1,0xf9,0xa5,0x18,0xe7,0xc0,0xee,0x51,0x70,
853 0x37,0xe1,0xb6,0x05,0x48,0x52,0x48,0x6f,0x38,0xea,0xc3,0xe8,0x6c,0x7b,0x44,
854 0x84,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xa0,0x30,0x82,0x01,0x9c,
855 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
856 0x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,
857 0x3b,0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,
858 0x03,0x30,0x2a,0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
859 0x16,0x1c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,
860 0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,
861 0x30,0x31,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24,
862 0xa0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,
863 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63,
864 0x61,0x33,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16,
865 0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2b,
866 0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
867 0x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48,
868 0x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x01,0x30,0x29,0x06,
869 0x03,0x55,0x1d,0x11,0x04,0x22,0x30,0x20,0xa4,0x1e,0x30,0x1c,0x31,0x1a,0x30,
870 0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6c,0x61,0x73,0x73,0x33,0x43,
871 0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x34,0x33,0x30,0x1d,0x06,0x03,0x55,
872 0x1d,0x0e,0x04,0x16,0x04,0x14,0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,
873 0x36,0x7c,0x68,0xcf,0x5b,0x78,0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x81,0x80,0x06,
874 0x03,0x55,0x1d,0x23,0x04,0x79,0x30,0x77,0xa1,0x63,0xa4,0x61,0x30,0x5f,0x31,
875 0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,
876 0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
877 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,
878 0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6c,
879 0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,
880 0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,
881 0x72,0x69,0x74,0x79,0x82,0x10,0x70,0xba,0xe4,0x1d,0x10,0xd9,0x29,0x34,0xb6,
882 0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
883 0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xae,0x3a,0x17,0xb8,
884 0x4a,0x7b,0x55,0xfa,0x64,0x55,0xec,0x40,0xa4,0xed,0x49,0x41,0x90,0x99,0x9c,
885 0x89,0xbc,0xaf,0x2e,0x1d,0xca,0x78,0x23,0xf9,0x1c,0x19,0x0f,0x7f,0xeb,0x68,
886 0xbc,0x32,0xd9,0x88,0x38,0xde,0xdc,0x3f,0xd3,0x89,0xb4,0x3f,0xb1,0x82,0x96,
887 0xf1,0xa4,0x5a,0xba,0xed,0x2e,0x26,0xd3,0xde,0x7c,0x01,0x6e,0x00,0x0a,0x00,
888 0xa4,0x06,0x92,0x11,0x48,0x09,0x40,0xf9,0x1c,0x18,0x79,0x67,0x23,0x24,0xe0,
889 0xbb,0xd5,0xe1,0x50,0xae,0x1b,0xf5,0x0e,0xdd,0xe0,0x2e,0x81,0xcd,0x80,0xa3,
890 0x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88,
891 0x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f,
892 0x5e,0xf6,0x7a,0xb5 };
893 static const BYTE iTunesCert3[] = {
894 0x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
895 0x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6,
896 0x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
897 0x00,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
898 0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,
899 0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,
900 0x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
901 0x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,
902 0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,
903 0x73,0x20,0x6f,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,
904 0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
905 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,
906 0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,
907 0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,
908 0x6f,0x64,0x65,0x20,0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,
909 0x34,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x31,0x37,0x30,
910 0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x38,0x30,0x31,0x32,0x32,0x32,
911 0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,
912 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
913 0x08,0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x12,
914 0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,
915 0x69,0x6e,0x6f,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0a,0x14,0x14,0x41,
916 0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x2c,0x20,
917 0x49,0x6e,0x63,0x2e,0x31,0x3e,0x30,0x3c,0x06,0x03,0x55,0x04,0x0b,0x13,0x35,
918 0x44,0x69,0x67,0x69,0x74,0x61,0x6c,0x20,0x49,0x44,0x20,0x43,0x6c,0x61,0x73,
919 0x73,0x20,0x33,0x20,0x2d,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
920 0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x56,0x61,0x6c,0x69,0x64,
921 0x61,0x74,0x69,0x6f,0x6e,0x20,0x76,0x32,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,
922 0x04,0x03,0x14,0x14,0x41,0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,
923 0x74,0x65,0x72,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x30,0x81,0x9f,0x30,0x0d,0x06,
924 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,
925 0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xd3,0xab,0x3b,0x7f,0xec,0x48,0x84,
926 0xce,0xa8,0x1a,0x12,0xf3,0x3c,0x87,0xcb,0x24,0x58,0x96,0x02,0x87,0x66,0x49,
927 0xeb,0x89,0xee,0x79,0x44,0x70,0x8d,0xe7,0xd4,0x1f,0x30,0x92,0xc0,0x9c,0x35,
928 0x78,0xc0,0xaf,0x1c,0xb6,0x28,0xd3,0xe0,0xe0,0x9d,0xd3,0x49,0x76,0x73,0x57,
929 0x19,0x4d,0x8d,0x70,0x85,0x64,0x4d,0x1d,0xc6,0x02,0x3e,0xe5,0x2c,0x66,0x07,
930 0xd2,0x27,0x4b,0xd6,0xc8,0x3c,0x93,0xb6,0x15,0x0c,0xde,0x5b,0xd7,0x93,0xdd,
931 0xbe,0x85,0x62,0x34,0x17,0x8a,0x05,0x60,0xf0,0x8a,0x1c,0x5a,0x40,0x21,0x8d,
932 0x51,0x6c,0xb0,0x62,0xd8,0xb5,0xd4,0xf9,0xb1,0xd0,0x58,0x7a,0x7a,0x82,0x55,
933 0xb3,0xf9,0x53,0x71,0xde,0xd2,0xc9,0x37,0x8c,0xf6,0x5a,0x1f,0x2d,0xcd,0x7c,
934 0x67,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30,
935 0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06,0x03,0x55,
936 0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x40,0x06,0x03,
937 0x55,0x1d,0x1f,0x04,0x39,0x30,0x37,0x30,0x35,0xa0,0x33,0xa0,0x31,0x86,0x2f,
938 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,
939 0x34,0x2d,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,
940 0x63,0x6f,0x6d,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2e,0x63,
941 0x72,0x6c,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b,0x30,0x39,
942 0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,0x03,0x30,0x2a,
943 0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1c,0x68,
944 0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,
945 0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x30,0x13,0x06,
946 0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
947 0x07,0x03,0x03,0x30,0x75,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
948 0x04,0x69,0x30,0x67,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,
949 0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,
950 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x3f,0x06,
951 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x33,0x68,0x74,0x74,0x70,
952 0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,
953 0x61,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,
954 0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,0x61,0x2e,0x63,
955 0x65,0x72,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
956 0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,0x36,0x7c,0x68,0xcf,0x5b,0x78,
957 0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,
958 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x04,0x10,0x30,0x16,0x06,0x0a,0x2b,0x06,
959 0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x1b,0x04,0x08,0x30,0x06,0x01,0x01,0x00,
960 0x01,0x01,0xff,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
961 0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6a,0xa6,0x06,0xd0,0x33,0x18,0x64,
962 0xe2,0x69,0x82,0xee,0x6e,0x36,0x9e,0x9d,0x9a,0x0e,0x18,0xa8,0xac,0x9d,0x10,
963 0xed,0x01,0x3c,0xb9,0x61,0x04,0x62,0xf3,0x85,0x8f,0xcc,0x4f,0x2c,0x66,0x35,
964 0x54,0x25,0x45,0x8d,0x95,0x1c,0xd2,0x33,0xbe,0x2e,0xdd,0x7f,0x74,0xaf,0x03,
965 0x7b,0x86,0x63,0xb0,0xc9,0xe6,0xbd,0xc7,0x8e,0xde,0x03,0x18,0x98,0x82,0xc3,
966 0xbb,0xf8,0x15,0x99,0x1a,0xa9,0xdd,0xb9,0x5d,0xb9,0xbd,0x53,0x95,0x25,0x76,
967 0xfb,0x5c,0x53,0x90,0xea,0x01,0x0a,0xa0,0xb1,0xbf,0x09,0x1b,0x97,0x8f,0x40,
968 0xfa,0x85,0x12,0x74,0x01,0xdb,0xf6,0xdb,0x09,0xd6,0x5f,0x4f,0xd7,0x17,0xb4,
969 0xbf,0x9e,0x2f,0x86,0x52,0x5d,0x70,0x24,0x52,0x32,0x1e,0xa5,0x1d,0x39,0x8b,
970 0x66,0xf6,0xba,0x9b,0x69,0x8e,0x12,0x60,0xdb,0xb6,0xcf,0xe6,0x0d,0xd6,0x1c,
971 0x8f,0xd4,0x5b,0x4b,0x00,0xde,0x21,0x93,0xfb,0x6e,0xc7,0x3d,0xb4,0x66,0x0d,
972 0x29,0x0c,0x4e,0xe9,0x3f,0x94,0xd6,0xd6,0xdc,0xec,0xf8,0x53,0x3b,0x62,0xd5,
973 0x97,0x50,0x53,0x84,0x17,0xfe,0xe2,0xed,0x4c,0x23,0x0a,0x49,0xce,0x5b,0xe9,
974 0x70,0x31,0xc1,0x04,0x02,0x02,0x6c,0xb8,0x52,0xcd,0xc7,0x4e,0x70,0xb4,0x13,
975 0xd7,0xe0,0x92,0xba,0x44,0x1a,0x10,0x4c,0x6e,0x45,0xc6,0x86,0x04,0xc6,0x64,
976 0xd3,0x9c,0x6e,0xc1,0x9c,0xac,0x74,0x3d,0x77,0x06,0x5e,0x28,0x28,0x5c,0xf5,
977 0xe0,0x9c,0x19,0xd8,0xba,0x74,0x81,0x2d,0x67,0x77,0x93,0x8d,0xbf,0xd2,0x52,
978 0x00,0xe6,0xa5,0x38,0x4e,0x2e,0x73,0x66,0x7a };
979 static BYTE iTunesIssuer[] = {
980 0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
981 0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,
982 0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
983 0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,
984 0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
985 0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,
986 0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,
987 0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,0x73,
988 0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,
989 0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,
990 0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,
991 0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,
992 0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
993 0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,
994 0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,
996 static BYTE iTunesSerialNum[] = {
997 0x8d,0xf6,0x6a,0xdf,0xd2,0x40,0xfe,0xb6,0xa6,0x61,0x9b,0x9b,
998 0xe0,0xa0,0x1a,0x0f };
1000 static void testFindCert(void)
1003 PCCERT_CONTEXT context = NULL, subject;
1005 CERT_INFO certInfo = { 0 };
1006 CRYPT_HASH_BLOB blob;
1007 BYTE otherSerialNumber[] = { 2 };
1009 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1010 CERT_STORE_CREATE_NEW_FLAG, NULL);
1011 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1015 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1016 bigCert, sizeof(bigCert), CERT_STORE_ADD_NEW, NULL);
1017 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1019 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1020 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
1021 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1023 /* This has the same name as bigCert */
1024 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1025 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1026 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1030 context = CertFindCertificateInStore(NULL, 0, 0, 0, NULL, NULL);
1033 /* Check first cert's there, by issuer */
1034 certInfo.Subject.pbData = subjectName;
1035 certInfo.Subject.cbData = sizeof(subjectName);
1036 certInfo.SerialNumber.pbData = serialNum;
1037 certInfo.SerialNumber.cbData = sizeof(serialNum);
1038 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1039 CERT_FIND_ISSUER_NAME, &certInfo.Subject, NULL);
1040 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1044 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1045 CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
1046 ok(context != NULL, "Expected more than one cert\n");
1049 context = CertFindCertificateInStore(store, X509_ASN_ENCODING,
1050 0, CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
1051 ok(context == NULL, "Expected precisely two certs\n");
1055 /* Check second cert's there as well, by subject name */
1056 certInfo.Subject.pbData = subjectName2;
1057 certInfo.Subject.cbData = sizeof(subjectName2);
1058 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1059 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, NULL);
1060 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1064 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1065 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, context);
1066 ok(context == NULL, "Expected one cert only\n");
1069 /* Strange but true: searching for the subject cert requires you to set
1070 * the issuer, not the subject
1072 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1073 CERT_FIND_SUBJECT_CERT, &certInfo.Subject, NULL);
1074 ok(context == NULL, "Expected no certificate\n");
1075 certInfo.Subject.pbData = NULL;
1076 certInfo.Subject.cbData = 0;
1077 certInfo.Issuer.pbData = subjectName2;
1078 certInfo.Issuer.cbData = sizeof(subjectName2);
1079 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1080 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1081 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1085 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1086 CERT_FIND_SUBJECT_CERT, &certInfo.Subject, context);
1087 ok(context == NULL, "Expected one cert only\n");
1089 /* A non-matching serial number will not match. */
1090 certInfo.SerialNumber.pbData = otherSerialNumber;
1091 certInfo.SerialNumber.cbData = sizeof(otherSerialNumber);
1092 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1093 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1094 ok(context == NULL, "Expected no match\n");
1095 /* No serial number will not match */
1096 certInfo.SerialNumber.cbData = 0;
1097 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1098 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1099 ok(context == NULL, "Expected no match\n");
1100 /* A serial number still won't match if the name doesn't */
1101 certInfo.SerialNumber.pbData = serialNum;
1102 certInfo.SerialNumber.cbData = sizeof(serialNum);
1103 certInfo.Issuer.pbData = subjectName3;
1104 certInfo.Issuer.cbData = sizeof(subjectName3);
1105 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1106 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1107 ok(context == NULL, "Expected no match\n");
1109 /* The nice thing about hashes, they're unique */
1110 blob.pbData = bigCertHash;
1111 blob.cbData = sizeof(bigCertHash);
1112 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1113 CERT_FIND_SHA1_HASH, &blob, NULL);
1114 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1118 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1119 CERT_FIND_SHA1_HASH, &certInfo.Subject, context);
1120 ok(context == NULL, "Expected one cert only\n");
1123 CertCloseStore(store, 0);
1125 /* Another subject cert search, using iTunes's certs */
1126 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1127 CERT_STORE_CREATE_NEW_FLAG, NULL);
1128 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1129 iTunesCert0, sizeof(iTunesCert0), CERT_STORE_ADD_NEW, NULL);
1130 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1132 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1133 iTunesCert1, sizeof(iTunesCert1), CERT_STORE_ADD_NEW, NULL);
1134 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1136 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1137 iTunesCert2, sizeof(iTunesCert2), CERT_STORE_ADD_NEW, NULL);
1138 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1140 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1141 iTunesCert3, sizeof(iTunesCert3), CERT_STORE_ADD_NEW, &subject);
1142 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1145 /* The certInfo's issuer does not match any subject, but the serial
1146 * number does match a cert whose issuer matches certInfo's issuer.
1147 * This yields a match.
1149 certInfo.SerialNumber.cbData = sizeof(iTunesSerialNum);
1150 certInfo.SerialNumber.pbData = iTunesSerialNum;
1151 certInfo.Issuer.cbData = sizeof(iTunesIssuer);
1152 certInfo.Issuer.pbData = iTunesIssuer;
1153 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1154 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1155 ok(context != NULL, "Expected a match\n");
1158 ret = CertCompareCertificateName(context->dwCertEncodingType,
1159 &certInfo.Issuer, &context->pCertInfo->Subject);
1160 ok(!ret, "Expected subject name not to match\n");
1161 ret = CertCompareCertificateName(context->dwCertEncodingType,
1162 &certInfo.Issuer, &context->pCertInfo->Issuer);
1163 ok(ret, "Expected issuer name to match\n");
1164 ret = CertCompareIntegerBlob(&certInfo.SerialNumber,
1165 &context->pCertInfo->SerialNumber);
1166 ok(ret, "Expected serial number to match\n");
1167 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1168 CERT_FIND_SUBJECT_CERT, &certInfo, context);
1169 ok(context == NULL, "Expected one cert only\n");
1172 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1173 CERT_FIND_ISSUER_OF, subject, NULL);
1174 ok(context != NULL, "Expected an issuer\n");
1177 PCCERT_CONTEXT none = CertFindCertificateInStore(store,
1178 X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_OF, context, NULL);
1180 ok(!none, "Expected no parent of issuer\n");
1181 CertFreeCertificateContext(context);
1183 CertFreeCertificateContext(subject);
1184 CertCloseStore(store, 0);
1187 static void testGetSubjectCert(void)
1190 PCCERT_CONTEXT context1, context2;
1191 CERT_INFO info = { 0 };
1194 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1195 CERT_STORE_CREATE_NEW_FLAG, NULL);
1196 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1200 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1201 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1202 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1204 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1205 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, &context1);
1206 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1208 ok(context1 != NULL, "Expected a context\n");
1209 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1210 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1211 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1214 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1216 ok(!context2 && GetLastError() == E_INVALIDARG,
1217 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1218 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1220 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1221 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1222 info.SerialNumber.cbData = sizeof(serialNum);
1223 info.SerialNumber.pbData = serialNum;
1224 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1226 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1227 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1228 info.Issuer.cbData = sizeof(subjectName2);
1229 info.Issuer.pbData = subjectName2;
1230 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1232 ok(context2 != NULL,
1233 "CertGetSubjectCertificateFromStore failed: %08x\n", GetLastError());
1234 /* Not only should this find a context, but it should be the same
1235 * (same address) as context1.
1237 ok(context1 == context2, "Expected identical context addresses\n");
1238 CertFreeCertificateContext(context2);
1240 CertFreeCertificateContext(context1);
1241 CertCloseStore(store, 0);
1244 /* This expires in 1970 or so */
1245 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
1246 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
1247 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
1248 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1249 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1250 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1251 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
1252 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
1253 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1254 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1255 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1256 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
1257 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
1258 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
1259 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
1260 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
1261 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
1262 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
1263 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
1264 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
1265 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
1266 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
1267 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
1268 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
1269 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
1271 /* This expires in 2036 or so */
1272 static const BYTE childOfExpired[] = { 0x30, 0x81, 0xcc, 0x30, 0x78, 0xa0,
1273 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
1274 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d,
1275 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63,
1276 0x40, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e,
1277 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x35, 0x30, 0x35,
1278 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x35,
1279 0x30, 0x35, 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x30, 0x15, 0x31, 0x13,
1280 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e,
1281 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03,
1282 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
1283 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x20, 0x3b, 0xdb, 0x4d, 0x67, 0x50,
1284 0xec, 0x73, 0x9d, 0xf9, 0x85, 0x5d, 0x18, 0xe9, 0xb4, 0x98, 0xe3, 0x31, 0xb7,
1285 0x03, 0x0b, 0xc0, 0x39, 0x93, 0x56, 0x81, 0x0a, 0xfc, 0x78, 0xa8, 0x29, 0x42,
1286 0x5f, 0x69, 0xfb, 0xbc, 0x5b, 0xf2, 0xa6, 0x2a, 0xbe, 0x91, 0x2c, 0xfc, 0x89,
1287 0x69, 0x15, 0x18, 0x58, 0xe5, 0x02, 0x75, 0xf7, 0x2a, 0xb6, 0xa9, 0xfb, 0x47,
1288 0x6a, 0x6e, 0x0a, 0x9b, 0xe9, 0xdc };
1292 * A chain with two issuers, only one of whose dates is valid.
1294 static const BYTE chain10_0[] = {
1295 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1296 0x4a,0x30,0x3a,0x42,0xa2,0x5a,0xb3,0x93,0x4d,0x94,0x06,0xad,0x6d,0x1c,0x34,
1297 0xe6,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1298 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1299 0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1300 0x30,0x5a,0x17,0x0d,0x30,0x36,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1301 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1302 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1303 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1304 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1305 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1306 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1307 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1308 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1309 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1310 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1311 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1312 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1313 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1314 0x81,0x00,0x85,0x6e,0x35,0x2f,0x2c,0x51,0x4f,0xd6,0x2a,0xe4,0x9e,0xd0,0x4b,
1315 0xe6,0x90,0xfd,0xf7,0x20,0xad,0x76,0x3f,0x93,0xea,0x7f,0x0d,0x1f,0xb3,0x8e,
1316 0xfd,0xe0,0xe1,0xd6,0xd7,0x9c,0x7d,0x46,0x6b,0x15,0x5c,0xe6,0xc9,0x62,0x3b,
1317 0x70,0x4a,0x4b,0xb2,0x82,0xe3,0x55,0x0c,0xc4,0x90,0x44,0x06,0x6c,0x86,0x1c,
1318 0x6d,0x47,0x12,0xda,0x33,0x95,0x5d,0x98,0x43,0xcb,0x7c,0xfa,0x2b,0xee,0xc4,
1319 0x2d,0xc8,0x95,0x33,0x89,0x08,0x3f,0x9f,0x87,0xea,0x20,0x04,0xaf,0x58,0x4b,
1320 0x9d,0xc0,0x7c,0x0a,0x1b,0x05,0x31,0x3b,0xbb,0x13,0x58,0x2e,0x3f,0x61,0x6b,
1321 0x10,0xb4,0xeb,0xb9,0x1a,0x30,0xfd,0xea,0xca,0x29,0x99,0x5f,0x42,0x2b,0x00,
1322 0xb0,0x08,0xc3,0xf0,0xb6,0xd6,0x6b,0xf9,0x35,0x95 };
1323 static const BYTE chain10_1[] = {
1324 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1325 0xbf,0x99,0x4f,0x14,0x03,0x77,0x44,0xb8,0x49,0x02,0x70,0xa1,0xb8,0x9c,0xa7,
1326 0x24,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1327 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1328 0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1329 0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1330 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1331 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1332 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1333 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1334 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1335 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1336 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1337 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1338 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1339 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1340 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1341 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1342 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1343 0x81,0x00,0xa8,0xec,0x8c,0x34,0xe7,0x2c,0xdf,0x75,0x87,0xc4,0xf7,0xda,0x71,
1344 0x72,0x29,0xb2,0x48,0xa8,0x2a,0xec,0x7b,0x7d,0x19,0xb9,0x5f,0x1d,0xd9,0x91,
1345 0x2b,0xc4,0x28,0x7e,0xd6,0xb5,0x91,0x69,0xa5,0x8a,0x1a,0x1f,0x97,0x98,0x46,
1346 0x9d,0xdf,0x12,0xf6,0x45,0x62,0xad,0x60,0xb6,0xba,0xb0,0xfd,0xf5,0x9f,0xc6,
1347 0x98,0x05,0x4f,0x4d,0x48,0xdc,0xee,0x69,0xbe,0xb8,0xc4,0xc4,0xd7,0x1b,0xb1,
1348 0x1f,0x64,0xd6,0x45,0xa7,0xdb,0xb3,0x87,0x63,0x0f,0x54,0xe1,0x3a,0x6b,0x57,
1349 0x36,0xd7,0x68,0x65,0xcf,0xda,0x57,0x8d,0xcd,0x84,0x75,0x47,0x26,0x2c,0xef,
1350 0x1e,0x8f,0xc7,0x3b,0xee,0x5d,0x03,0xa6,0xdf,0x3a,0x20,0xb2,0xcc,0xc9,0x09,
1351 0x2c,0xfe,0x2b,0x79,0xb0,0xca,0x2c,0x9a,0x81,0x6b };
1352 static const BYTE chain7_1[] = {
1353 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
1354 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,
1355 0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,
1356 0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,
1357 0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,
1358 0x35,0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,
1359 0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,
1360 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,
1361 0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,
1362 0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,
1363 0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,
1364 0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,
1365 0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,
1366 0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,
1367 0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,
1368 0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,
1369 0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,
1370 0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1371 0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9f,0x69,0xfd,0x26,0xd5,0x4b,
1372 0xe0,0xab,0x12,0x21,0xb9,0xfc,0xf7,0xe0,0x0c,0x09,0x94,0xad,0x27,0xd7,0x9d,
1373 0xa3,0xcc,0x46,0x2a,0x25,0x9a,0x24,0xa7,0x31,0x58,0x78,0xf5,0xfc,0x30,0xe1,
1374 0x6d,0xfd,0x59,0xab,0xbe,0x69,0xa0,0xea,0xe3,0x7d,0x7a,0x7b,0xe5,0x85,0xeb,
1375 0x86,0x6a,0x84,0x3c,0x96,0x01,0x1a,0x70,0xa7,0xb8,0xcb,0xf2,0x11,0xe7,0x52,
1376 0x9c,0x58,0x2d,0xac,0x63,0xce,0x72,0x4b,0xad,0x62,0xa8,0x1d,0x75,0x96,0xe2,
1377 0x27,0xf5,0x6f,0xba,0x91,0xf8,0xf1,0xb0,0xbf,0x90,0x24,0x6d,0xba,0x5d,0xd7,
1378 0x39,0x63,0x3b,0x7c,0x04,0x5d,0x89,0x9d,0x1c,0xf2,0xf7,0xcc,0xdf,0x6e,0x8a,
1379 0x43,0xa9,0xdd,0x86,0x05,0xa2,0xf3,0x22,0x2d,0x1e,0x70,0xa1,0x59,0xd7,0xa5,
1382 static void testGetIssuerCert(void)
1385 PCCERT_CONTEXT parent, child, cert1, cert2;
1386 DWORD flags = 0xffffffff;
1387 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1388 CERT_STORE_CREATE_NEW_FLAG, NULL);
1390 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1392 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1393 expiredCert, sizeof(expiredCert), CERT_STORE_ADD_ALWAYS, NULL);
1394 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1397 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1398 childOfExpired, sizeof(childOfExpired), CERT_STORE_ADD_ALWAYS, &child);
1399 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1403 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, NULL);
1404 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, NULL);
1406 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, &flags);
1407 ok(!parent && GetLastError() == E_INVALIDARG,
1408 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1409 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, &flags);
1410 ok(!parent && GetLastError() == E_INVALIDARG,
1411 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1412 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1413 ok(!parent && GetLastError() == E_INVALIDARG,
1414 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1415 /* Confusing: the caller cannot set either of the
1416 * CERT_STORE_NO_*_FLAGs, as these are not checks,
1419 flags = CERT_STORE_NO_CRL_FLAG | CERT_STORE_NO_ISSUER_FLAG;
1420 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1421 ok(!parent && GetLastError() == E_INVALIDARG,
1422 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1423 /* Perform no checks */
1425 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1426 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1429 CertFreeCertificateContext(parent);
1430 /* Check revocation and signature only */
1431 flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG;
1432 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1433 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1435 /* Confusing: CERT_STORE_REVOCATION_FLAG succeeds when there is no CRL by
1436 * setting CERT_STORE_NO_CRL_FLAG.
1438 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
1439 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
1442 CertFreeCertificateContext(parent);
1443 /* Checking time validity is not productive, because while most Windows
1444 * versions return 0 (time valid) because the child is not expired,
1445 * Windows 2003 SP1 returns that it is expired. Thus the range of
1446 * possibilities is covered, and a test verifies nothing.
1449 CertFreeCertificateContext(child);
1450 CertCloseStore(store, 0);
1453 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1454 CERT_STORE_CREATE_NEW_FLAG, NULL);
1455 /* With only the child certificate, no issuer will be found */
1456 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1457 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1458 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1459 ok(parent == NULL, "Expected no issuer\n");
1460 /* Adding an issuer allows one (and only one) issuer to be found */
1461 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1462 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert1);
1463 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1464 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1465 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1466 ok(parent == NULL, "Expected only one issuer\n");
1467 /* Adding a second issuer allows two issuers to be found - and the second
1468 * issuer is found before the first, implying certs are added to the head
1471 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1472 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert2);
1473 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1474 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1475 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1476 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1477 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1478 ok(parent == NULL, "Expected no more than two issuers\n");
1479 CertFreeCertificateContext(child);
1480 CertFreeCertificateContext(cert1);
1481 CertFreeCertificateContext(cert2);
1482 CertCloseStore(store, 0);
1484 /* Repeat the test, reversing the order in which issuers are added,
1485 * to show it's order-dependent.
1487 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1488 CERT_STORE_CREATE_NEW_FLAG, NULL);
1489 /* With only the child certificate, no issuer will be found */
1490 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1491 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1492 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1493 ok(parent == NULL, "Expected no issuer\n");
1494 /* Adding an issuer allows one (and only one) issuer to be found */
1495 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1496 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert1);
1497 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1498 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1499 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1500 ok(parent == NULL, "Expected only one issuer\n");
1501 /* Adding a second issuer allows two issuers to be found - and the second
1502 * issuer is found before the first, implying certs are added to the head
1505 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1506 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert2);
1507 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1508 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1509 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1510 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1511 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1512 ok(parent == NULL, "Expected no more than two issuers\n");
1513 CertFreeCertificateContext(child);
1514 CertFreeCertificateContext(cert1);
1515 CertFreeCertificateContext(cert2);
1516 CertCloseStore(store, 0);
1519 static void testCryptHashCert(void)
1521 static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b,
1522 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07,
1524 static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee,
1525 0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8,
1527 static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:";
1530 DWORD hashLen = sizeof(hash);
1532 /* NULL buffer and nonzero length crashes
1533 ret = CryptHashCertificate(0, 0, 0, NULL, size, hash, &hashLen);
1534 empty hash length also crashes
1535 ret = CryptHashCertificate(0, 0, 0, buf, size, hash, NULL);
1537 /* Test empty hash */
1538 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), NULL,
1540 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1541 ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen);
1542 /* Test with empty buffer */
1543 ret = CryptHashCertificate(0, 0, 0, NULL, 0, hash, &hashLen);
1544 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1545 ok(!memcmp(hash, emptyHash, sizeof(emptyHash)),
1546 "Unexpected hash of nothing\n");
1547 /* Test a known value */
1548 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), hash,
1550 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1551 ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
1554 static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen,
1555 const BYTE *sig, unsigned int sigLen)
1558 BOOL ret = CryptCreateHash(csp, CALG_SHA1, 0, 0, &hash);
1560 ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
1564 DWORD mySigSize = sizeof(mySig);
1566 ret = CryptHashData(hash, toSign, toSignLen, 0);
1567 ok(ret, "CryptHashData failed: %08x\n", GetLastError());
1568 /* use the A variant so the test can run on Win9x */
1569 ret = CryptSignHashA(hash, AT_SIGNATURE, NULL, 0, mySig, &mySigSize);
1570 ok(ret, "CryptSignHash failed: %08x\n", GetLastError());
1573 ok(mySigSize == sigLen, "Expected sig length %d, got %d\n",
1575 ok(!memcmp(mySig, sig, sigLen), "Unexpected signature\n");
1577 CryptDestroyHash(hash);
1581 /* Tests signing the certificate described by toBeSigned with the CSP passed in,
1582 * using the algorithm with OID sigOID. The CSP is assumed to be empty, and a
1583 * keyset named AT_SIGNATURE will be added to it. The signing key will be
1584 * stored in *key, and the signature will be stored in sig. sigLen should be
1585 * at least 64 bytes.
1587 static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1588 LPCSTR sigOID, HCRYPTKEY *key, BYTE *sig, DWORD *sigLen)
1592 CRYPT_ALGORITHM_IDENTIFIER algoID = { NULL, { 0, NULL } };
1595 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1596 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, &size);
1597 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1598 NULL, NULL, NULL, &size);
1600 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1601 &algoID, NULL, NULL, &size);
1602 ok(!ret && GetLastError() == NTE_BAD_ALGID,
1603 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1604 algoID.pszObjId = (LPSTR)sigOID;
1605 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1606 &algoID, NULL, NULL, &size);
1607 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1608 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1610 ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData,
1611 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1612 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1613 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1616 /* No keys exist in the new CSP yet.. */
1617 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1618 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1619 ok(!ret && (GetLastError() == NTE_BAD_KEYSET || GetLastError() ==
1620 NTE_NO_KEY), "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %08x\n",
1622 ret = CryptGenKey(csp, AT_SIGNATURE, 0, key);
1623 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1626 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1627 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1628 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1629 ok(size <= *sigLen, "Expected size <= %d, got %d\n", *sigLen, size);
1632 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1633 toBeSigned->cbData, &algoID, NULL, sig, &size);
1634 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1638 verifySig(csp, toBeSigned->pbData, toBeSigned->cbData, sig,
1645 static void testVerifyCertSig(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1646 LPCSTR sigOID, const BYTE *sig, DWORD sigLen)
1648 CERT_SIGNED_CONTENT_INFO info;
1653 if (!pCryptVerifyCertificateSignatureEx)
1655 skip("no CryptVerifyCertificateSignatureEx support\n");
1658 if (!pCryptEncodeObjectEx)
1660 skip("no CryptEncodeObjectEx support\n");
1663 ret = pCryptVerifyCertificateSignatureEx(0, 0, 0, NULL, 0, NULL, 0, NULL);
1664 ok(!ret && GetLastError() == E_INVALIDARG,
1665 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1666 ret = pCryptVerifyCertificateSignatureEx(csp, 0, 0, NULL, 0, NULL, 0, NULL);
1667 ok(!ret && GetLastError() == E_INVALIDARG,
1668 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1669 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 0, NULL, 0,
1671 ok(!ret && GetLastError() == E_INVALIDARG,
1672 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1674 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1675 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, NULL, 0, NULL, 0, NULL);
1677 info.ToBeSigned.cbData = toBeSigned->cbData;
1678 info.ToBeSigned.pbData = toBeSigned->pbData;
1679 info.SignatureAlgorithm.pszObjId = (LPSTR)sigOID;
1680 info.SignatureAlgorithm.Parameters.cbData = 0;
1681 info.Signature.cbData = sigLen;
1682 info.Signature.pbData = (BYTE *)sig;
1683 info.Signature.cUnusedBits = 0;
1684 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT, &info,
1685 CRYPT_ENCODE_ALLOC_FLAG, NULL, &cert, &size);
1686 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1689 CRYPT_DATA_BLOB certBlob = { 0, NULL };
1690 PCERT_PUBLIC_KEY_INFO pubKeyInfo = NULL;
1692 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1693 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1694 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
1695 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
1696 certBlob.cbData = 1;
1697 certBlob.pbData = (void *)0xdeadbeef;
1698 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1699 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1700 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
1701 GetLastError() == CRYPT_E_ASN1_EOD /* Win9x */ ||
1702 GetLastError() == CRYPT_E_ASN1_BADTAG /* Win98 */),
1703 "Expected STATUS_ACCESS_VIOLATION, CRYPT_E_ASN1_EOD, OR CRYPT_E_ASN1_BADTAG, got %08x\n",
1706 certBlob.cbData = size;
1707 certBlob.pbData = cert;
1708 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1709 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1710 ok(!ret && GetLastError() == E_INVALIDARG,
1711 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1712 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1713 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1714 CRYPT_VERIFY_CERT_SIGN_ISSUER_NULL, NULL, 0, NULL);
1715 ok(!ret && GetLastError() == E_INVALIDARG,
1716 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1718 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1719 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1720 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, NULL, 0, NULL);
1722 CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
1723 (LPSTR)sigOID, 0, NULL, NULL, &size);
1724 pubKeyInfo = HeapAlloc(GetProcessHeap(), 0, size);
1727 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
1728 X509_ASN_ENCODING, (LPSTR)sigOID, 0, NULL, pubKeyInfo, &size);
1729 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
1732 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1733 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1734 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pubKeyInfo, 0, NULL);
1735 ok(ret, "CryptVerifyCertificateSignatureEx failed: %08x\n",
1738 HeapFree(GetProcessHeap(), 0, pubKeyInfo);
1744 static BYTE emptyCert[] = { 0x30, 0x00 };
1746 static void testCertSigs(void)
1749 CRYPT_DATA_BLOB toBeSigned = { sizeof(emptyCert), emptyCert };
1753 DWORD sigSize = sizeof(sig);
1755 /* Just in case a previous run failed, delete this thing */
1756 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1757 CRYPT_DELETEKEYSET);
1758 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1760 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1762 testSignCert(csp, &toBeSigned, szOID_RSA_SHA1RSA, &key, sig, &sigSize);
1763 testVerifyCertSig(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize);
1765 CryptDestroyKey(key);
1766 CryptReleaseContext(csp, 0);
1767 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1768 CRYPT_DELETEKEYSET);
1771 static const BYTE md5SignedEmptyCert[] = {
1772 0x30,0x56,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1773 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
1774 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
1775 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1776 0x0d,0x02,0x05,0x05,0x00,0x03,0x11,0x00,0xfb,0x0f,0x66,0x82,0x66,0xd9,0xe5,0xf8,
1777 0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
1778 static const BYTE md5SignedEmptyCertNoNull[] = {
1779 0x30,0x54,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1780 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
1781 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
1782 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1783 0x0d,0x02,0x05,0x03,0x11,0x00,0x04,0xd9,0xa5,0xe1,0x2b,0x55,0xa2,0xd8,0xf8,0xe5,
1784 0xd9,0x66,0x82,0x66,0x0f,0xfb };
1786 static void testSignAndEncodeCert(void)
1788 static char oid_rsa_md5rsa[] = szOID_RSA_MD5RSA;
1789 static char oid_rsa_md5[] = szOID_RSA_MD5;
1792 CRYPT_ALGORITHM_IDENTIFIER algID = { 0 };
1793 CERT_INFO info = { 0 };
1796 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1798 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1801 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, &algID, NULL, NULL,
1803 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1804 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1805 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, NULL, NULL,
1806 &algID, NULL, NULL, &size);
1807 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1808 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1809 ret = CryptSignAndEncodeCertificate(0, 0, 0, X509_CERT_TO_BE_SIGNED, NULL,
1810 &algID, NULL, NULL, &size);
1811 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1812 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1813 /* Crashes on some win9x boxes */
1816 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1817 X509_CERT_TO_BE_SIGNED, NULL, &algID, NULL, NULL, &size);
1818 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1819 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1822 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1823 X509_CERT_TO_BE_SIGNED, &info, NULL, NULL, NULL, &size);
1825 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1826 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1828 (GetLastError() == NTE_BAD_ALGID ||
1829 GetLastError() == OSS_BAD_PTR), /* win9x */
1830 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1831 algID.pszObjId = oid_rsa_md5rsa;
1832 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1833 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1834 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1835 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1837 algID.pszObjId = oid_rsa_md5;
1838 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1839 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1840 /* oid_rsa_md5 not present in some win2k */
1843 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
1847 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1848 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, buf, &size);
1849 ok(ret, "CryptSignAndEncodeCertificate failed: %08x\n",
1851 /* Tricky: because the NULL parameters may either be omitted or
1852 * included as an asn.1-encoded NULL (0x05,0x00), two different
1853 * values are allowed.
1855 ok(size == sizeof(md5SignedEmptyCert) ||
1856 size == sizeof(md5SignedEmptyCertNoNull), "Unexpected size %d\n",
1858 if (size == sizeof(md5SignedEmptyCert))
1859 ok(!memcmp(buf, md5SignedEmptyCert, size),
1860 "Unexpected value\n");
1861 else if (size == sizeof(md5SignedEmptyCertNoNull))
1862 ok(!memcmp(buf, md5SignedEmptyCertNoNull, size),
1863 "Unexpected value\n");
1864 HeapFree(GetProcessHeap(), 0, buf);
1869 static void testCreateSelfSignCert(void)
1871 PCCERT_CONTEXT context;
1872 CERT_NAME_BLOB name = { sizeof(subjectName), subjectName };
1876 CRYPT_KEY_PROV_INFO info;
1878 if (!pCertCreateSelfSignCertificate)
1880 skip("CertCreateSelfSignCertificate() is not available\n");
1885 context = pCertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL,
1887 * Calling this with no first parameter creates a new key container, which
1888 * lasts beyond the test, so I don't test that. Nb: the generated key
1890 context = pCertCreateSelfSignCertificate(0, &name, 0, NULL, NULL, NULL, NULL,
1895 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1896 CRYPT_DELETEKEYSET);
1897 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1899 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1901 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1903 ok(!context && GetLastError() == NTE_NO_KEY,
1904 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1905 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
1906 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1909 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1911 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1916 PCRYPT_KEY_PROV_INFO info;
1918 /* The context must have a key provider info property */
1919 ret = CertGetCertificateContextProperty(context,
1920 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1921 ok(ret && size, "Expected non-zero key provider info\n");
1924 info = HeapAlloc(GetProcessHeap(), 0, size);
1927 ret = CertGetCertificateContextProperty(context,
1928 CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1929 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1933 /* Sanity-check the key provider */
1934 ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1935 "Unexpected key container\n");
1936 ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1937 "Unexpected provider\n");
1938 ok(info->dwKeySpec == AT_SIGNATURE,
1939 "Expected AT_SIGNATURE, got %d\n", info->dwKeySpec);
1941 HeapFree(GetProcessHeap(), 0, info);
1945 CertFreeCertificateContext(context);
1948 CryptDestroyKey(key);
1951 CryptReleaseContext(csp, 0);
1952 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1953 CRYPT_DELETEKEYSET);
1955 /* do the same test with AT_KEYEXCHANGE and key info*/
1956 memset(&info,0,sizeof(info));
1957 info.dwProvType = PROV_RSA_FULL;
1958 info.dwKeySpec = AT_KEYEXCHANGE;
1959 info.pwszProvName = (LPWSTR) MS_DEF_PROV_W;
1960 info.pwszContainerName = cspNameW;
1961 context = pCertCreateSelfSignCertificate(0, &name, 0, &info, NULL, NULL,
1963 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1968 PCRYPT_KEY_PROV_INFO info;
1970 /* The context must have a key provider info property */
1971 ret = CertGetCertificateContextProperty(context,
1972 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1973 ok(ret && size, "Expected non-zero key provider info\n");
1976 info = HeapAlloc(GetProcessHeap(), 0, size);
1979 ret = CertGetCertificateContextProperty(context,
1980 CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1981 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1985 /* Sanity-check the key provider */
1986 ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1987 "Unexpected key container\n");
1988 ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1989 "Unexpected provider\n");
1990 ok(info->dwKeySpec == AT_KEYEXCHANGE,
1991 "Expected AT_KEYEXCHANGE, got %d\n", info->dwKeySpec);
1993 HeapFree(GetProcessHeap(), 0, info);
1997 CertFreeCertificateContext(context);
2000 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2001 CRYPT_DELETEKEYSET);
2004 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
2005 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
2007 static void testKeyUsage(void)
2010 PCCERT_CONTEXT context;
2013 /* Test base cases */
2014 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, NULL);
2015 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2016 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2018 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
2019 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2020 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2022 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
2023 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2024 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2026 ret = CertSetEnhancedKeyUsage(NULL, NULL);
2027 usage.cUsageIdentifier = 0;
2028 ret = CertSetEnhancedKeyUsage(NULL, &usage);
2030 /* Test with a cert with no enhanced key usage extension */
2031 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2033 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2037 static const char oid[] = "1.2.3.4";
2038 BYTE buf[sizeof(CERT_ENHKEY_USAGE) + 2 * (sizeof(LPSTR) + sizeof(oid))];
2039 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2041 ret = CertGetEnhancedKeyUsage(context, 0, NULL, NULL);
2042 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2043 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2045 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &size);
2048 /* Windows 2000, ME, or later: even though it succeeded, we expect
2049 * CRYPT_E_NOT_FOUND, which indicates there is no enhanced key
2050 * usage set for this cert (which implies it's valid for all uses.)
2052 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2053 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2054 ok(size == sizeof(CERT_ENHKEY_USAGE), "Wrong size %d\n", size);
2055 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2056 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2057 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2058 pUsage->cUsageIdentifier);
2062 /* Windows NT, 95, or 98: it fails, and the last error is
2063 * CRYPT_E_NOT_FOUND.
2065 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2066 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2068 /* I can add a usage identifier when no key usage has been set */
2069 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2070 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2073 ret = CertGetEnhancedKeyUsage(context,
2074 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2075 ok(ret && GetLastError() == 0,
2076 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2077 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2078 pUsage->cUsageIdentifier);
2079 if (pUsage->cUsageIdentifier)
2080 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2081 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2082 /* Now set an empty key usage */
2083 pUsage->cUsageIdentifier = 0;
2084 ret = CertSetEnhancedKeyUsage(context, pUsage);
2085 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2086 /* Shouldn't find it in the cert */
2088 ret = CertGetEnhancedKeyUsage(context,
2089 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2090 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2091 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2092 /* Should find it as an extended property */
2093 ret = CertGetEnhancedKeyUsage(context,
2094 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2095 ok(ret && GetLastError() == 0,
2096 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2097 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2098 pUsage->cUsageIdentifier);
2099 /* Should find it as either */
2100 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2101 ok(ret && GetLastError() == 0,
2102 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2103 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2104 pUsage->cUsageIdentifier);
2105 /* Add a usage identifier */
2106 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2107 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2110 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2111 ok(ret && GetLastError() == 0,
2112 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2113 ok(pUsage->cUsageIdentifier == 1, "Expected 1 identifier, got %d\n",
2114 pUsage->cUsageIdentifier);
2115 if (pUsage->cUsageIdentifier)
2116 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2117 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2118 /* Re-adding the same usage identifier succeeds, though it only adds
2119 * a duplicate usage identifier on versions prior to Vista
2121 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2122 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2125 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2126 ok(ret && GetLastError() == 0,
2127 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2128 ok(pUsage->cUsageIdentifier == 1 || pUsage->cUsageIdentifier == 2,
2129 "Expected 1 or 2 identifiers, got %d\n", pUsage->cUsageIdentifier);
2130 if (pUsage->cUsageIdentifier)
2131 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2132 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2133 if (pUsage->cUsageIdentifier >= 2)
2134 ok(!strcmp(pUsage->rgpszUsageIdentifier[1], oid),
2135 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[1]);
2136 /* Now set a NULL extended property--this deletes the property. */
2137 ret = CertSetEnhancedKeyUsage(context, NULL);
2138 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2139 SetLastError(0xbaadcafe);
2141 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2142 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2143 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2145 CertFreeCertificateContext(context);
2147 /* Now test with a cert with an enhanced key usage extension */
2148 context = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2149 sizeof(certWithUsage));
2150 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2155 DWORD bufSize = 0, i;
2157 /* The size may depend on what flags are used to query it, so I
2158 * realloc the buffer for each test.
2160 ret = CertGetEnhancedKeyUsage(context,
2161 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2162 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2163 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2166 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2168 /* Should find it in the cert */
2170 ret = CertGetEnhancedKeyUsage(context,
2171 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2172 ok(ret && GetLastError() == 0,
2173 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2174 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2175 pUsage->cUsageIdentifier);
2176 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2177 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2178 "Expected %s, got %s\n", keyUsages[i],
2179 pUsage->rgpszUsageIdentifier[i]);
2180 HeapFree(GetProcessHeap(), 0, buf);
2182 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2183 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2184 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2187 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2189 /* Should find it as either */
2191 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2192 /* In Windows, GetLastError returns CRYPT_E_NOT_FOUND not found
2193 * here, even though the return is successful and the usage id
2194 * count is positive. I don't enforce that here.
2197 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2198 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2199 pUsage->cUsageIdentifier);
2200 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2201 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2202 "Expected %s, got %s\n", keyUsages[i],
2203 pUsage->rgpszUsageIdentifier[i]);
2204 HeapFree(GetProcessHeap(), 0, buf);
2206 /* Shouldn't find it as an extended property */
2207 ret = CertGetEnhancedKeyUsage(context,
2208 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &size);
2209 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2210 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2211 /* Adding a usage identifier overrides the cert's usage!? */
2212 ret = CertAddEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2213 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2215 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2216 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2217 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2220 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2222 /* Should find it as either */
2224 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2226 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2227 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2228 pUsage->cUsageIdentifier);
2229 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], szOID_RSA_RSA),
2230 "Expected %s, got %s\n", szOID_RSA_RSA,
2231 pUsage->rgpszUsageIdentifier[0]);
2232 HeapFree(GetProcessHeap(), 0, buf);
2234 /* But querying the cert directly returns its usage */
2235 ret = CertGetEnhancedKeyUsage(context,
2236 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2237 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2238 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2241 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2244 ret = CertGetEnhancedKeyUsage(context,
2245 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2247 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2248 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2249 pUsage->cUsageIdentifier);
2250 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2251 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2252 "Expected %s, got %s\n", keyUsages[i],
2253 pUsage->rgpszUsageIdentifier[i]);
2254 HeapFree(GetProcessHeap(), 0, buf);
2256 /* And removing the only usage identifier in the extended property
2257 * results in the cert's key usage being found.
2259 ret = CertRemoveEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2260 ok(ret, "CertRemoveEnhancedKeyUsage failed: %08x\n", GetLastError());
2261 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2262 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2263 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2266 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2268 /* Should find it as either */
2270 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2272 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2273 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2274 pUsage->cUsageIdentifier);
2275 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2276 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2277 "Expected %s, got %s\n", keyUsages[i],
2278 pUsage->rgpszUsageIdentifier[i]);
2279 HeapFree(GetProcessHeap(), 0, buf);
2282 CertFreeCertificateContext(context);
2286 static const BYTE cert2WithUsage[] = {
2287 0x30,0x81,0x89,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2288 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2289 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2290 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2291 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2292 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2293 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x25,0x30,0x23,
2294 0x30,0x21,0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x17,0x30,0x15,0x06,
2295 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x2a,0x86,0x48,0x86,
2296 0xf7,0x0d,0x01,0x01,0x01 };
2298 static void testGetValidUsages(void)
2300 static const LPCSTR expectedOIDs[] = {
2301 "1.3.6.1.5.5.7.3.3",
2302 "1.3.6.1.5.5.7.3.2",
2303 "1.2.840.113549.1.1.1",
2305 static const LPCSTR expectedOIDs2[] = {
2306 "1.3.6.1.5.5.7.3.2",
2307 "1.2.840.113549.1.1.1",
2313 PCCERT_CONTEXT contexts[3];
2315 if (!pCertGetValidUsages)
2317 skip("CertGetValidUsages() is not available\n");
2322 ret = pCertGetValidUsages(0, NULL, NULL, NULL, NULL);
2323 ret = pCertGetValidUsages(0, NULL, NULL, NULL, &size);
2326 numOIDs = size = 0xdeadbeef;
2327 SetLastError(0xdeadbeef);
2328 ret = pCertGetValidUsages(1, &contexts[0], &numOIDs, NULL, &size);
2329 ok(ret, "CertGetValidUsages failed: %d\n", GetLastError());
2330 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2331 ok(size == 0, "Expected size 0, got %d\n", size);
2332 contexts[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2334 contexts[1] = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2335 sizeof(certWithUsage));
2336 contexts[2] = CertCreateCertificateContext(X509_ASN_ENCODING,
2337 cert2WithUsage, sizeof(cert2WithUsage));
2338 numOIDs = size = 0xdeadbeef;
2339 ret = pCertGetValidUsages(0, NULL, &numOIDs, NULL, &size);
2340 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2341 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2342 ok(size == 0, "Expected size 0, got %d\n", size);
2343 numOIDs = size = 0xdeadbeef;
2344 ret = pCertGetValidUsages(1, contexts, &numOIDs, NULL, &size);
2345 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2346 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2347 ok(size == 0, "Expected size 0, got %d\n", size);
2348 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, NULL, &size);
2349 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2350 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2351 ok(size, "Expected non-zero size\n");
2352 oids = HeapAlloc(GetProcessHeap(), 0, size);
2356 DWORD smallSize = 1;
2358 SetLastError(0xdeadbeef);
2359 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &smallSize);
2360 ok(!ret && GetLastError() == ERROR_MORE_DATA,
2361 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
2362 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2363 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2364 for (i = 0; i < numOIDs; i++)
2365 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2367 HeapFree(GetProcessHeap(), 0, oids);
2369 numOIDs = size = 0xdeadbeef;
2370 /* Oddly enough, this crashes when the number of contexts is not 1:
2371 ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2372 * but setting size to 0 allows it to succeed:
2375 ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2376 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2377 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2378 ok(size, "Expected non-zero size\n");
2379 oids = HeapAlloc(GetProcessHeap(), 0, size);
2384 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2385 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2386 for (i = 0; i < numOIDs; i++)
2387 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2389 HeapFree(GetProcessHeap(), 0, oids);
2391 numOIDs = 0xdeadbeef;
2393 ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, NULL, &size);
2394 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2395 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2396 ok(size, "Expected non-zero size\n");
2397 oids = HeapAlloc(GetProcessHeap(), 0, size);
2402 ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, oids, &size);
2403 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2404 for (i = 0; i < numOIDs; i++)
2405 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2407 HeapFree(GetProcessHeap(), 0, oids);
2409 numOIDs = 0xdeadbeef;
2411 ret = pCertGetValidUsages(3, contexts, &numOIDs, NULL, &size);
2412 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2413 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2414 ok(size, "Expected non-zero size\n");
2415 oids = HeapAlloc(GetProcessHeap(), 0, size);
2420 ret = pCertGetValidUsages(3, contexts, &numOIDs, oids, &size);
2421 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2422 for (i = 0; i < numOIDs; i++)
2423 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2425 HeapFree(GetProcessHeap(), 0, oids);
2427 CertFreeCertificateContext(contexts[0]);
2428 CertFreeCertificateContext(contexts[1]);
2429 CertFreeCertificateContext(contexts[2]);
2432 static void testCompareCertName(void)
2434 static BYTE bogus[] = { 1, 2, 3, 4 };
2435 static BYTE bogusPrime[] = { 0, 1, 2, 3, 4 };
2436 static BYTE emptyPrime[] = { 0x30, 0x00, 0x01 };
2438 CERT_NAME_BLOB blob1, blob2;
2441 ret = CertCompareCertificateName(0, NULL, NULL);
2443 /* An empty name checks against itself.. */
2444 blob1.pbData = emptyCert;
2445 blob1.cbData = sizeof(emptyCert);
2446 ret = CertCompareCertificateName(0, &blob1, &blob1);
2447 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2448 /* It doesn't have to be a valid encoded name.. */
2449 blob1.pbData = bogus;
2450 blob1.cbData = sizeof(bogus);
2451 ret = CertCompareCertificateName(0, &blob1, &blob1);
2452 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2453 /* Leading zeroes matter.. */
2454 blob2.pbData = bogusPrime;
2455 blob2.cbData = sizeof(bogusPrime);
2456 ret = CertCompareCertificateName(0, &blob1, &blob2);
2457 ok(!ret, "Expected failure\n");
2458 /* As do trailing extra bytes. */
2459 blob2.pbData = emptyPrime;
2460 blob2.cbData = sizeof(emptyPrime);
2461 ret = CertCompareCertificateName(0, &blob1, &blob2);
2462 ok(!ret, "Expected failure\n");
2465 static BYTE int1[] = { 0x88, 0xff, 0xff, 0xff };
2466 static BYTE int2[] = { 0x88, 0xff };
2467 static BYTE int3[] = { 0x23, 0xff };
2468 static BYTE int4[] = { 0x7f, 0x00 };
2469 static BYTE int5[] = { 0x7f };
2470 static BYTE int6[] = { 0x80, 0x00, 0x00, 0x00 };
2471 static BYTE int7[] = { 0x80, 0x00 };
2473 static struct IntBlobTest
2475 CRYPT_INTEGER_BLOB blob1;
2476 CRYPT_INTEGER_BLOB blob2;
2479 { { sizeof(int1), int1 }, { sizeof(int2), int2 }, TRUE },
2480 { { sizeof(int3), int3 }, { sizeof(int3), int3 }, TRUE },
2481 { { sizeof(int4), int4 }, { sizeof(int5), int5 }, TRUE },
2482 { { sizeof(int6), int6 }, { sizeof(int7), int7 }, TRUE },
2483 { { sizeof(int1), int1 }, { sizeof(int7), int7 }, FALSE },
2486 static void testCompareIntegerBlob(void)
2491 for (i = 0; i < sizeof(intBlobs) / sizeof(intBlobs[0]); i++)
2493 ret = CertCompareIntegerBlob(&intBlobs[i].blob1, &intBlobs[i].blob2);
2494 ok(ret == intBlobs[i].areEqual,
2495 "%d: expected blobs %s compare\n", i, intBlobs[i].areEqual ?
2500 static void testComparePublicKeyInfo(void)
2503 CERT_PUBLIC_KEY_INFO info1 = { { 0 } }, info2 = { { 0 } };
2504 static CHAR oid_rsa_rsa[] = szOID_RSA_RSA;
2505 static CHAR oid_rsa_sha1rsa[] = szOID_RSA_SHA1RSA;
2506 static CHAR oid_x957_dsa[] = szOID_X957_DSA;
2507 static BYTE bits1[] = { 1, 0 };
2508 static BYTE bits2[] = { 0 };
2509 static BYTE bits3[] = { 1 };
2510 static BYTE bits4[] = { 0x30,8, 2,1,0x81, 2,3,1,0,1 };
2511 static BYTE bits5[] = { 0x30,9, 2,2,0,0x81, 2,3,1,0,1 };
2512 static BYTE bits6[] = { 0x30,9, 2,2,0,0x82, 2,3,1,0,1 };
2515 ret = CertComparePublicKeyInfo(0, NULL, NULL);
2517 /* Empty public keys compare */
2518 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2519 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2520 /* Different OIDs appear to compare */
2521 info1.Algorithm.pszObjId = oid_rsa_rsa;
2522 info2.Algorithm.pszObjId = oid_rsa_sha1rsa;
2523 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2524 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2525 info2.Algorithm.pszObjId = oid_x957_dsa;
2526 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2527 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2528 info1.PublicKey.cbData = sizeof(bits1);
2529 info1.PublicKey.pbData = bits1;
2530 info1.PublicKey.cUnusedBits = 0;
2531 info2.PublicKey.cbData = sizeof(bits1);
2532 info2.PublicKey.pbData = bits1;
2533 info2.PublicKey.cUnusedBits = 0;
2534 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2535 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2536 info2.Algorithm.pszObjId = oid_rsa_rsa;
2537 info1.PublicKey.cbData = sizeof(bits4);
2538 info1.PublicKey.pbData = bits4;
2539 info1.PublicKey.cUnusedBits = 0;
2540 info2.PublicKey.cbData = sizeof(bits5);
2541 info2.PublicKey.pbData = bits5;
2542 info2.PublicKey.cUnusedBits = 0;
2543 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2544 ok(!ret, "CertComparePublicKeyInfo: as raw binary: keys should be unequal\n");
2545 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2547 broken(!ret), /* win9x */
2548 "CertComparePublicKeyInfo: as ASN.1 encoded: keys should be equal\n");
2549 info1.PublicKey.cUnusedBits = 1;
2550 info2.PublicKey.cUnusedBits = 5;
2551 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2553 broken(!ret), /* win9x */
2554 "CertComparePublicKeyInfo: ASN.1 encoding should ignore cUnusedBits\n");
2555 info1.PublicKey.cUnusedBits = 0;
2556 info2.PublicKey.cUnusedBits = 0;
2557 info1.PublicKey.cbData--; /* kill one byte, make ASN.1 encoded data invalid */
2558 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2559 ok(!ret, "CertComparePublicKeyInfo: comparing bad ASN.1 encoded key should fail\n");
2560 /* Even though they compare in their used bits, these do not compare */
2561 info1.PublicKey.cbData = sizeof(bits2);
2562 info1.PublicKey.pbData = bits2;
2563 info1.PublicKey.cUnusedBits = 0;
2564 info2.PublicKey.cbData = sizeof(bits3);
2565 info2.PublicKey.pbData = bits3;
2566 info2.PublicKey.cUnusedBits = 1;
2567 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2568 /* Simple (non-comparing) case */
2569 ok(!ret, "Expected keys not to compare\n");
2570 info2.PublicKey.cbData = sizeof(bits1);
2571 info2.PublicKey.pbData = bits1;
2572 info2.PublicKey.cUnusedBits = 0;
2573 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2574 ok(!ret, "Expected keys not to compare\n");
2575 /* ASN.1 encoded non-comparing case */
2576 info1.PublicKey.cbData = sizeof(bits5);
2577 info1.PublicKey.pbData = bits5;
2578 info1.PublicKey.cUnusedBits = 0;
2579 info2.PublicKey.cbData = sizeof(bits6);
2580 info2.PublicKey.pbData = bits6;
2581 info2.PublicKey.cUnusedBits = 0;
2582 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2583 ok(!ret, "CertComparePublicKeyInfo: different keys should be unequal\n");
2586 static void testHashPublicKeyInfo(void)
2589 CERT_PUBLIC_KEY_INFO info = { { 0 } };
2593 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, NULL);
2594 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, &info, NULL, NULL);
2596 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, &len);
2597 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2598 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2599 /* Crashes on some win9x boxes */
2602 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, NULL, NULL, &len);
2603 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2604 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2606 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, NULL, &len);
2608 broken(!ret), /* win9x */
2609 "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2612 ok(len == 16, "Expected hash size 16, got %d\n", len);
2615 static const BYTE emptyHash[] = { 0xb8,0x51,0x3a,0x31,0x0e,0x9f,0x40,
2616 0x36,0x9c,0x92,0x45,0x1b,0x9d,0xc8,0xf9,0xf6 };
2619 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, buf,
2621 ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2622 ok(!memcmp(buf, emptyHash, len), "Unexpected hash\n");
2627 static const BYTE md5SignedEmptyCertHash[] = { 0xfb,0x0f,0x66,0x82,0x66,0xd9,
2628 0xe5,0xf8,0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
2630 static void testHashToBeSigned(void)
2639 ret = CryptHashToBeSigned(0, 0, NULL, 0, NULL, NULL);
2641 SetLastError(0xdeadbeef);
2642 ret = CryptHashToBeSigned(0, 0, NULL, 0, NULL, &size);
2643 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2644 "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
2645 SetLastError(0xdeadbeef);
2646 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, NULL, 0, NULL, &size);
2648 (GetLastError() == CRYPT_E_ASN1_EOD ||
2649 GetLastError() == OSS_BAD_ARG), /* win9x */
2650 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2651 /* Can't sign anything: has to be asn.1 encoded, at least */
2652 SetLastError(0xdeadbeef);
2653 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, int1, sizeof(int1),
2656 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2657 GetLastError() == OSS_MORE_INPUT), /* win9x */
2658 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2659 /* Can't be empty, either */
2660 SetLastError(0xdeadbeef);
2661 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, emptyCert,
2662 sizeof(emptyCert), NULL, &size);
2664 (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2665 GetLastError() == OSS_DATA_ERROR), /* win9x */
2666 "expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2667 /* Signing a cert works */
2668 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert,
2669 sizeof(md5SignedEmptyCert), NULL, &size);
2671 broken(!ret), /* win9x */
2672 "CryptHashToBeSigned failed: %08x\n", GetLastError());
2675 ok(size == sizeof(md5SignedEmptyCertHash), "unexpected size %d\n", size);
2678 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert,
2679 sizeof(md5SignedEmptyCert), hash, &size);
2680 ok(!memcmp(hash, md5SignedEmptyCertHash, size), "unexpected value\n");
2683 static void testCompareCert(void)
2685 CERT_INFO info1 = { 0 }, info2 = { 0 };
2689 ret = CertCompareCertificate(X509_ASN_ENCODING, NULL, NULL);
2692 /* Certs with the same issuer and serial number are equal, even if they
2693 * differ in other respects (like subject).
2695 info1.SerialNumber.pbData = serialNum;
2696 info1.SerialNumber.cbData = sizeof(serialNum);
2697 info1.Issuer.pbData = subjectName;
2698 info1.Issuer.cbData = sizeof(subjectName);
2699 info1.Subject.pbData = subjectName2;
2700 info1.Subject.cbData = sizeof(subjectName2);
2701 info2.SerialNumber.pbData = serialNum;
2702 info2.SerialNumber.cbData = sizeof(serialNum);
2703 info2.Issuer.pbData = subjectName;
2704 info2.Issuer.cbData = sizeof(subjectName);
2705 info2.Subject.pbData = subjectName;
2706 info2.Subject.cbData = sizeof(subjectName);
2707 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2708 ok(ret, "Expected certs to be equal\n");
2710 info2.Issuer.pbData = subjectName2;
2711 info2.Issuer.cbData = sizeof(subjectName2);
2712 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2713 ok(!ret, "Expected certs not to be equal\n");
2716 static void testVerifySubjectCert(void)
2720 PCCERT_CONTEXT context1, context2;
2723 ret = CertVerifySubjectCertificateContext(NULL, NULL, NULL);
2726 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2727 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2729 flags = CERT_STORE_NO_CRL_FLAG;
2730 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2731 ok(!ret && GetLastError() == E_INVALIDARG,
2732 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2735 context1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2737 ret = CertVerifySubjectCertificateContext(NULL, context1, &flags);
2738 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2740 ret = CertVerifySubjectCertificateContext(context1, NULL, &flags);
2741 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2743 ret = CertVerifySubjectCertificateContext(context1, context1, &flags);
2744 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2747 context2 = CertCreateCertificateContext(X509_ASN_ENCODING,
2748 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject));
2749 SetLastError(0xdeadbeef);
2750 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2751 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2753 flags = CERT_STORE_REVOCATION_FLAG;
2754 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2755 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2757 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
2758 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
2760 flags = CERT_STORE_SIGNATURE_FLAG;
2761 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2762 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2764 ok(flags == CERT_STORE_SIGNATURE_FLAG,
2765 "Expected CERT_STORE_SIGNATURE_FLAG, got %08x\n", flags);
2766 CertFreeCertificateContext(context2);
2768 CertFreeCertificateContext(context1);
2771 static void testVerifyRevocation(void)
2774 CERT_REVOCATION_STATUS status = { 0 };
2775 PCCERT_CONTEXT cert = CertCreateCertificateContext(X509_ASN_ENCODING,
2776 bigCert, sizeof(bigCert));
2779 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL);
2781 SetLastError(0xdeadbeef);
2782 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2783 ok(!ret && GetLastError() == E_INVALIDARG,
2784 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2785 status.cbSize = sizeof(status);
2786 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2787 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2788 ret = CertVerifyRevocation(0, 2, 0, NULL, 0, NULL, &status);
2789 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2790 ret = CertVerifyRevocation(2, 0, 0, NULL, 0, NULL, &status);
2791 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2792 SetLastError(0xdeadbeef);
2793 ret = CertVerifyRevocation(0, 0, 1, (void **)&cert, 0, NULL, &status);
2794 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2795 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2796 SetLastError(0xdeadbeef);
2797 ret = CertVerifyRevocation(0, 2, 1, (void **)&cert, 0, NULL, &status);
2798 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2799 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2801 CertFreeCertificateContext(cert);
2804 static BYTE privKey[] = {
2805 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
2806 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
2807 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
2808 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
2809 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
2810 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
2811 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
2812 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
2813 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
2814 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
2815 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
2816 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
2817 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
2818 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
2819 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
2820 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
2821 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
2822 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
2823 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
2824 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
2825 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
2826 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
2827 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
2828 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
2830 static const BYTE exportedPublicKeyBlob[] = {
2831 0x06,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x31,0x00,0x02,0x00,0x00,
2832 0x01,0x00,0x01,0x00,0x79,0x10,0x1c,0xd0,0x6b,0x10,0x18,0x30,0x94,0x61,0xdc,0x0e,
2833 0xcb,0x96,0x4e,0x21,0x3f,0x79,0xcd,0xa9,0x17,0x62,0xbc,0xbb,0x61,0x4c,0xe0,0x75,
2834 0x38,0x6c,0xf3,0xde,0x60,0x86,0x03,0x97,0x65,0xeb,0x1e,0x6b,0xdb,0x53,0x85,0xad,
2835 0x68,0x21,0xf1,0x5d,0xe7,0x1f,0xe6,0x53,0xb4,0xbb,0x59,0x3e,0x14,0x27,0xb1,0x83,
2836 0xa7,0x3a,0x54,0xe2 };
2838 static const BYTE asnEncodedPublicKey[] = {
2839 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,
2840 0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
2841 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,
2842 0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
2843 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
2845 static void testAcquireCertPrivateKey(void)
2848 PCCERT_CONTEXT cert;
2850 DWORD size, keySpec;
2852 CRYPT_KEY_PROV_INFO keyProvInfo;
2854 WCHAR ms_def_prov_w[MAX_PATH];
2856 if (!pCryptAcquireCertificatePrivateKey)
2858 skip("CryptAcquireCertificatePrivateKey() is not available\n");
2862 lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
2864 keyProvInfo.pwszContainerName = cspNameW;
2865 keyProvInfo.pwszProvName = ms_def_prov_w;
2866 keyProvInfo.dwProvType = PROV_RSA_FULL;
2867 keyProvInfo.dwFlags = 0;
2868 keyProvInfo.cProvParam = 0;
2869 keyProvInfo.rgProvParam = NULL;
2870 keyProvInfo.dwKeySpec = AT_SIGNATURE;
2872 pCryptAcquireContextA(NULL, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2873 CRYPT_DELETEKEYSET);
2875 cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
2876 sizeof(selfSignedCert));
2879 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL, NULL);
2880 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL,
2882 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, &keySpec,
2884 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, NULL, NULL);
2885 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, &keySpec,
2887 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, NULL, NULL, NULL);
2890 /* Missing private key */
2891 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, NULL, NULL);
2892 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2893 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2894 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2896 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2897 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2898 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2900 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2902 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2903 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2905 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2907 ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
2908 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
2913 CERT_KEY_CONTEXT keyContext;
2915 /* Don't cache provider */
2916 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2917 &keySpec, &callerFree);
2919 broken(!ret), /* win95 */
2920 "CryptAcquireCertificatePrivateKey failed: %08x\n",
2924 ok(callerFree, "Expected callerFree to be TRUE\n");
2925 CryptReleaseContext(certCSP, 0);
2928 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2931 broken(!ret), /* win95 */
2932 "CryptAcquireCertificatePrivateKey failed: %08x\n",
2934 CryptReleaseContext(certCSP, 0);
2936 /* Use the key prov info's caching (there shouldn't be any) */
2937 ret = pCryptAcquireCertificatePrivateKey(cert,
2938 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2941 broken(!ret), /* win95 */
2942 "CryptAcquireCertificatePrivateKey failed: %08x\n",
2946 ok(callerFree, "Expected callerFree to be TRUE\n");
2947 CryptReleaseContext(certCSP, 0);
2950 /* Cache it (and check that it's cached) */
2951 ret = pCryptAcquireCertificatePrivateKey(cert,
2952 CRYPT_ACQUIRE_CACHE_FLAG, NULL, &certCSP, &keySpec, &callerFree);
2954 broken(!ret), /* win95 */
2955 "CryptAcquireCertificatePrivateKey failed: %08x\n",
2957 ok(!callerFree, "Expected callerFree to be FALSE\n");
2958 size = sizeof(keyContext);
2959 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2960 &keyContext, &size);
2962 broken(!ret), /* win95 */
2963 "CertGetCertificateContextProperty failed: %08x\n",
2966 /* Remove the cached provider */
2967 CryptReleaseContext(keyContext.hCryptProv, 0);
2968 CertSetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID, 0,
2970 /* Allow caching via the key prov info */
2971 keyProvInfo.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
2972 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2974 /* Now use the key prov info's caching */
2975 ret = pCryptAcquireCertificatePrivateKey(cert,
2976 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2979 broken(!ret), /* win95 */
2980 "CryptAcquireCertificatePrivateKey failed: %08x\n",
2982 ok(!callerFree, "Expected callerFree to be FALSE\n");
2983 size = sizeof(keyContext);
2984 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2985 &keyContext, &size);
2987 broken(!ret), /* win95 */
2988 "CertGetCertificateContextProperty failed: %08x\n",
2990 CryptReleaseContext(certCSP, 0);
2992 CryptDestroyKey(key);
2995 /* Some sanity-checking on public key exporting */
2996 ret = CryptImportPublicKeyInfo(csp, X509_ASN_ENCODING,
2997 &cert->pCertInfo->SubjectPublicKeyInfo, &key);
2998 ok(ret, "CryptImportPublicKeyInfo failed: %08x\n", GetLastError());
3001 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, NULL, &size);
3002 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
3005 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size), encodedKey;
3007 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, buf, &size);
3008 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
3009 ok(size == sizeof(exportedPublicKeyBlob), "Unexpected size %d\n",
3011 ok(!memcmp(buf, exportedPublicKeyBlob, size), "Unexpected value\n");
3012 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB,
3013 buf, CRYPT_ENCODE_ALLOC_FLAG, NULL, &encodedKey, &size);
3014 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3017 ok(size == sizeof(asnEncodedPublicKey), "Unexpected size %d\n",
3019 ok(!memcmp(encodedKey, asnEncodedPublicKey, size),
3020 "Unexpected value\n");
3021 LocalFree(encodedKey);
3023 HeapFree(GetProcessHeap(), 0, buf);
3025 CryptDestroyKey(key);
3027 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
3028 NULL, 0, NULL, NULL, &size);
3029 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
3032 PCERT_PUBLIC_KEY_INFO info = HeapAlloc(GetProcessHeap(), 0, size);
3034 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
3035 NULL, 0, NULL, info, &size);
3036 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
3039 ok(info->PublicKey.cbData == sizeof(asnEncodedPublicKey),
3040 "Unexpected size %d\n", info->PublicKey.cbData);
3041 ok(!memcmp(info->PublicKey.pbData, asnEncodedPublicKey,
3042 info->PublicKey.cbData), "Unexpected value\n");
3044 HeapFree(GetProcessHeap(), 0, info);
3047 CryptReleaseContext(csp, 0);
3048 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
3049 CRYPT_DELETEKEYSET);
3051 CertFreeCertificateContext(cert);
3054 static void testGetPublicKeyLength(void)
3056 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3057 static char oid_rsa_dh[] = szOID_RSA_DH;
3058 static char bogusOID[] = "1.2.3";
3060 CERT_PUBLIC_KEY_INFO info = { { 0 } };
3061 BYTE bogusKey[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
3062 BYTE key[] = { 0x30,0x0f,0x02,0x08,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
3063 0x02,0x03,0x01,0x00,0x01 };
3066 ret = CertGetPublicKeyLength(0, NULL);
3068 /* With an empty public key info */
3069 SetLastError(0xdeadbeef);
3070 ret = CertGetPublicKeyLength(0, &info);
3071 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3072 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3073 ret, GetLastError());
3074 SetLastError(0xdeadbeef);
3075 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3077 (GetLastError() == CRYPT_E_ASN1_EOD ||
3078 GetLastError() == OSS_BAD_ARG), /* win9x */
3079 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
3080 ret, GetLastError());
3081 /* With a nearly-empty public key info */
3082 info.Algorithm.pszObjId = oid_rsa_rsa;
3083 SetLastError(0xdeadbeef);
3084 ret = CertGetPublicKeyLength(0, &info);
3085 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3086 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3087 ret, GetLastError());
3088 SetLastError(0xdeadbeef);
3089 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3091 (GetLastError() == CRYPT_E_ASN1_EOD ||
3092 GetLastError() == OSS_BAD_ARG), /* win9x */
3093 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
3094 ret, GetLastError());
3095 /* With a bogus key */
3096 info.PublicKey.cbData = sizeof(bogusKey);
3097 info.PublicKey.pbData = bogusKey;
3098 SetLastError(0xdeadbeef);
3099 ret = CertGetPublicKeyLength(0, &info);
3100 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3101 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3102 ret, GetLastError());
3103 SetLastError(0xdeadbeef);
3104 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3106 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3107 GetLastError() == OSS_PDU_MISMATCH), /* win9x */
3108 "Expected length 0 and CRYPT_E_ASN1_BADTAGTAG, got length %d, %08x\n",
3109 ret, GetLastError());
3110 /* With a believable RSA key but a bogus OID */
3111 info.Algorithm.pszObjId = bogusOID;
3112 info.PublicKey.cbData = sizeof(key);
3113 info.PublicKey.pbData = key;
3114 SetLastError(0xdeadbeef);
3115 ret = CertGetPublicKeyLength(0, &info);
3116 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3117 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3118 ret, GetLastError());
3119 SetLastError(0xdeadbeef);
3120 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3121 ok(ret == 56, "Expected length 56, got %d\n", ret);
3122 /* An RSA key with the DH OID */
3123 info.Algorithm.pszObjId = oid_rsa_dh;
3124 SetLastError(0xdeadbeef);
3125 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3127 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3128 GetLastError() == E_INVALIDARG), /* win9x */
3129 "Expected length 0 and CRYPT_E_ASN1_BADTAG, got length %d, %08x\n",
3130 ret, GetLastError());
3131 /* With the RSA OID */
3132 info.Algorithm.pszObjId = oid_rsa_rsa;
3133 SetLastError(0xdeadbeef);
3134 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3135 ok(ret == 56, "Expected length 56, got %d\n", ret);
3136 /* With the RSA OID and a message encoding */
3137 info.Algorithm.pszObjId = oid_rsa_rsa;
3138 SetLastError(0xdeadbeef);
3139 ret = CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &info);
3140 ok(ret == 56, "Expected length 56, got %d\n", ret);
3145 init_function_pointers();
3148 testCertProperties();
3151 testGetSubjectCert();
3152 testGetIssuerCert();
3154 testCryptHashCert();
3156 testSignAndEncodeCert();
3157 testCreateSelfSignCert();
3159 testGetValidUsages();
3160 testCompareCertName();
3161 testCompareIntegerBlob();
3162 testComparePublicKeyInfo();
3163 testHashPublicKeyInfo();
3164 testHashToBeSigned();
3166 testVerifySubjectCert();
3167 testVerifyRevocation();
3168 testAcquireCertPrivateKey();
3169 testGetPublicKeyLength();