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);
514 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
515 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
517 /* Test key contexts and handles and such */
519 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
521 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
522 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
523 size = sizeof(CERT_KEY_CONTEXT);
524 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
526 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
527 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
528 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
530 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
531 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
532 /* Key context with an invalid size */
533 keyContext.cbSize = 0;
534 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
536 ok(!ret && GetLastError() == E_INVALIDARG,
537 "Expected E_INVALIDARG, got %08x\n", GetLastError());
538 size = sizeof(keyContext);
539 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
541 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
542 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
543 keyContext.cbSize = sizeof(keyContext);
544 keyContext.hCryptProv = 0;
545 keyContext.dwKeySpec = AT_SIGNATURE;
546 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
548 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
549 /* Now that that's set, the key prov handle property is also gettable.
551 size = sizeof(DWORD);
552 ret = CertGetCertificateContextProperty(context,
553 CERT_KEY_PROV_HANDLE_PROP_ID, &keyContext.hCryptProv, &size);
554 ok(ret, "Expected to get the CERT_KEY_PROV_HANDLE_PROP_ID, got %08x\n",
556 /* Remove the key prov handle property.. */
557 ret = CertSetCertificateContextProperty(context,
558 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
559 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
561 /* and the key context's CSP is set to NULL. */
562 size = sizeof(keyContext);
563 ret = CertGetCertificateContextProperty(context,
564 CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
565 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
567 ok(keyContext.hCryptProv == 0, "Expected no hCryptProv\n");
569 /* According to MSDN the subject key id can be stored as a property,
570 * as a subject key extension, or as the SHA1 hash of the public key,
571 * but this cert has none of them:
573 ret = CertGetCertificateContextProperty(context,
574 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
575 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
576 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
577 CertFreeCertificateContext(context);
578 /* This cert does have a public key, but its subject key identifier still
579 * isn't available: */
580 context = CertCreateCertificateContext(X509_ASN_ENCODING,
581 v1CertWithPubKey, sizeof(v1CertWithPubKey));
582 ret = CertGetCertificateContextProperty(context,
583 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
584 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
585 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
586 CertFreeCertificateContext(context);
587 /* This cert with a subject key extension can have its key identifier
588 * property retrieved:
590 context = CertCreateCertificateContext(X509_ASN_ENCODING,
591 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId));
592 ret = CertGetCertificateContextProperty(context,
593 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
594 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
597 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
601 ret = CertGetCertificateContextProperty(context,
602 CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
603 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
605 ok(!memcmp(buf, subjectKeyId, size), "Unexpected subject key id\n");
606 HeapFree(GetProcessHeap(), 0, buf);
609 CertFreeCertificateContext(context);
611 context = CertCreateCertificateContext(X509_ASN_ENCODING,
612 selfSignedCert, sizeof(selfSignedCert));
613 /* Getting the signature hash of a valid (self-signed) cert succeeds */
615 ret = CertGetCertificateContextProperty(context,
616 CERT_SIGNATURE_HASH_PROP_ID, NULL, &size);
617 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
618 ok(size == sizeof(selfSignedSignatureHash), "unexpected size %d\n", size);
619 ret = CertGetCertificateContextProperty(context,
620 CERT_SIGNATURE_HASH_PROP_ID, hashProperty, &size);
622 ok(!memcmp(hashProperty, selfSignedSignatureHash, size),
623 "unexpected value\n");
624 CertFreeCertificateContext(context);
627 static void testDupCert(void)
630 PCCERT_CONTEXT context, dupContext;
633 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
634 CERT_STORE_CREATE_NEW_FLAG, NULL);
635 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
639 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
640 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
641 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
643 ok(context != NULL, "Expected a valid cert context\n");
646 ok(context->cbCertEncoded == sizeof(bigCert),
647 "Wrong cert size %d\n", context->cbCertEncoded);
648 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)),
649 "Unexpected encoded cert in context\n");
650 ok(context->hCertStore == store, "Unexpected store\n");
652 dupContext = CertDuplicateCertificateContext(context);
653 ok(dupContext != NULL, "Expected valid duplicate\n");
654 /* Not only is it a duplicate, it's identical: the address is the
657 ok(dupContext == context, "Expected identical context addresses\n");
658 CertFreeCertificateContext(dupContext);
659 CertFreeCertificateContext(context);
661 CertCloseStore(store, 0);
664 static BYTE subjectName3[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
665 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x52, 0x6f, 0x62, 0x20, 0x20, 0x4c, 0x61,
667 static const BYTE iTunesCert0[] = {
668 0x30,0x82,0x03,0xc4,0x30,0x82,0x03,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
669 0x47,0xbf,0x19,0x95,0xdf,0x8d,0x52,0x46,0x43,0xf7,0xdb,0x6d,0x48,0x0d,0x31,
670 0xa4,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
671 0x00,0x30,0x81,0x8b,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
672 0x5a,0x41,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0c,0x57,0x65,
673 0x73,0x74,0x65,0x72,0x6e,0x20,0x43,0x61,0x70,0x65,0x31,0x14,0x30,0x12,0x06,
674 0x03,0x55,0x04,0x07,0x13,0x0b,0x44,0x75,0x72,0x62,0x61,0x6e,0x76,0x69,0x6c,
675 0x6c,0x65,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x0a,0x13,0x06,0x54,0x68,
676 0x61,0x77,0x74,0x65,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14,
677 0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
678 0x61,0x74,0x69,0x6f,0x6e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13,
679 0x16,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
680 0x6d,0x70,0x69,0x6e,0x67,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x33,0x31,
681 0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x33,0x31,
682 0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x53,0x31,0x0b,0x30,
683 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,
684 0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
685 0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,
686 0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,0x6d,0x65,0x20,
687 0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,0x76,0x69,0x63,
688 0x65,0x73,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,
689 0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,
690 0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa9,0xca,0xb2,0xa4,0xcc,0xcd,0x20,
691 0xaf,0x0a,0x7d,0x89,0xac,0x87,0x75,0xf0,0xb4,0x4e,0xf1,0xdf,0xc1,0x0f,0xbf,
692 0x67,0x61,0xbd,0xa3,0x64,0x1c,0xda,0xbb,0xf9,0xca,0x33,0xab,0x84,0x30,0x89,
693 0x58,0x7e,0x8c,0xdb,0x6b,0xdd,0x36,0x9e,0x0f,0xbf,0xd1,0xec,0x78,0xf2,0x77,
694 0xa6,0x7e,0x6f,0x3c,0xbf,0x93,0xaf,0x0d,0xba,0x68,0xf4,0x6c,0x94,0xca,0xbd,
695 0x52,0x2d,0xab,0x48,0x3d,0xf5,0xb6,0xd5,0x5d,0x5f,0x1b,0x02,0x9f,0xfa,0x2f,
696 0x6b,0x1e,0xa4,0xf7,0xa3,0x9a,0xa6,0x1a,0xc8,0x02,0xe1,0x7f,0x4c,0x52,0xe3,
697 0x0e,0x60,0xec,0x40,0x1c,0x7e,0xb9,0x0d,0xde,0x3f,0xc7,0xb4,0xdf,0x87,0xbd,
698 0x5f,0x7a,0x6a,0x31,0x2e,0x03,0x99,0x81,0x13,0xa8,0x47,0x20,0xce,0x31,0x73,
699 0x0d,0x57,0x2d,0xcd,0x78,0x34,0x33,0x95,0x12,0x99,0x12,0xb9,0xde,0x68,0x2f,
700 0xaa,0xe6,0xe3,0xc2,0x8a,0x8c,0x2a,0xc3,0x8b,0x21,0x87,0x66,0xbd,0x83,0x58,
701 0x57,0x6f,0x75,0xbf,0x3c,0xaa,0x26,0x87,0x5d,0xca,0x10,0x15,0x3c,0x9f,0x84,
702 0xea,0x54,0xc1,0x0a,0x6e,0xc4,0xfe,0xc5,0x4a,0xdd,0xb9,0x07,0x11,0x97,0x22,
703 0x7c,0xdb,0x3e,0x27,0xd1,0x1e,0x78,0xec,0x9f,0x31,0xc9,0xf1,0xe6,0x22,0x19,
704 0xdb,0xc4,0xb3,0x47,0x43,0x9a,0x1a,0x5f,0xa0,0x1e,0x90,0xe4,0x5e,0xf5,0xee,
705 0x7c,0xf1,0x7d,0xab,0x62,0x01,0x8f,0xf5,0x4d,0x0b,0xde,0xd0,0x22,0x56,0xa8,
706 0x95,0xcd,0xae,0x88,0x76,0xae,0xee,0xba,0x0d,0xf3,0xe4,0x4d,0xd9,0xa0,0xfb,
707 0x68,0xa0,0xae,0x14,0x3b,0xb3,0x87,0xc1,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,
708 0x81,0xdb,0x30,0x81,0xd8,0x30,0x34,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
709 0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
710 0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,
711 0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,
712 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
713 0xff,0x02,0x01,0x00,0x30,0x41,0x06,0x03,0x55,0x1d,0x1f,0x04,0x3a,0x30,0x38,
714 0x30,0x36,0xa0,0x34,0xa0,0x32,0x86,0x30,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
715 0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,
716 0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
717 0x6d,0x70,0x69,0x6e,0x67,0x43,0x41,0x2e,0x63,0x72,0x6c,0x30,0x13,0x06,0x03,
718 0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
719 0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,
720 0x02,0x01,0x06,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,0x04,0x1d,0x30,0x1b,0xa4,
721 0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0c,0x54,
722 0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,0x33,0x30,0x0d,0x06,0x09,
723 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,
724 0x4a,0x6b,0xf9,0xea,0x58,0xc2,0x44,0x1c,0x31,0x89,0x79,0x99,0x2b,0x96,0xbf,
725 0x82,0xac,0x01,0xd6,0x1c,0x4c,0xcd,0xb0,0x8a,0x58,0x6e,0xdf,0x08,0x29,0xa3,
726 0x5e,0xc8,0xca,0x93,0x13,0xe7,0x04,0x52,0x0d,0xef,0x47,0x27,0x2f,0x00,0x38,
727 0xb0,0xe4,0xc9,0x93,0x4e,0x9a,0xd4,0x22,0x62,0x15,0xf7,0x3f,0x37,0x21,0x4f,
728 0x70,0x31,0x80,0xf1,0x8b,0x38,0x87,0xb3,0xe8,0xe8,0x97,0x00,0xfe,0xcf,0x55,
729 0x96,0x4e,0x24,0xd2,0xa9,0x27,0x4e,0x7a,0xae,0xb7,0x61,0x41,0xf3,0x2a,0xce,
730 0xe7,0xc9,0xd9,0x5e,0xdd,0xbb,0x2b,0x85,0x3e,0xb5,0x9d,0xb5,0xd9,0xe1,0x57,
731 0xff,0xbe,0xb4,0xc5,0x7e,0xf5,0xcf,0x0c,0x9e,0xf0,0x97,0xfe,0x2b,0xd3,0x3b,
732 0x52,0x1b,0x1b,0x38,0x27,0xf7,0x3f,0x4a };
733 static const BYTE iTunesCert1[] = {
734 0x30,0x82,0x03,0xff,0x30,0x82,0x02,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
735 0x0d,0xe9,0x2b,0xf0,0xd4,0xd8,0x29,0x88,0x18,0x32,0x05,0x09,0x5e,0x9a,0x76,
736 0x88,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
737 0x00,0x30,0x53,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
738 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
739 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,
740 0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
741 0x20,0x54,0x69,0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,
742 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,
743 0x30,0x33,0x31,0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
744 0x30,0x38,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x57,
745 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,
746 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,
747 0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2f,0x30,0x2d,0x06,0x03,0x55,
748 0x04,0x03,0x13,0x26,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,
749 0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,
750 0x76,0x69,0x63,0x65,0x73,0x20,0x53,0x69,0x67,0x6e,0x65,0x72,0x30,0x82,0x01,
751 0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
752 0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,
753 0xb2,0x50,0x28,0x48,0xdd,0xd3,0x68,0x7a,0x84,0x18,0x44,0x66,0x75,0x5d,0x7e,
754 0xc4,0xb8,0x9f,0x63,0x26,0xff,0x3d,0x43,0x9c,0x7c,0x11,0x38,0x10,0x25,0x55,
755 0x73,0xd9,0x75,0x27,0x69,0xfd,0x4e,0xb9,0x20,0x5c,0xd3,0x0a,0xf9,0xa0,0x1b,
756 0x2a,0xed,0x55,0x56,0x21,0x61,0xd8,0x1e,0xdb,0xe4,0xbc,0x33,0x6b,0xc7,0xef,
757 0xdd,0xa3,0x37,0x65,0x8e,0x1b,0x93,0x0c,0xb6,0x53,0x1e,0x5c,0x7c,0x66,0x35,
758 0x5f,0x05,0x8a,0x45,0xfe,0x76,0x4e,0xdf,0x53,0x80,0xa2,0x81,0x20,0x9d,0xae,
759 0x88,0x5c,0xa2,0x08,0xf7,0xe5,0x30,0xf9,0xee,0x22,0x37,0x4c,0x42,0x0a,0xce,
760 0xdf,0xc6,0x1f,0xc4,0xd6,0x55,0xe9,0x81,0x3f,0xb5,0x52,0xa3,0x2c,0xaa,0x01,
761 0x7a,0xf2,0xa2,0xaa,0x8d,0x35,0xfe,0x9f,0xe6,0x5d,0x6a,0x05,0x9f,0x3d,0x6b,
762 0xe3,0xbf,0x96,0xc0,0xfe,0xcc,0x60,0xf9,0x40,0xe7,0x07,0xa0,0x44,0xeb,0x81,
763 0x51,0x6e,0xa5,0x2a,0xf2,0xb6,0x8a,0x10,0x28,0xed,0x8f,0xdc,0x06,0xa0,0x86,
764 0x50,0x9a,0x7b,0x4a,0x08,0x0d,0x30,0x1d,0xca,0x10,0x9e,0x6b,0xf7,0xe9,0x58,
765 0xae,0x04,0xa9,0x40,0x99,0xb2,0x28,0xe8,0x8f,0x16,0xac,0x3c,0xe3,0x53,0x6f,
766 0x4b,0xd3,0x35,0x9d,0xb5,0x6f,0x64,0x1d,0xb3,0x96,0x2c,0xbb,0x3d,0xe7,0x79,
767 0xeb,0x6d,0x7a,0xf9,0x16,0xe6,0x26,0xad,0xaf,0xef,0x99,0x53,0xb7,0x40,0x2c,
768 0x95,0xb8,0x79,0xaa,0xfe,0xd4,0x52,0xab,0x29,0x74,0x7e,0x42,0xec,0x39,0x1e,
769 0xa2,0x6a,0x16,0xe6,0x59,0xbb,0x24,0x68,0xd8,0x00,0x80,0x43,0x10,0x87,0x80,
770 0x6b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xca,0x30,0x81,0xc7,0x30,0x34,0x06,
771 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,
772 0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,
773 0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
774 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
775 0xff,0x04,0x02,0x30,0x00,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30,
776 0x2a,0x30,0x28,0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,
777 0x2f,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,
778 0x6f,0x6d,0x2f,0x74,0x73,0x73,0x2d,0x63,0x61,0x2e,0x63,0x72,0x6c,0x30,0x16,
779 0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,
780 0x06,0x01,0x05,0x05,0x07,0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
781 0x01,0xff,0x04,0x04,0x03,0x02,0x06,0xc0,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,
782 0x04,0x1d,0x30,0x1b,0xa4,0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,
783 0x04,0x03,0x13,0x0c,0x54,0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,
784 0x34,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
785 0x00,0x03,0x82,0x01,0x01,0x00,0x87,0x78,0x70,0xda,0x4e,0x52,0x01,0x20,0x5b,
786 0xe0,0x79,0xc9,0x82,0x30,0xc4,0xfd,0xb9,0x19,0x96,0xbd,0x91,0x00,0xc3,0xbd,
787 0xcd,0xcd,0xc6,0xf4,0x0e,0xd8,0xff,0xf9,0x4d,0xc0,0x33,0x62,0x30,0x11,0xc5,
788 0xf5,0x74,0x1b,0xd4,0x92,0xde,0x5f,0x9c,0x20,0x13,0xb1,0x7c,0x45,0xbe,0x50,
789 0xcd,0x83,0xe7,0x80,0x17,0x83,0xa7,0x27,0x93,0x67,0x13,0x46,0xfb,0xca,0xb8,
790 0x98,0x41,0x03,0xcc,0x9b,0x51,0x5b,0x05,0x8b,0x7f,0xa8,0x6f,0xf3,0x1b,0x50,
791 0x1b,0x24,0x2e,0xf2,0x69,0x8d,0x6c,0x22,0xf7,0xbb,0xca,0x16,0x95,0xed,0x0c,
792 0x74,0xc0,0x68,0x77,0xd9,0xeb,0x99,0x62,0x87,0xc1,0x73,0x90,0xf8,0x89,0x74,
793 0x7a,0x23,0xab,0xa3,0x98,0x7b,0x97,0xb1,0xf7,0x8f,0x29,0x71,0x4d,0x2e,0x75,
794 0x1b,0x48,0x41,0xda,0xf0,0xb5,0x0d,0x20,0x54,0xd6,0x77,0xa0,0x97,0x82,0x63,
795 0x69,0xfd,0x09,0xcf,0x8a,0xf0,0x75,0xbb,0x09,0x9b,0xd9,0xf9,0x11,0x55,0x26,
796 0x9a,0x61,0x32,0xbe,0x7a,0x02,0xb0,0x7b,0x86,0xbe,0xa2,0xc3,0x8b,0x22,0x2c,
797 0x78,0xd1,0x35,0x76,0xbc,0x92,0x73,0x5c,0xf9,0xb9,0xe6,0x4c,0x15,0x0a,0x23,
798 0xcc,0xe4,0xd2,0xd4,0x34,0x2e,0x49,0x40,0x15,0x3c,0x0f,0x60,0x7a,0x24,0xc6,
799 0xa5,0x66,0xef,0x96,0xcf,0x70,0xeb,0x3e,0xe7,0xf4,0x0d,0x7e,0xdc,0xd1,0x7c,
800 0xa3,0x76,0x71,0x69,0xc1,0x9c,0x4f,0x47,0x30,0x35,0x21,0xb1,0xa2,0xaf,0x1a,
801 0x62,0x3c,0x2b,0xd9,0x8e,0xaa,0x2a,0x07,0x7b,0xd8,0x18,0xb3,0x5c,0x7b,0xe2,
802 0x9d,0xa5,0x6f,0xfe,0x3c,0x89,0xad };
803 static const BYTE iTunesCert2[] = {
804 0x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
805 0x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75,
806 0xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
807 0x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
808 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
809 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,
810 0x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,
811 0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,
812 0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,
813 0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x34,0x30,
814 0x37,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30,
815 0x37,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,
816 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,
817 0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
818 0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b,
819 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,
820 0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,
821 0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,
822 0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,
823 0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,
824 0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,
825 0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,
826 0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,0x53,0x69,
827 0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,0x20,0x43,0x41,0x30,0x82,
828 0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,
829 0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,
830 0x00,0xbe,0xbc,0xee,0xbc,0x7e,0xef,0x83,0xeb,0xe0,0x37,0x4f,0xfb,0x03,0x10,
831 0x38,0xbe,0x08,0xd2,0x8c,0x7d,0x9d,0xfa,0x92,0x7f,0x19,0x0c,0xc2,0x6b,0xee,
832 0x42,0x52,0x8c,0xde,0xd3,0x1c,0x48,0x13,0x25,0xea,0xc1,0x63,0x7a,0xf9,0x51,
833 0x65,0xee,0xd3,0xaa,0x3b,0xf5,0xf0,0x94,0x9c,0x2b,0xfb,0xf2,0x66,0xd4,0x24,
834 0xda,0xf7,0xf5,0x9f,0x6e,0x19,0x39,0x36,0xbc,0xd0,0xa3,0x76,0x08,0x1e,0x22,
835 0x27,0x24,0x6c,0x38,0x91,0x27,0xe2,0x84,0x49,0xae,0x1b,0x8a,0xa1,0xfd,0x25,
836 0x82,0x2c,0x10,0x30,0xe8,0x71,0xab,0x28,0xe8,0x77,0x4a,0x51,0xf1,0xec,0xcd,
837 0xf8,0xf0,0x54,0xd4,0x6f,0xc0,0xe3,0x6d,0x0a,0x8f,0xd9,0xd8,0x64,0x8d,0x63,
838 0xb2,0x2d,0x4e,0x27,0xf6,0x85,0x0e,0xfe,0x6d,0xe3,0x29,0x99,0xe2,0x85,0x47,
839 0x7c,0x2d,0x86,0x7f,0xe8,0x57,0x8f,0xad,0x67,0xc2,0x33,0x32,0x91,0x13,0x20,
840 0xfc,0xa9,0x23,0x14,0x9a,0x6d,0xc2,0x84,0x4b,0x76,0x68,0x04,0xd5,0x71,0x2c,
841 0x5d,0x21,0xfa,0x88,0x0d,0x26,0xfd,0x1f,0x2d,0x91,0x2b,0xe7,0x01,0x55,0x4d,
842 0xf2,0x6d,0x35,0x28,0x82,0xdf,0xd9,0x6b,0x5c,0xb6,0xd6,0xd9,0xaa,0x81,0xfd,
843 0x5f,0xcd,0x83,0xba,0x63,0x9d,0xd0,0x22,0xfc,0xa9,0x3b,0x42,0x69,0xb2,0x8e,
844 0x3a,0xb5,0xbc,0xb4,0x9e,0x0f,0x5e,0xc4,0xea,0x2c,0x82,0x8b,0x28,0xfd,0x53,
845 0x08,0x96,0xdd,0xb5,0x01,0x20,0xd1,0xf9,0xa5,0x18,0xe7,0xc0,0xee,0x51,0x70,
846 0x37,0xe1,0xb6,0x05,0x48,0x52,0x48,0x6f,0x38,0xea,0xc3,0xe8,0x6c,0x7b,0x44,
847 0x84,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xa0,0x30,0x82,0x01,0x9c,
848 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
849 0x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,
850 0x3b,0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,
851 0x03,0x30,0x2a,0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
852 0x16,0x1c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,
853 0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,
854 0x30,0x31,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24,
855 0xa0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,
856 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63,
857 0x61,0x33,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16,
858 0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2b,
859 0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
860 0x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48,
861 0x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x01,0x30,0x29,0x06,
862 0x03,0x55,0x1d,0x11,0x04,0x22,0x30,0x20,0xa4,0x1e,0x30,0x1c,0x31,0x1a,0x30,
863 0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6c,0x61,0x73,0x73,0x33,0x43,
864 0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x34,0x33,0x30,0x1d,0x06,0x03,0x55,
865 0x1d,0x0e,0x04,0x16,0x04,0x14,0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,
866 0x36,0x7c,0x68,0xcf,0x5b,0x78,0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x81,0x80,0x06,
867 0x03,0x55,0x1d,0x23,0x04,0x79,0x30,0x77,0xa1,0x63,0xa4,0x61,0x30,0x5f,0x31,
868 0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,
869 0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
870 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,
871 0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6c,
872 0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,
873 0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,
874 0x72,0x69,0x74,0x79,0x82,0x10,0x70,0xba,0xe4,0x1d,0x10,0xd9,0x29,0x34,0xb6,
875 0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
876 0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xae,0x3a,0x17,0xb8,
877 0x4a,0x7b,0x55,0xfa,0x64,0x55,0xec,0x40,0xa4,0xed,0x49,0x41,0x90,0x99,0x9c,
878 0x89,0xbc,0xaf,0x2e,0x1d,0xca,0x78,0x23,0xf9,0x1c,0x19,0x0f,0x7f,0xeb,0x68,
879 0xbc,0x32,0xd9,0x88,0x38,0xde,0xdc,0x3f,0xd3,0x89,0xb4,0x3f,0xb1,0x82,0x96,
880 0xf1,0xa4,0x5a,0xba,0xed,0x2e,0x26,0xd3,0xde,0x7c,0x01,0x6e,0x00,0x0a,0x00,
881 0xa4,0x06,0x92,0x11,0x48,0x09,0x40,0xf9,0x1c,0x18,0x79,0x67,0x23,0x24,0xe0,
882 0xbb,0xd5,0xe1,0x50,0xae,0x1b,0xf5,0x0e,0xdd,0xe0,0x2e,0x81,0xcd,0x80,0xa3,
883 0x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88,
884 0x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f,
885 0x5e,0xf6,0x7a,0xb5 };
886 static const BYTE iTunesCert3[] = {
887 0x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
888 0x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6,
889 0x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
890 0x00,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
891 0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,
892 0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,
893 0x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
894 0x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,
895 0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,
896 0x73,0x20,0x6f,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,
897 0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
898 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,
899 0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,
900 0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,
901 0x6f,0x64,0x65,0x20,0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,
902 0x34,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x31,0x37,0x30,
903 0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x38,0x30,0x31,0x32,0x32,0x32,
904 0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,
905 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
906 0x08,0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x12,
907 0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,
908 0x69,0x6e,0x6f,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0a,0x14,0x14,0x41,
909 0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x2c,0x20,
910 0x49,0x6e,0x63,0x2e,0x31,0x3e,0x30,0x3c,0x06,0x03,0x55,0x04,0x0b,0x13,0x35,
911 0x44,0x69,0x67,0x69,0x74,0x61,0x6c,0x20,0x49,0x44,0x20,0x43,0x6c,0x61,0x73,
912 0x73,0x20,0x33,0x20,0x2d,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
913 0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x56,0x61,0x6c,0x69,0x64,
914 0x61,0x74,0x69,0x6f,0x6e,0x20,0x76,0x32,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,
915 0x04,0x03,0x14,0x14,0x41,0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,
916 0x74,0x65,0x72,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x30,0x81,0x9f,0x30,0x0d,0x06,
917 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,
918 0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xd3,0xab,0x3b,0x7f,0xec,0x48,0x84,
919 0xce,0xa8,0x1a,0x12,0xf3,0x3c,0x87,0xcb,0x24,0x58,0x96,0x02,0x87,0x66,0x49,
920 0xeb,0x89,0xee,0x79,0x44,0x70,0x8d,0xe7,0xd4,0x1f,0x30,0x92,0xc0,0x9c,0x35,
921 0x78,0xc0,0xaf,0x1c,0xb6,0x28,0xd3,0xe0,0xe0,0x9d,0xd3,0x49,0x76,0x73,0x57,
922 0x19,0x4d,0x8d,0x70,0x85,0x64,0x4d,0x1d,0xc6,0x02,0x3e,0xe5,0x2c,0x66,0x07,
923 0xd2,0x27,0x4b,0xd6,0xc8,0x3c,0x93,0xb6,0x15,0x0c,0xde,0x5b,0xd7,0x93,0xdd,
924 0xbe,0x85,0x62,0x34,0x17,0x8a,0x05,0x60,0xf0,0x8a,0x1c,0x5a,0x40,0x21,0x8d,
925 0x51,0x6c,0xb0,0x62,0xd8,0xb5,0xd4,0xf9,0xb1,0xd0,0x58,0x7a,0x7a,0x82,0x55,
926 0xb3,0xf9,0x53,0x71,0xde,0xd2,0xc9,0x37,0x8c,0xf6,0x5a,0x1f,0x2d,0xcd,0x7c,
927 0x67,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30,
928 0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06,0x03,0x55,
929 0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x40,0x06,0x03,
930 0x55,0x1d,0x1f,0x04,0x39,0x30,0x37,0x30,0x35,0xa0,0x33,0xa0,0x31,0x86,0x2f,
931 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,
932 0x34,0x2d,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,
933 0x63,0x6f,0x6d,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2e,0x63,
934 0x72,0x6c,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b,0x30,0x39,
935 0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,0x03,0x30,0x2a,
936 0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1c,0x68,
937 0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,
938 0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x30,0x13,0x06,
939 0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
940 0x07,0x03,0x03,0x30,0x75,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
941 0x04,0x69,0x30,0x67,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,
942 0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,
943 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x3f,0x06,
944 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x33,0x68,0x74,0x74,0x70,
945 0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,
946 0x61,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,
947 0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,0x61,0x2e,0x63,
948 0x65,0x72,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
949 0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,0x36,0x7c,0x68,0xcf,0x5b,0x78,
950 0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,
951 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x04,0x10,0x30,0x16,0x06,0x0a,0x2b,0x06,
952 0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x1b,0x04,0x08,0x30,0x06,0x01,0x01,0x00,
953 0x01,0x01,0xff,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
954 0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6a,0xa6,0x06,0xd0,0x33,0x18,0x64,
955 0xe2,0x69,0x82,0xee,0x6e,0x36,0x9e,0x9d,0x9a,0x0e,0x18,0xa8,0xac,0x9d,0x10,
956 0xed,0x01,0x3c,0xb9,0x61,0x04,0x62,0xf3,0x85,0x8f,0xcc,0x4f,0x2c,0x66,0x35,
957 0x54,0x25,0x45,0x8d,0x95,0x1c,0xd2,0x33,0xbe,0x2e,0xdd,0x7f,0x74,0xaf,0x03,
958 0x7b,0x86,0x63,0xb0,0xc9,0xe6,0xbd,0xc7,0x8e,0xde,0x03,0x18,0x98,0x82,0xc3,
959 0xbb,0xf8,0x15,0x99,0x1a,0xa9,0xdd,0xb9,0x5d,0xb9,0xbd,0x53,0x95,0x25,0x76,
960 0xfb,0x5c,0x53,0x90,0xea,0x01,0x0a,0xa0,0xb1,0xbf,0x09,0x1b,0x97,0x8f,0x40,
961 0xfa,0x85,0x12,0x74,0x01,0xdb,0xf6,0xdb,0x09,0xd6,0x5f,0x4f,0xd7,0x17,0xb4,
962 0xbf,0x9e,0x2f,0x86,0x52,0x5d,0x70,0x24,0x52,0x32,0x1e,0xa5,0x1d,0x39,0x8b,
963 0x66,0xf6,0xba,0x9b,0x69,0x8e,0x12,0x60,0xdb,0xb6,0xcf,0xe6,0x0d,0xd6,0x1c,
964 0x8f,0xd4,0x5b,0x4b,0x00,0xde,0x21,0x93,0xfb,0x6e,0xc7,0x3d,0xb4,0x66,0x0d,
965 0x29,0x0c,0x4e,0xe9,0x3f,0x94,0xd6,0xd6,0xdc,0xec,0xf8,0x53,0x3b,0x62,0xd5,
966 0x97,0x50,0x53,0x84,0x17,0xfe,0xe2,0xed,0x4c,0x23,0x0a,0x49,0xce,0x5b,0xe9,
967 0x70,0x31,0xc1,0x04,0x02,0x02,0x6c,0xb8,0x52,0xcd,0xc7,0x4e,0x70,0xb4,0x13,
968 0xd7,0xe0,0x92,0xba,0x44,0x1a,0x10,0x4c,0x6e,0x45,0xc6,0x86,0x04,0xc6,0x64,
969 0xd3,0x9c,0x6e,0xc1,0x9c,0xac,0x74,0x3d,0x77,0x06,0x5e,0x28,0x28,0x5c,0xf5,
970 0xe0,0x9c,0x19,0xd8,0xba,0x74,0x81,0x2d,0x67,0x77,0x93,0x8d,0xbf,0xd2,0x52,
971 0x00,0xe6,0xa5,0x38,0x4e,0x2e,0x73,0x66,0x7a };
972 static BYTE iTunesIssuer[] = {
973 0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
974 0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,
975 0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
976 0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,
977 0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
978 0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,
979 0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,
980 0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,0x73,
981 0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,
982 0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,
983 0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,
984 0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,
985 0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
986 0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,
987 0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,
989 static BYTE iTunesSerialNum[] = {
990 0x8d,0xf6,0x6a,0xdf,0xd2,0x40,0xfe,0xb6,0xa6,0x61,0x9b,0x9b,
991 0xe0,0xa0,0x1a,0x0f };
993 static void testFindCert(void)
996 PCCERT_CONTEXT context = NULL, subject;
998 CERT_INFO certInfo = { 0 };
999 CRYPT_HASH_BLOB blob;
1000 BYTE otherSerialNumber[] = { 2 };
1002 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1003 CERT_STORE_CREATE_NEW_FLAG, NULL);
1004 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1008 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1009 bigCert, sizeof(bigCert), CERT_STORE_ADD_NEW, NULL);
1010 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1012 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1013 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
1014 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1016 /* This has the same name as bigCert */
1017 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1018 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1019 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1023 context = CertFindCertificateInStore(NULL, 0, 0, 0, NULL, NULL);
1026 /* Check first cert's there, by issuer */
1027 certInfo.Subject.pbData = subjectName;
1028 certInfo.Subject.cbData = sizeof(subjectName);
1029 certInfo.SerialNumber.pbData = serialNum;
1030 certInfo.SerialNumber.cbData = sizeof(serialNum);
1031 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1032 CERT_FIND_ISSUER_NAME, &certInfo.Subject, NULL);
1033 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1037 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1038 CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
1039 ok(context != NULL, "Expected more than one cert\n");
1042 context = CertFindCertificateInStore(store, X509_ASN_ENCODING,
1043 0, CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
1044 ok(context == NULL, "Expected precisely two certs\n");
1048 /* Check second cert's there as well, by subject name */
1049 certInfo.Subject.pbData = subjectName2;
1050 certInfo.Subject.cbData = sizeof(subjectName2);
1051 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1052 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, NULL);
1053 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1057 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1058 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, context);
1059 ok(context == NULL, "Expected one cert only\n");
1062 /* Strange but true: searching for the subject cert requires you to set
1063 * the issuer, not the subject
1065 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1066 CERT_FIND_SUBJECT_CERT, &certInfo.Subject, NULL);
1067 ok(context == NULL, "Expected no certificate\n");
1068 certInfo.Subject.pbData = NULL;
1069 certInfo.Subject.cbData = 0;
1070 certInfo.Issuer.pbData = subjectName2;
1071 certInfo.Issuer.cbData = sizeof(subjectName2);
1072 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1073 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1074 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1078 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1079 CERT_FIND_SUBJECT_CERT, &certInfo.Subject, context);
1080 ok(context == NULL, "Expected one cert only\n");
1082 /* A non-matching serial number will not match. */
1083 certInfo.SerialNumber.pbData = otherSerialNumber;
1084 certInfo.SerialNumber.cbData = sizeof(otherSerialNumber);
1085 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1086 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1087 ok(context == NULL, "Expected no match\n");
1088 /* No serial number will not match */
1089 certInfo.SerialNumber.cbData = 0;
1090 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1091 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1092 ok(context == NULL, "Expected no match\n");
1093 /* A serial number still won't match if the name doesn't */
1094 certInfo.SerialNumber.pbData = serialNum;
1095 certInfo.SerialNumber.cbData = sizeof(serialNum);
1096 certInfo.Issuer.pbData = subjectName3;
1097 certInfo.Issuer.cbData = sizeof(subjectName3);
1098 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1099 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1100 ok(context == NULL, "Expected no match\n");
1102 /* The nice thing about hashes, they're unique */
1103 blob.pbData = bigCertHash;
1104 blob.cbData = sizeof(bigCertHash);
1105 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1106 CERT_FIND_SHA1_HASH, &blob, NULL);
1107 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1111 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1112 CERT_FIND_SHA1_HASH, &certInfo.Subject, context);
1113 ok(context == NULL, "Expected one cert only\n");
1116 CertCloseStore(store, 0);
1118 /* Another subject cert search, using iTunes's certs */
1119 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1120 CERT_STORE_CREATE_NEW_FLAG, NULL);
1121 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1122 iTunesCert0, sizeof(iTunesCert0), CERT_STORE_ADD_NEW, NULL);
1123 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1125 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1126 iTunesCert1, sizeof(iTunesCert1), CERT_STORE_ADD_NEW, NULL);
1127 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1129 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1130 iTunesCert2, sizeof(iTunesCert2), CERT_STORE_ADD_NEW, NULL);
1131 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1133 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1134 iTunesCert3, sizeof(iTunesCert3), CERT_STORE_ADD_NEW, &subject);
1135 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1138 /* The certInfo's issuer does not match any subject, but the serial
1139 * number does match a cert whose issuer matches certInfo's issuer.
1140 * This yields a match.
1142 certInfo.SerialNumber.cbData = sizeof(iTunesSerialNum);
1143 certInfo.SerialNumber.pbData = iTunesSerialNum;
1144 certInfo.Issuer.cbData = sizeof(iTunesIssuer);
1145 certInfo.Issuer.pbData = iTunesIssuer;
1146 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1147 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1148 ok(context != NULL, "Expected a match\n");
1151 ret = CertCompareCertificateName(context->dwCertEncodingType,
1152 &certInfo.Issuer, &context->pCertInfo->Subject);
1153 ok(!ret, "Expected subject name not to match\n");
1154 ret = CertCompareCertificateName(context->dwCertEncodingType,
1155 &certInfo.Issuer, &context->pCertInfo->Issuer);
1156 ok(ret, "Expected issuer name to match\n");
1157 ret = CertCompareIntegerBlob(&certInfo.SerialNumber,
1158 &context->pCertInfo->SerialNumber);
1159 ok(ret, "Expected serial number to match\n");
1160 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1161 CERT_FIND_SUBJECT_CERT, &certInfo, context);
1162 ok(context == NULL, "Expected one cert only\n");
1165 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1166 CERT_FIND_ISSUER_OF, subject, NULL);
1167 ok(context != NULL, "Expected an issuer\n");
1170 PCCERT_CONTEXT none = CertFindCertificateInStore(store,
1171 X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_OF, context, NULL);
1173 ok(!none, "Expected no parent of issuer\n");
1174 CertFreeCertificateContext(context);
1176 CertFreeCertificateContext(subject);
1177 CertCloseStore(store, 0);
1180 static void testGetSubjectCert(void)
1183 PCCERT_CONTEXT context1, context2;
1184 CERT_INFO info = { 0 };
1187 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1188 CERT_STORE_CREATE_NEW_FLAG, NULL);
1189 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1193 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1194 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1195 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1197 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1198 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, &context1);
1199 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1201 ok(context1 != NULL, "Expected a context\n");
1202 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1203 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1204 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1207 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1209 ok(!context2 && GetLastError() == E_INVALIDARG,
1210 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1211 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1213 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1214 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1215 info.SerialNumber.cbData = sizeof(serialNum);
1216 info.SerialNumber.pbData = serialNum;
1217 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1219 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1220 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1221 info.Issuer.cbData = sizeof(subjectName2);
1222 info.Issuer.pbData = subjectName2;
1223 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1225 ok(context2 != NULL,
1226 "CertGetSubjectCertificateFromStore failed: %08x\n", GetLastError());
1227 /* Not only should this find a context, but it should be the same
1228 * (same address) as context1.
1230 ok(context1 == context2, "Expected identical context addresses\n");
1231 CertFreeCertificateContext(context2);
1233 CertFreeCertificateContext(context1);
1234 CertCloseStore(store, 0);
1237 /* This expires in 1970 or so */
1238 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
1239 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
1240 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
1241 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1242 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1243 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1244 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
1245 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
1246 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1247 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1248 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1249 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
1250 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
1251 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
1252 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
1253 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
1254 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
1255 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
1256 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
1257 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
1258 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
1259 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
1260 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
1261 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
1262 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
1264 /* This expires in 2036 or so */
1265 static const BYTE childOfExpired[] = { 0x30, 0x81, 0xcc, 0x30, 0x78, 0xa0,
1266 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
1267 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d,
1268 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63,
1269 0x40, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e,
1270 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x35, 0x30, 0x35,
1271 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x35,
1272 0x30, 0x35, 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x30, 0x15, 0x31, 0x13,
1273 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e,
1274 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03,
1275 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
1276 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x20, 0x3b, 0xdb, 0x4d, 0x67, 0x50,
1277 0xec, 0x73, 0x9d, 0xf9, 0x85, 0x5d, 0x18, 0xe9, 0xb4, 0x98, 0xe3, 0x31, 0xb7,
1278 0x03, 0x0b, 0xc0, 0x39, 0x93, 0x56, 0x81, 0x0a, 0xfc, 0x78, 0xa8, 0x29, 0x42,
1279 0x5f, 0x69, 0xfb, 0xbc, 0x5b, 0xf2, 0xa6, 0x2a, 0xbe, 0x91, 0x2c, 0xfc, 0x89,
1280 0x69, 0x15, 0x18, 0x58, 0xe5, 0x02, 0x75, 0xf7, 0x2a, 0xb6, 0xa9, 0xfb, 0x47,
1281 0x6a, 0x6e, 0x0a, 0x9b, 0xe9, 0xdc };
1285 * A chain with two issuers, only one of whose dates is valid.
1287 static const BYTE chain10_0[] = {
1288 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1289 0x4a,0x30,0x3a,0x42,0xa2,0x5a,0xb3,0x93,0x4d,0x94,0x06,0xad,0x6d,0x1c,0x34,
1290 0xe6,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1291 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1292 0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1293 0x30,0x5a,0x17,0x0d,0x30,0x36,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1294 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1295 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1296 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1297 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1298 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1299 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1300 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1301 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1302 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1303 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1304 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1305 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1306 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1307 0x81,0x00,0x85,0x6e,0x35,0x2f,0x2c,0x51,0x4f,0xd6,0x2a,0xe4,0x9e,0xd0,0x4b,
1308 0xe6,0x90,0xfd,0xf7,0x20,0xad,0x76,0x3f,0x93,0xea,0x7f,0x0d,0x1f,0xb3,0x8e,
1309 0xfd,0xe0,0xe1,0xd6,0xd7,0x9c,0x7d,0x46,0x6b,0x15,0x5c,0xe6,0xc9,0x62,0x3b,
1310 0x70,0x4a,0x4b,0xb2,0x82,0xe3,0x55,0x0c,0xc4,0x90,0x44,0x06,0x6c,0x86,0x1c,
1311 0x6d,0x47,0x12,0xda,0x33,0x95,0x5d,0x98,0x43,0xcb,0x7c,0xfa,0x2b,0xee,0xc4,
1312 0x2d,0xc8,0x95,0x33,0x89,0x08,0x3f,0x9f,0x87,0xea,0x20,0x04,0xaf,0x58,0x4b,
1313 0x9d,0xc0,0x7c,0x0a,0x1b,0x05,0x31,0x3b,0xbb,0x13,0x58,0x2e,0x3f,0x61,0x6b,
1314 0x10,0xb4,0xeb,0xb9,0x1a,0x30,0xfd,0xea,0xca,0x29,0x99,0x5f,0x42,0x2b,0x00,
1315 0xb0,0x08,0xc3,0xf0,0xb6,0xd6,0x6b,0xf9,0x35,0x95 };
1316 static const BYTE chain10_1[] = {
1317 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1318 0xbf,0x99,0x4f,0x14,0x03,0x77,0x44,0xb8,0x49,0x02,0x70,0xa1,0xb8,0x9c,0xa7,
1319 0x24,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1320 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1321 0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1322 0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1323 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1324 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1325 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1326 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1327 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1328 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1329 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1330 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1331 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1332 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1333 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1334 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1335 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1336 0x81,0x00,0xa8,0xec,0x8c,0x34,0xe7,0x2c,0xdf,0x75,0x87,0xc4,0xf7,0xda,0x71,
1337 0x72,0x29,0xb2,0x48,0xa8,0x2a,0xec,0x7b,0x7d,0x19,0xb9,0x5f,0x1d,0xd9,0x91,
1338 0x2b,0xc4,0x28,0x7e,0xd6,0xb5,0x91,0x69,0xa5,0x8a,0x1a,0x1f,0x97,0x98,0x46,
1339 0x9d,0xdf,0x12,0xf6,0x45,0x62,0xad,0x60,0xb6,0xba,0xb0,0xfd,0xf5,0x9f,0xc6,
1340 0x98,0x05,0x4f,0x4d,0x48,0xdc,0xee,0x69,0xbe,0xb8,0xc4,0xc4,0xd7,0x1b,0xb1,
1341 0x1f,0x64,0xd6,0x45,0xa7,0xdb,0xb3,0x87,0x63,0x0f,0x54,0xe1,0x3a,0x6b,0x57,
1342 0x36,0xd7,0x68,0x65,0xcf,0xda,0x57,0x8d,0xcd,0x84,0x75,0x47,0x26,0x2c,0xef,
1343 0x1e,0x8f,0xc7,0x3b,0xee,0x5d,0x03,0xa6,0xdf,0x3a,0x20,0xb2,0xcc,0xc9,0x09,
1344 0x2c,0xfe,0x2b,0x79,0xb0,0xca,0x2c,0x9a,0x81,0x6b };
1345 static const BYTE chain7_1[] = {
1346 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
1347 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,
1348 0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,
1349 0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,
1350 0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,
1351 0x35,0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,
1352 0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,
1353 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,
1354 0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,
1355 0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,
1356 0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,
1357 0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,
1358 0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,
1359 0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,
1360 0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,
1361 0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,
1362 0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,
1363 0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1364 0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9f,0x69,0xfd,0x26,0xd5,0x4b,
1365 0xe0,0xab,0x12,0x21,0xb9,0xfc,0xf7,0xe0,0x0c,0x09,0x94,0xad,0x27,0xd7,0x9d,
1366 0xa3,0xcc,0x46,0x2a,0x25,0x9a,0x24,0xa7,0x31,0x58,0x78,0xf5,0xfc,0x30,0xe1,
1367 0x6d,0xfd,0x59,0xab,0xbe,0x69,0xa0,0xea,0xe3,0x7d,0x7a,0x7b,0xe5,0x85,0xeb,
1368 0x86,0x6a,0x84,0x3c,0x96,0x01,0x1a,0x70,0xa7,0xb8,0xcb,0xf2,0x11,0xe7,0x52,
1369 0x9c,0x58,0x2d,0xac,0x63,0xce,0x72,0x4b,0xad,0x62,0xa8,0x1d,0x75,0x96,0xe2,
1370 0x27,0xf5,0x6f,0xba,0x91,0xf8,0xf1,0xb0,0xbf,0x90,0x24,0x6d,0xba,0x5d,0xd7,
1371 0x39,0x63,0x3b,0x7c,0x04,0x5d,0x89,0x9d,0x1c,0xf2,0xf7,0xcc,0xdf,0x6e,0x8a,
1372 0x43,0xa9,0xdd,0x86,0x05,0xa2,0xf3,0x22,0x2d,0x1e,0x70,0xa1,0x59,0xd7,0xa5,
1375 static void testGetIssuerCert(void)
1378 PCCERT_CONTEXT parent, child, cert1, cert2;
1379 DWORD flags = 0xffffffff;
1380 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1381 CERT_STORE_CREATE_NEW_FLAG, NULL);
1383 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1385 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1386 expiredCert, sizeof(expiredCert), CERT_STORE_ADD_ALWAYS, NULL);
1387 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1390 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1391 childOfExpired, sizeof(childOfExpired), CERT_STORE_ADD_ALWAYS, &child);
1392 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1396 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, NULL);
1397 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, NULL);
1399 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, &flags);
1400 ok(!parent && GetLastError() == E_INVALIDARG,
1401 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1402 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, &flags);
1403 ok(!parent && GetLastError() == E_INVALIDARG,
1404 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1405 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1406 ok(!parent && GetLastError() == E_INVALIDARG,
1407 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1408 /* Confusing: the caller cannot set either of the
1409 * CERT_STORE_NO_*_FLAGs, as these are not checks,
1412 flags = CERT_STORE_NO_CRL_FLAG | CERT_STORE_NO_ISSUER_FLAG;
1413 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1414 ok(!parent && GetLastError() == E_INVALIDARG,
1415 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1416 /* Perform no checks */
1418 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1419 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1422 CertFreeCertificateContext(parent);
1423 /* Check revocation and signature only */
1424 flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG;
1425 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1426 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1428 /* Confusing: CERT_STORE_REVOCATION_FLAG succeeds when there is no CRL by
1429 * setting CERT_STORE_NO_CRL_FLAG.
1431 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
1432 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
1435 CertFreeCertificateContext(parent);
1436 /* Checking time validity is not productive, because while most Windows
1437 * versions return 0 (time valid) because the child is not expired,
1438 * Windows 2003 SP1 returns that it is expired. Thus the range of
1439 * possibilities is covered, and a test verifies nothing.
1442 CertFreeCertificateContext(child);
1443 CertCloseStore(store, 0);
1446 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1447 CERT_STORE_CREATE_NEW_FLAG, NULL);
1448 /* With only the child certificate, no issuer will be found */
1449 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1450 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1451 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1452 ok(parent == NULL, "Expected no issuer\n");
1453 /* Adding an issuer allows one (and only one) issuer to be found */
1454 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1455 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert1);
1456 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1457 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1458 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1459 ok(parent == NULL, "Expected only one issuer\n");
1460 /* Adding a second issuer allows two issuers to be found - and the second
1461 * issuer is found before the first, implying certs are added to the head
1464 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1465 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert2);
1466 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1467 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1468 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1469 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1470 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1471 ok(parent == NULL, "Expected no more than two issuers\n");
1472 CertFreeCertificateContext(child);
1473 CertFreeCertificateContext(cert1);
1474 CertFreeCertificateContext(cert2);
1475 CertCloseStore(store, 0);
1477 /* Repeat the test, reversing the order in which issuers are added,
1478 * to show it's order-dependent.
1480 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1481 CERT_STORE_CREATE_NEW_FLAG, NULL);
1482 /* With only the child certificate, no issuer will be found */
1483 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1484 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1485 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1486 ok(parent == NULL, "Expected no issuer\n");
1487 /* Adding an issuer allows one (and only one) issuer to be found */
1488 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1489 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert1);
1490 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1491 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1492 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1493 ok(parent == NULL, "Expected only one issuer\n");
1494 /* Adding a second issuer allows two issuers to be found - and the second
1495 * issuer is found before the first, implying certs are added to the head
1498 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1499 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert2);
1500 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1501 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1502 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1503 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1504 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1505 ok(parent == NULL, "Expected no more than two issuers\n");
1506 CertFreeCertificateContext(child);
1507 CertFreeCertificateContext(cert1);
1508 CertFreeCertificateContext(cert2);
1509 CertCloseStore(store, 0);
1512 static void testCryptHashCert(void)
1514 static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b,
1515 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07,
1517 static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee,
1518 0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8,
1520 static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:";
1523 DWORD hashLen = sizeof(hash);
1525 /* NULL buffer and nonzero length crashes
1526 ret = CryptHashCertificate(0, 0, 0, NULL, size, hash, &hashLen);
1527 empty hash length also crashes
1528 ret = CryptHashCertificate(0, 0, 0, buf, size, hash, NULL);
1530 /* Test empty hash */
1531 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), NULL,
1533 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1534 ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen);
1535 /* Test with empty buffer */
1536 ret = CryptHashCertificate(0, 0, 0, NULL, 0, hash, &hashLen);
1537 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1538 ok(!memcmp(hash, emptyHash, sizeof(emptyHash)),
1539 "Unexpected hash of nothing\n");
1540 /* Test a known value */
1541 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), hash,
1543 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1544 ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
1547 static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen,
1548 const BYTE *sig, unsigned int sigLen)
1551 BOOL ret = CryptCreateHash(csp, CALG_SHA1, 0, 0, &hash);
1553 ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
1557 DWORD mySigSize = sizeof(mySig);
1559 ret = CryptHashData(hash, toSign, toSignLen, 0);
1560 ok(ret, "CryptHashData failed: %08x\n", GetLastError());
1561 /* use the A variant so the test can run on Win9x */
1562 ret = CryptSignHashA(hash, AT_SIGNATURE, NULL, 0, mySig, &mySigSize);
1563 ok(ret, "CryptSignHash failed: %08x\n", GetLastError());
1566 ok(mySigSize == sigLen, "Expected sig length %d, got %d\n",
1568 ok(!memcmp(mySig, sig, sigLen), "Unexpected signature\n");
1570 CryptDestroyHash(hash);
1574 /* Tests signing the certificate described by toBeSigned with the CSP passed in,
1575 * using the algorithm with OID sigOID. The CSP is assumed to be empty, and a
1576 * keyset named AT_SIGNATURE will be added to it. The signing key will be
1577 * stored in *key, and the signature will be stored in sig. sigLen should be
1578 * at least 64 bytes.
1580 static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1581 LPCSTR sigOID, HCRYPTKEY *key, BYTE *sig, DWORD *sigLen)
1585 CRYPT_ALGORITHM_IDENTIFIER algoID = { NULL, { 0, NULL } };
1588 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1589 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, &size);
1590 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1591 NULL, NULL, NULL, &size);
1593 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1594 &algoID, NULL, NULL, &size);
1595 ok(!ret && GetLastError() == NTE_BAD_ALGID,
1596 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1597 algoID.pszObjId = (LPSTR)sigOID;
1598 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1599 &algoID, NULL, NULL, &size);
1600 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1601 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1603 ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData,
1604 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1605 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1606 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1609 /* No keys exist in the new CSP yet.. */
1610 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1611 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1612 ok(!ret && (GetLastError() == NTE_BAD_KEYSET || GetLastError() ==
1613 NTE_NO_KEY), "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %08x\n",
1615 ret = CryptGenKey(csp, AT_SIGNATURE, 0, key);
1616 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1619 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1620 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1621 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1622 ok(size <= *sigLen, "Expected size <= %d, got %d\n", *sigLen, size);
1625 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1626 toBeSigned->cbData, &algoID, NULL, sig, &size);
1627 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1631 verifySig(csp, toBeSigned->pbData, toBeSigned->cbData, sig,
1638 static void testVerifyCertSig(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1639 LPCSTR sigOID, const BYTE *sig, DWORD sigLen)
1641 CERT_SIGNED_CONTENT_INFO info;
1646 if (!pCryptVerifyCertificateSignatureEx)
1648 skip("no CryptVerifyCertificateSignatureEx support\n");
1651 if (!pCryptEncodeObjectEx)
1653 skip("no CryptEncodeObjectEx support\n");
1656 ret = pCryptVerifyCertificateSignatureEx(0, 0, 0, NULL, 0, NULL, 0, NULL);
1657 ok(!ret && GetLastError() == E_INVALIDARG,
1658 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1659 ret = pCryptVerifyCertificateSignatureEx(csp, 0, 0, NULL, 0, NULL, 0, NULL);
1660 ok(!ret && GetLastError() == E_INVALIDARG,
1661 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1662 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 0, NULL, 0,
1664 ok(!ret && GetLastError() == E_INVALIDARG,
1665 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1667 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1668 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, NULL, 0, NULL, 0, NULL);
1670 info.ToBeSigned.cbData = toBeSigned->cbData;
1671 info.ToBeSigned.pbData = toBeSigned->pbData;
1672 info.SignatureAlgorithm.pszObjId = (LPSTR)sigOID;
1673 info.SignatureAlgorithm.Parameters.cbData = 0;
1674 info.Signature.cbData = sigLen;
1675 info.Signature.pbData = (BYTE *)sig;
1676 info.Signature.cUnusedBits = 0;
1677 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT, &info,
1678 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&cert, &size);
1679 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1682 CRYPT_DATA_BLOB certBlob = { 0, NULL };
1683 PCERT_PUBLIC_KEY_INFO pubKeyInfo = NULL;
1685 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1686 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1687 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
1688 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
1689 certBlob.cbData = 1;
1690 certBlob.pbData = (void *)0xdeadbeef;
1691 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1692 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1693 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1694 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1695 certBlob.cbData = size;
1696 certBlob.pbData = cert;
1697 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1698 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1699 ok(!ret && GetLastError() == E_INVALIDARG,
1700 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1701 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1702 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1703 CRYPT_VERIFY_CERT_SIGN_ISSUER_NULL, NULL, 0, NULL);
1704 ok(!ret && GetLastError() == E_INVALIDARG,
1705 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1707 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1708 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1709 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, NULL, 0, NULL);
1711 CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
1712 (LPSTR)sigOID, 0, NULL, NULL, &size);
1713 pubKeyInfo = HeapAlloc(GetProcessHeap(), 0, size);
1716 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
1717 X509_ASN_ENCODING, (LPSTR)sigOID, 0, NULL, pubKeyInfo, &size);
1718 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
1721 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1722 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1723 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pubKeyInfo, 0, NULL);
1724 ok(ret, "CryptVerifyCertificateSignatureEx failed: %08x\n",
1727 HeapFree(GetProcessHeap(), 0, pubKeyInfo);
1733 static BYTE emptyCert[] = { 0x30, 0x00 };
1735 static void testCertSigs(void)
1738 CRYPT_DATA_BLOB toBeSigned = { sizeof(emptyCert), emptyCert };
1742 DWORD sigSize = sizeof(sig);
1744 /* Just in case a previous run failed, delete this thing */
1745 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1746 CRYPT_DELETEKEYSET);
1747 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1749 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1751 testSignCert(csp, &toBeSigned, szOID_RSA_SHA1RSA, &key, sig, &sigSize);
1752 testVerifyCertSig(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize);
1754 CryptDestroyKey(key);
1755 CryptReleaseContext(csp, 0);
1756 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1757 CRYPT_DELETEKEYSET);
1760 static const BYTE md5SignedEmptyCert[] = {
1761 0x30,0x56,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1762 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
1763 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
1764 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1765 0x0d,0x02,0x05,0x05,0x00,0x03,0x11,0x00,0xfb,0x0f,0x66,0x82,0x66,0xd9,0xe5,0xf8,
1766 0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
1767 static const BYTE md5SignedEmptyCertNoNull[] = {
1768 0x30,0x54,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1769 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
1770 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
1771 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1772 0x0d,0x02,0x05,0x03,0x11,0x00,0x04,0xd9,0xa5,0xe1,0x2b,0x55,0xa2,0xd8,0xf8,0xe5,
1773 0xd9,0x66,0x82,0x66,0x0f,0xfb };
1775 static void testSignAndEncodeCert(void)
1777 static char oid_rsa_md5rsa[] = szOID_RSA_MD5RSA;
1778 static char oid_rsa_md5[] = szOID_RSA_MD5;
1781 CRYPT_ALGORITHM_IDENTIFIER algID = { 0 };
1782 CERT_INFO info = { 0 };
1785 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1787 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1790 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, &algID, NULL, NULL,
1792 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1793 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1794 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, NULL, NULL,
1795 &algID, NULL, NULL, &size);
1796 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1797 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1798 ret = CryptSignAndEncodeCertificate(0, 0, 0, X509_CERT_TO_BE_SIGNED, NULL,
1799 &algID, NULL, NULL, &size);
1800 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1801 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1802 /* Crashes on some win9x boxes */
1805 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1806 X509_CERT_TO_BE_SIGNED, NULL, &algID, NULL, NULL, &size);
1807 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1808 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1811 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1812 X509_CERT_TO_BE_SIGNED, &info, NULL, NULL, NULL, &size);
1814 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1815 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1816 ok(!ret && GetLastError() == NTE_BAD_ALGID,
1817 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1818 algID.pszObjId = oid_rsa_md5rsa;
1819 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1820 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1821 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1822 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1824 algID.pszObjId = oid_rsa_md5;
1825 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1826 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1827 /* oid_rsa_md5 not present in some win2k */
1830 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
1834 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1835 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, buf, &size);
1836 ok(ret, "CryptSignAndEncodeCertificate failed: %08x\n",
1838 /* Tricky: because the NULL parameters may either be omitted or
1839 * included as an asn.1-encoded NULL (0x05,0x00), two different
1840 * values are allowed.
1842 ok(size == sizeof(md5SignedEmptyCert) ||
1843 size == sizeof(md5SignedEmptyCertNoNull), "Unexpected size %d\n",
1845 if (size == sizeof(md5SignedEmptyCert))
1846 ok(!memcmp(buf, md5SignedEmptyCert, size),
1847 "Unexpected value\n");
1848 else if (size == sizeof(md5SignedEmptyCertNoNull))
1849 ok(!memcmp(buf, md5SignedEmptyCertNoNull, size),
1850 "Unexpected value\n");
1851 HeapFree(GetProcessHeap(), 0, buf);
1856 static void testCreateSelfSignCert(void)
1858 PCCERT_CONTEXT context;
1859 CERT_NAME_BLOB name = { sizeof(subjectName), subjectName };
1863 CRYPT_KEY_PROV_INFO info;
1865 if (!pCertCreateSelfSignCertificate)
1867 skip("CertCreateSelfSignCertificate() is not available\n");
1872 context = pCertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL,
1874 * Calling this with no first parameter creates a new key container, which
1875 * lasts beyond the test, so I don't test that. Nb: the generated key
1877 context = pCertCreateSelfSignCertificate(0, &name, 0, NULL, NULL, NULL, NULL,
1882 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1883 CRYPT_DELETEKEYSET);
1884 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1886 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1888 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1890 ok(!context && GetLastError() == NTE_NO_KEY,
1891 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1892 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
1893 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1896 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1898 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1903 PCRYPT_KEY_PROV_INFO info;
1905 /* The context must have a key provider info property */
1906 ret = CertGetCertificateContextProperty(context,
1907 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1908 ok(ret && size, "Expected non-zero key provider info\n");
1911 info = HeapAlloc(GetProcessHeap(), 0, size);
1914 ret = CertGetCertificateContextProperty(context,
1915 CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1916 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1920 /* Sanity-check the key provider */
1921 ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1922 "Unexpected key container\n");
1923 ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1924 "Unexpected provider\n");
1925 ok(info->dwKeySpec == AT_SIGNATURE,
1926 "Expected AT_SIGNATURE, got %d\n", info->dwKeySpec);
1928 HeapFree(GetProcessHeap(), 0, info);
1932 CertFreeCertificateContext(context);
1935 CryptDestroyKey(key);
1938 CryptReleaseContext(csp, 0);
1939 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1940 CRYPT_DELETEKEYSET);
1942 /* do the same test with AT_KEYEXCHANGE and key info*/
1943 memset(&info,0,sizeof(info));
1944 info.dwProvType = PROV_RSA_FULL;
1945 info.dwKeySpec = AT_KEYEXCHANGE;
1946 info.pwszProvName = (LPWSTR) MS_DEF_PROV_W;
1947 info.pwszContainerName = cspNameW;
1948 context = pCertCreateSelfSignCertificate(0, &name, 0, &info, NULL, NULL,
1950 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1955 PCRYPT_KEY_PROV_INFO info;
1957 /* The context must have a key provider info property */
1958 ret = CertGetCertificateContextProperty(context,
1959 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1960 ok(ret && size, "Expected non-zero key provider info\n");
1963 info = HeapAlloc(GetProcessHeap(), 0, size);
1966 ret = CertGetCertificateContextProperty(context,
1967 CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1968 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1972 /* Sanity-check the key provider */
1973 ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1974 "Unexpected key container\n");
1975 ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1976 "Unexpected provider\n");
1977 ok(info->dwKeySpec == AT_KEYEXCHANGE,
1978 "Expected AT_KEYEXCHANGE, got %d\n", info->dwKeySpec);
1980 HeapFree(GetProcessHeap(), 0, info);
1984 CertFreeCertificateContext(context);
1987 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1988 CRYPT_DELETEKEYSET);
1991 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
1992 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
1994 static void testKeyUsage(void)
1997 PCCERT_CONTEXT context;
2000 /* Test base cases */
2001 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, NULL);
2002 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2003 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2005 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
2006 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2007 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2009 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
2010 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2011 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2013 ret = CertSetEnhancedKeyUsage(NULL, NULL);
2014 usage.cUsageIdentifier = 0;
2015 ret = CertSetEnhancedKeyUsage(NULL, &usage);
2017 /* Test with a cert with no enhanced key usage extension */
2018 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2020 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2024 static const char oid[] = "1.2.3.4";
2025 BYTE buf[sizeof(CERT_ENHKEY_USAGE) + 2 * (sizeof(LPSTR) + sizeof(oid))];
2026 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2028 ret = CertGetEnhancedKeyUsage(context, 0, NULL, NULL);
2029 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2030 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2032 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &size);
2035 /* Windows 2000, ME, or later: even though it succeeded, we expect
2036 * CRYPT_E_NOT_FOUND, which indicates there is no enhanced key
2037 * usage set for this cert (which implies it's valid for all uses.)
2039 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2040 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2041 ok(size == sizeof(CERT_ENHKEY_USAGE), "Wrong size %d\n", size);
2042 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2043 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2044 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2045 pUsage->cUsageIdentifier);
2049 /* Windows NT, 95, or 98: it fails, and the last error is
2050 * CRYPT_E_NOT_FOUND.
2052 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2053 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2055 /* I can add a usage identifier when no key usage has been set */
2056 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2057 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2060 ret = CertGetEnhancedKeyUsage(context,
2061 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2062 ok(ret && GetLastError() == 0,
2063 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2064 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2065 pUsage->cUsageIdentifier);
2066 if (pUsage->cUsageIdentifier)
2067 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2068 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2069 /* Now set an empty key usage */
2070 pUsage->cUsageIdentifier = 0;
2071 ret = CertSetEnhancedKeyUsage(context, pUsage);
2072 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2073 /* Shouldn't find it in the cert */
2075 ret = CertGetEnhancedKeyUsage(context,
2076 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2077 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2078 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2079 /* Should find it as an extended property */
2080 ret = CertGetEnhancedKeyUsage(context,
2081 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2082 ok(ret && GetLastError() == 0,
2083 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2084 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2085 pUsage->cUsageIdentifier);
2086 /* Should find it as either */
2087 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2088 ok(ret && GetLastError() == 0,
2089 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2090 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2091 pUsage->cUsageIdentifier);
2092 /* Add a usage identifier */
2093 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2094 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2097 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2098 ok(ret && GetLastError() == 0,
2099 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2100 ok(pUsage->cUsageIdentifier == 1, "Expected 1 identifier, got %d\n",
2101 pUsage->cUsageIdentifier);
2102 if (pUsage->cUsageIdentifier)
2103 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2104 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2105 /* Re-adding the same usage identifier succeeds, though it only adds
2106 * a duplicate usage identifier on versions prior to Vista
2108 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2109 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2112 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2113 ok(ret && GetLastError() == 0,
2114 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2115 ok(pUsage->cUsageIdentifier == 1 || pUsage->cUsageIdentifier == 2,
2116 "Expected 1 or 2 identifiers, got %d\n", pUsage->cUsageIdentifier);
2117 if (pUsage->cUsageIdentifier)
2118 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2119 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2120 if (pUsage->cUsageIdentifier >= 2)
2121 ok(!strcmp(pUsage->rgpszUsageIdentifier[1], oid),
2122 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[1]);
2123 /* Now set a NULL extended property--this deletes the property. */
2124 ret = CertSetEnhancedKeyUsage(context, NULL);
2125 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2126 SetLastError(0xbaadcafe);
2128 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2129 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2130 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2132 CertFreeCertificateContext(context);
2134 /* Now test with a cert with an enhanced key usage extension */
2135 context = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2136 sizeof(certWithUsage));
2137 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2142 DWORD bufSize = 0, i;
2144 /* The size may depend on what flags are used to query it, so I
2145 * realloc the buffer for each test.
2147 ret = CertGetEnhancedKeyUsage(context,
2148 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2149 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2150 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2153 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2155 /* Should find it in the cert */
2157 ret = CertGetEnhancedKeyUsage(context,
2158 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2159 ok(ret && GetLastError() == 0,
2160 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2161 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2162 pUsage->cUsageIdentifier);
2163 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2164 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2165 "Expected %s, got %s\n", keyUsages[i],
2166 pUsage->rgpszUsageIdentifier[i]);
2167 HeapFree(GetProcessHeap(), 0, buf);
2169 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2170 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2171 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2174 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2176 /* Should find it as either */
2178 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2179 /* In Windows, GetLastError returns CRYPT_E_NOT_FOUND not found
2180 * here, even though the return is successful and the usage id
2181 * count is positive. I don't enforce that here.
2184 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2185 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2186 pUsage->cUsageIdentifier);
2187 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2188 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2189 "Expected %s, got %s\n", keyUsages[i],
2190 pUsage->rgpszUsageIdentifier[i]);
2191 HeapFree(GetProcessHeap(), 0, buf);
2193 /* Shouldn't find it as an extended property */
2194 ret = CertGetEnhancedKeyUsage(context,
2195 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &size);
2196 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2197 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2198 /* Adding a usage identifier overrides the cert's usage!? */
2199 ret = CertAddEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2200 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2202 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2203 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2204 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2207 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2209 /* Should find it as either */
2211 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2213 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2214 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2215 pUsage->cUsageIdentifier);
2216 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], szOID_RSA_RSA),
2217 "Expected %s, got %s\n", szOID_RSA_RSA,
2218 pUsage->rgpszUsageIdentifier[0]);
2219 HeapFree(GetProcessHeap(), 0, buf);
2221 /* But querying the cert directly returns its usage */
2222 ret = CertGetEnhancedKeyUsage(context,
2223 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2224 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2225 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2228 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2231 ret = CertGetEnhancedKeyUsage(context,
2232 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2234 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2235 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2236 pUsage->cUsageIdentifier);
2237 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2238 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2239 "Expected %s, got %s\n", keyUsages[i],
2240 pUsage->rgpszUsageIdentifier[i]);
2241 HeapFree(GetProcessHeap(), 0, buf);
2243 /* And removing the only usage identifier in the extended property
2244 * results in the cert's key usage being found.
2246 ret = CertRemoveEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2247 ok(ret, "CertRemoveEnhancedKeyUsage failed: %08x\n", GetLastError());
2248 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2249 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2250 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2253 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2255 /* Should find it as either */
2257 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2259 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2260 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2261 pUsage->cUsageIdentifier);
2262 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2263 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2264 "Expected %s, got %s\n", keyUsages[i],
2265 pUsage->rgpszUsageIdentifier[i]);
2266 HeapFree(GetProcessHeap(), 0, buf);
2269 CertFreeCertificateContext(context);
2273 static const BYTE cert2WithUsage[] = {
2274 0x30,0x81,0x89,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2275 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2276 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2277 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2278 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2279 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2280 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x25,0x30,0x23,
2281 0x30,0x21,0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x17,0x30,0x15,0x06,
2282 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x2a,0x86,0x48,0x86,
2283 0xf7,0x0d,0x01,0x01,0x01 };
2285 static void testGetValidUsages(void)
2287 static const LPCSTR expectedOIDs[] = {
2288 "1.3.6.1.5.5.7.3.3",
2289 "1.3.6.1.5.5.7.3.2",
2290 "1.2.840.113549.1.1.1",
2292 static const LPCSTR expectedOIDs2[] = {
2293 "1.3.6.1.5.5.7.3.2",
2294 "1.2.840.113549.1.1.1",
2300 PCCERT_CONTEXT contexts[3];
2302 if (!pCertGetValidUsages)
2304 skip("CertGetValidUsages() is not available\n");
2309 ret = pCertGetValidUsages(0, NULL, NULL, NULL, NULL);
2310 ret = pCertGetValidUsages(0, NULL, NULL, NULL, &size);
2313 numOIDs = size = 0xdeadbeef;
2314 SetLastError(0xdeadbeef);
2315 ret = pCertGetValidUsages(1, &contexts[0], &numOIDs, NULL, &size);
2316 ok(ret, "CertGetValidUsages failed: %d\n", GetLastError());
2317 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2318 ok(size == 0, "Expected size 0, got %d\n", size);
2319 contexts[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2321 contexts[1] = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2322 sizeof(certWithUsage));
2323 contexts[2] = CertCreateCertificateContext(X509_ASN_ENCODING,
2324 cert2WithUsage, sizeof(cert2WithUsage));
2325 numOIDs = size = 0xdeadbeef;
2326 ret = pCertGetValidUsages(0, NULL, &numOIDs, NULL, &size);
2327 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2328 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2329 ok(size == 0, "Expected size 0, got %d\n", size);
2330 numOIDs = size = 0xdeadbeef;
2331 ret = pCertGetValidUsages(1, contexts, &numOIDs, NULL, &size);
2332 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2333 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2334 ok(size == 0, "Expected size 0, got %d\n", size);
2335 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, NULL, &size);
2336 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2337 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2338 ok(size, "Expected non-zero size\n");
2339 oids = HeapAlloc(GetProcessHeap(), 0, size);
2343 DWORD smallSize = 1;
2345 SetLastError(0xdeadbeef);
2346 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &smallSize);
2347 ok(!ret && GetLastError() == ERROR_MORE_DATA,
2348 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
2349 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2350 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2351 for (i = 0; i < numOIDs; i++)
2352 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2354 HeapFree(GetProcessHeap(), 0, oids);
2356 numOIDs = size = 0xdeadbeef;
2357 /* Oddly enough, this crashes when the number of contexts is not 1:
2358 ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2359 * but setting size to 0 allows it to succeed:
2362 ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2363 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2364 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2365 ok(size, "Expected non-zero size\n");
2366 oids = HeapAlloc(GetProcessHeap(), 0, size);
2371 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2372 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2373 for (i = 0; i < numOIDs; i++)
2374 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2376 HeapFree(GetProcessHeap(), 0, oids);
2378 numOIDs = 0xdeadbeef;
2380 ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, NULL, &size);
2381 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2382 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2383 ok(size, "Expected non-zero size\n");
2384 oids = HeapAlloc(GetProcessHeap(), 0, size);
2389 ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, oids, &size);
2390 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2391 for (i = 0; i < numOIDs; i++)
2392 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2394 HeapFree(GetProcessHeap(), 0, oids);
2396 numOIDs = 0xdeadbeef;
2398 ret = pCertGetValidUsages(3, contexts, &numOIDs, NULL, &size);
2399 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2400 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2401 ok(size, "Expected non-zero size\n");
2402 oids = HeapAlloc(GetProcessHeap(), 0, size);
2407 ret = pCertGetValidUsages(3, contexts, &numOIDs, oids, &size);
2408 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2409 for (i = 0; i < numOIDs; i++)
2410 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2412 HeapFree(GetProcessHeap(), 0, oids);
2414 CertFreeCertificateContext(contexts[0]);
2415 CertFreeCertificateContext(contexts[1]);
2416 CertFreeCertificateContext(contexts[2]);
2419 static void testCompareCertName(void)
2421 static BYTE bogus[] = { 1, 2, 3, 4 };
2422 static BYTE bogusPrime[] = { 0, 1, 2, 3, 4 };
2423 static BYTE emptyPrime[] = { 0x30, 0x00, 0x01 };
2425 CERT_NAME_BLOB blob1, blob2;
2428 ret = CertCompareCertificateName(0, NULL, NULL);
2430 /* An empty name checks against itself.. */
2431 blob1.pbData = emptyCert;
2432 blob1.cbData = sizeof(emptyCert);
2433 ret = CertCompareCertificateName(0, &blob1, &blob1);
2434 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2435 /* It doesn't have to be a valid encoded name.. */
2436 blob1.pbData = bogus;
2437 blob1.cbData = sizeof(bogus);
2438 ret = CertCompareCertificateName(0, &blob1, &blob1);
2439 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2440 /* Leading zeroes matter.. */
2441 blob2.pbData = bogusPrime;
2442 blob2.cbData = sizeof(bogusPrime);
2443 ret = CertCompareCertificateName(0, &blob1, &blob2);
2444 ok(!ret, "Expected failure\n");
2445 /* As do trailing extra bytes. */
2446 blob2.pbData = emptyPrime;
2447 blob2.cbData = sizeof(emptyPrime);
2448 ret = CertCompareCertificateName(0, &blob1, &blob2);
2449 ok(!ret, "Expected failure\n");
2452 static BYTE int1[] = { 0x88, 0xff, 0xff, 0xff };
2453 static BYTE int2[] = { 0x88, 0xff };
2454 static BYTE int3[] = { 0x23, 0xff };
2455 static BYTE int4[] = { 0x7f, 0x00 };
2456 static BYTE int5[] = { 0x7f };
2457 static BYTE int6[] = { 0x80, 0x00, 0x00, 0x00 };
2458 static BYTE int7[] = { 0x80, 0x00 };
2460 static struct IntBlobTest
2462 CRYPT_INTEGER_BLOB blob1;
2463 CRYPT_INTEGER_BLOB blob2;
2466 { { sizeof(int1), int1 }, { sizeof(int2), int2 }, TRUE },
2467 { { sizeof(int3), int3 }, { sizeof(int3), int3 }, TRUE },
2468 { { sizeof(int4), int4 }, { sizeof(int5), int5 }, TRUE },
2469 { { sizeof(int6), int6 }, { sizeof(int7), int7 }, TRUE },
2470 { { sizeof(int1), int1 }, { sizeof(int7), int7 }, FALSE },
2473 static void testCompareIntegerBlob(void)
2478 for (i = 0; i < sizeof(intBlobs) / sizeof(intBlobs[0]); i++)
2480 ret = CertCompareIntegerBlob(&intBlobs[i].blob1, &intBlobs[i].blob2);
2481 ok(ret == intBlobs[i].areEqual,
2482 "%d: expected blobs %s compare\n", i, intBlobs[i].areEqual ?
2487 static void testComparePublicKeyInfo(void)
2490 CERT_PUBLIC_KEY_INFO info1 = { { 0 } }, info2 = { { 0 } };
2491 static CHAR oid_rsa_rsa[] = szOID_RSA_RSA;
2492 static CHAR oid_rsa_sha1rsa[] = szOID_RSA_SHA1RSA;
2493 static CHAR oid_x957_dsa[] = szOID_X957_DSA;
2494 static BYTE bits1[] = { 1, 0 };
2495 static BYTE bits2[] = { 0 };
2496 static BYTE bits3[] = { 1 };
2497 static BYTE bits4[] = { 0x30,8, 2,1,0x81, 2,3,1,0,1 };
2498 static BYTE bits5[] = { 0x30,9, 2,2,0,0x81, 2,3,1,0,1 };
2499 static BYTE bits6[] = { 0x30,9, 2,2,0,0x82, 2,3,1,0,1 };
2502 ret = CertComparePublicKeyInfo(0, NULL, NULL);
2504 /* Empty public keys compare */
2505 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2506 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2507 /* Different OIDs appear to compare */
2508 info1.Algorithm.pszObjId = oid_rsa_rsa;
2509 info2.Algorithm.pszObjId = oid_rsa_sha1rsa;
2510 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2511 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2512 info2.Algorithm.pszObjId = oid_x957_dsa;
2513 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2514 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2515 info1.PublicKey.cbData = sizeof(bits1);
2516 info1.PublicKey.pbData = bits1;
2517 info1.PublicKey.cUnusedBits = 0;
2518 info2.PublicKey.cbData = sizeof(bits1);
2519 info2.PublicKey.pbData = bits1;
2520 info2.PublicKey.cUnusedBits = 0;
2521 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2522 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2523 info2.Algorithm.pszObjId = oid_rsa_rsa;
2524 info1.PublicKey.cbData = sizeof(bits4);
2525 info1.PublicKey.pbData = bits4;
2526 info1.PublicKey.cUnusedBits = 0;
2527 info2.PublicKey.cbData = sizeof(bits5);
2528 info2.PublicKey.pbData = bits5;
2529 info2.PublicKey.cUnusedBits = 0;
2530 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2531 ok(!ret, "CertComparePublicKeyInfo: as raw binary: keys should be unequal\n");
2532 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2533 ok(ret, "CertComparePublicKeyInfo: as ASN.1 encoded: keys should be equal\n");
2534 info1.PublicKey.cUnusedBits = 1;
2535 info2.PublicKey.cUnusedBits = 5;
2536 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2537 ok(ret, "CertComparePublicKeyInfo: ASN.1 encoding should ignore cUnusedBits\n");
2538 info1.PublicKey.cUnusedBits = 0;
2539 info2.PublicKey.cUnusedBits = 0;
2540 info1.PublicKey.cbData--; /* kill one byte, make ASN.1 encoded data invalid */
2541 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2542 ok(!ret, "CertComparePublicKeyInfo: comparing bad ASN.1 encoded key should fail\n");
2543 /* Even though they compare in their used bits, these do not compare */
2544 info1.PublicKey.cbData = sizeof(bits2);
2545 info1.PublicKey.pbData = bits2;
2546 info1.PublicKey.cUnusedBits = 0;
2547 info2.PublicKey.cbData = sizeof(bits3);
2548 info2.PublicKey.pbData = bits3;
2549 info2.PublicKey.cUnusedBits = 1;
2550 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2551 /* Simple (non-comparing) case */
2552 ok(!ret, "Expected keys not to compare\n");
2553 info2.PublicKey.cbData = sizeof(bits1);
2554 info2.PublicKey.pbData = bits1;
2555 info2.PublicKey.cUnusedBits = 0;
2556 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2557 ok(!ret, "Expected keys not to compare\n");
2558 /* ASN.1 encoded non-comparing case */
2559 info1.PublicKey.cbData = sizeof(bits5);
2560 info1.PublicKey.pbData = bits5;
2561 info1.PublicKey.cUnusedBits = 0;
2562 info2.PublicKey.cbData = sizeof(bits6);
2563 info2.PublicKey.pbData = bits6;
2564 info2.PublicKey.cUnusedBits = 0;
2565 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2566 ok(!ret, "CertComparePublicKeyInfo: different keys should be unequal\n");
2569 static void testHashPublicKeyInfo(void)
2572 CERT_PUBLIC_KEY_INFO info = { { 0 } };
2576 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, NULL);
2577 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, &info, NULL, NULL);
2579 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, &len);
2580 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2581 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2582 /* Crashes on some win9x boxes */
2585 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, NULL, NULL, &len);
2586 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2587 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2589 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, NULL, &len);
2590 ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2591 ok(len == 16, "Expected hash size 16, got %d\n", len);
2594 static const BYTE emptyHash[] = { 0xb8,0x51,0x3a,0x31,0x0e,0x9f,0x40,
2595 0x36,0x9c,0x92,0x45,0x1b,0x9d,0xc8,0xf9,0xf6 };
2598 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, buf,
2600 ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2601 ok(!memcmp(buf, emptyHash, len), "Unexpected hash\n");
2605 static const BYTE md5SignedEmptyCertHash[] = { 0xfb,0x0f,0x66,0x82,0x66,0xd9,
2606 0xe5,0xf8,0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
2608 static void testHashToBeSigned(void)
2617 ret = CryptHashToBeSigned(0, 0, NULL, 0, NULL, NULL);
2619 SetLastError(0xdeadbeef);
2620 ret = CryptHashToBeSigned(0, 0, NULL, 0, NULL, &size);
2622 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2623 "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
2624 SetLastError(0xdeadbeef);
2625 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, NULL, 0, NULL, &size);
2626 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2627 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2628 /* Can't sign anything: has to be asn.1 encoded, at least */
2629 SetLastError(0xdeadbeef);
2630 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, int1, sizeof(int1),
2632 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
2633 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2634 /* Can't be empty, either */
2635 SetLastError(0xdeadbeef);
2636 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, emptyCert,
2637 sizeof(emptyCert), NULL, &size);
2638 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2639 "expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2640 /* Signing a cert works */
2641 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert,
2642 sizeof(md5SignedEmptyCert), NULL, &size);
2643 ok(ret, "CryptHashToBeSigned failed: %08x\n", GetLastError());
2644 ok(size == sizeof(md5SignedEmptyCertHash), "unexpected size %d\n", size);
2645 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert,
2646 sizeof(md5SignedEmptyCert), hash, &size);
2647 ok(!memcmp(hash, md5SignedEmptyCertHash, size), "unexpected value\n");
2650 static void testCompareCert(void)
2652 CERT_INFO info1 = { 0 }, info2 = { 0 };
2656 ret = CertCompareCertificate(X509_ASN_ENCODING, NULL, NULL);
2659 /* Certs with the same issuer and serial number are equal, even if they
2660 * differ in other respects (like subject).
2662 info1.SerialNumber.pbData = serialNum;
2663 info1.SerialNumber.cbData = sizeof(serialNum);
2664 info1.Issuer.pbData = subjectName;
2665 info1.Issuer.cbData = sizeof(subjectName);
2666 info1.Subject.pbData = subjectName2;
2667 info1.Subject.cbData = sizeof(subjectName2);
2668 info2.SerialNumber.pbData = serialNum;
2669 info2.SerialNumber.cbData = sizeof(serialNum);
2670 info2.Issuer.pbData = subjectName;
2671 info2.Issuer.cbData = sizeof(subjectName);
2672 info2.Subject.pbData = subjectName;
2673 info2.Subject.cbData = sizeof(subjectName);
2674 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2675 ok(ret, "Expected certs to be equal\n");
2677 info2.Issuer.pbData = subjectName2;
2678 info2.Issuer.cbData = sizeof(subjectName2);
2679 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2680 ok(!ret, "Expected certs not to be equal\n");
2683 static void testVerifySubjectCert(void)
2687 PCCERT_CONTEXT context1, context2;
2690 ret = CertVerifySubjectCertificateContext(NULL, NULL, NULL);
2693 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2694 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2696 flags = CERT_STORE_NO_CRL_FLAG;
2697 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2698 ok(!ret && GetLastError() == E_INVALIDARG,
2699 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2702 context1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2704 ret = CertVerifySubjectCertificateContext(NULL, context1, &flags);
2705 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2707 ret = CertVerifySubjectCertificateContext(context1, NULL, &flags);
2708 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2710 ret = CertVerifySubjectCertificateContext(context1, context1, &flags);
2711 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2714 context2 = CertCreateCertificateContext(X509_ASN_ENCODING,
2715 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject));
2716 SetLastError(0xdeadbeef);
2717 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2718 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2720 flags = CERT_STORE_REVOCATION_FLAG;
2721 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2722 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2724 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
2725 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
2727 flags = CERT_STORE_SIGNATURE_FLAG;
2728 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2729 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2731 ok(flags == CERT_STORE_SIGNATURE_FLAG,
2732 "Expected CERT_STORE_SIGNATURE_FLAG, got %08x\n", flags);
2733 CertFreeCertificateContext(context2);
2735 CertFreeCertificateContext(context1);
2738 static void testVerifyRevocation(void)
2741 CERT_REVOCATION_STATUS status = { 0 };
2742 PCCERT_CONTEXT cert = CertCreateCertificateContext(X509_ASN_ENCODING,
2743 bigCert, sizeof(bigCert));
2746 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL);
2748 SetLastError(0xdeadbeef);
2749 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2750 ok(!ret && GetLastError() == E_INVALIDARG,
2751 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2752 status.cbSize = sizeof(status);
2753 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2754 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2755 ret = CertVerifyRevocation(0, 2, 0, NULL, 0, NULL, &status);
2756 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2757 ret = CertVerifyRevocation(2, 0, 0, NULL, 0, NULL, &status);
2758 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2759 SetLastError(0xdeadbeef);
2760 ret = CertVerifyRevocation(0, 0, 1, (void **)&cert, 0, NULL, &status);
2761 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2762 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2763 SetLastError(0xdeadbeef);
2764 ret = CertVerifyRevocation(0, 2, 1, (void **)&cert, 0, NULL, &status);
2765 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2766 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2768 CertFreeCertificateContext(cert);
2771 static BYTE privKey[] = {
2772 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
2773 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
2774 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
2775 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
2776 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
2777 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
2778 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
2779 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
2780 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
2781 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
2782 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
2783 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
2784 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
2785 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
2786 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
2787 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
2788 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
2789 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
2790 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
2791 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
2792 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
2793 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
2794 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
2795 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
2797 static const BYTE exportedPublicKeyBlob[] = {
2798 0x06,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x31,0x00,0x02,0x00,0x00,
2799 0x01,0x00,0x01,0x00,0x79,0x10,0x1c,0xd0,0x6b,0x10,0x18,0x30,0x94,0x61,0xdc,0x0e,
2800 0xcb,0x96,0x4e,0x21,0x3f,0x79,0xcd,0xa9,0x17,0x62,0xbc,0xbb,0x61,0x4c,0xe0,0x75,
2801 0x38,0x6c,0xf3,0xde,0x60,0x86,0x03,0x97,0x65,0xeb,0x1e,0x6b,0xdb,0x53,0x85,0xad,
2802 0x68,0x21,0xf1,0x5d,0xe7,0x1f,0xe6,0x53,0xb4,0xbb,0x59,0x3e,0x14,0x27,0xb1,0x83,
2803 0xa7,0x3a,0x54,0xe2 };
2805 static const BYTE asnEncodedPublicKey[] = {
2806 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,
2807 0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
2808 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,
2809 0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
2810 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
2812 static void testAcquireCertPrivateKey(void)
2815 PCCERT_CONTEXT cert;
2817 DWORD size, keySpec;
2819 CRYPT_KEY_PROV_INFO keyProvInfo;
2821 WCHAR ms_def_prov_w[MAX_PATH];
2823 if (!pCryptAcquireCertificatePrivateKey)
2825 skip("CryptAcquireCertificatePrivateKey() is not available\n");
2829 lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
2831 keyProvInfo.pwszContainerName = cspNameW;
2832 keyProvInfo.pwszProvName = ms_def_prov_w;
2833 keyProvInfo.dwProvType = PROV_RSA_FULL;
2834 keyProvInfo.dwFlags = 0;
2835 keyProvInfo.cProvParam = 0;
2836 keyProvInfo.rgProvParam = NULL;
2837 keyProvInfo.dwKeySpec = AT_SIGNATURE;
2839 pCryptAcquireContextA(NULL, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2840 CRYPT_DELETEKEYSET);
2842 cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
2843 sizeof(selfSignedCert));
2846 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL, NULL);
2847 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL,
2849 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, &keySpec,
2851 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, NULL, NULL);
2852 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, &keySpec,
2854 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, NULL, NULL, NULL);
2857 /* Missing private key */
2858 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, NULL, NULL);
2859 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2860 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2861 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2863 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2864 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2865 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2867 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2869 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2870 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2872 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2874 ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
2875 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
2880 CERT_KEY_CONTEXT keyContext;
2882 /* Don't cache provider */
2883 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2884 &keySpec, &callerFree);
2885 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2887 ok(callerFree, "Expected callerFree to be TRUE\n");
2888 CryptReleaseContext(certCSP, 0);
2889 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2891 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2893 CryptReleaseContext(certCSP, 0);
2895 /* Use the key prov info's caching (there shouldn't be any) */
2896 ret = pCryptAcquireCertificatePrivateKey(cert,
2897 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2899 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2901 ok(callerFree, "Expected callerFree to be TRUE\n");
2902 CryptReleaseContext(certCSP, 0);
2904 /* Cache it (and check that it's cached) */
2905 ret = pCryptAcquireCertificatePrivateKey(cert,
2906 CRYPT_ACQUIRE_CACHE_FLAG, NULL, &certCSP, &keySpec, &callerFree);
2907 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2909 ok(!callerFree, "Expected callerFree to be FALSE\n");
2910 size = sizeof(keyContext);
2911 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2912 &keyContext, &size);
2913 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2916 /* Remove the cached provider */
2917 CryptReleaseContext(keyContext.hCryptProv, 0);
2918 CertSetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID, 0,
2920 /* Allow caching via the key prov info */
2921 keyProvInfo.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
2922 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2924 /* Now use the key prov info's caching */
2925 ret = pCryptAcquireCertificatePrivateKey(cert,
2926 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2928 ok(ret, "CryptAcquireCertificatePrivateKey failed: %08x\n",
2930 ok(!callerFree, "Expected callerFree to be FALSE\n");
2931 size = sizeof(keyContext);
2932 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2933 &keyContext, &size);
2934 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2936 CryptReleaseContext(certCSP, 0);
2938 CryptDestroyKey(key);
2941 /* Some sanity-checking on public key exporting */
2942 ret = CryptImportPublicKeyInfo(csp, X509_ASN_ENCODING,
2943 &cert->pCertInfo->SubjectPublicKeyInfo, &key);
2944 ok(ret, "CryptImportPublicKeyInfo failed: %08x\n", GetLastError());
2947 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, NULL, &size);
2948 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
2951 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size), encodedKey;
2953 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, buf, &size);
2954 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
2955 ok(size == sizeof(exportedPublicKeyBlob), "Unexpected size %d\n",
2957 ok(!memcmp(buf, exportedPublicKeyBlob, size), "Unexpected value\n");
2958 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB,
2959 buf, CRYPT_ENCODE_ALLOC_FLAG, NULL, &encodedKey, &size);
2960 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2963 ok(size == sizeof(asnEncodedPublicKey), "Unexpected size %d\n",
2965 ok(!memcmp(encodedKey, asnEncodedPublicKey, size),
2966 "Unexpected value\n");
2967 LocalFree(encodedKey);
2969 HeapFree(GetProcessHeap(), 0, buf);
2971 CryptDestroyKey(key);
2973 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
2974 NULL, 0, NULL, NULL, &size);
2975 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
2978 PCERT_PUBLIC_KEY_INFO info = HeapAlloc(GetProcessHeap(), 0, size);
2980 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
2981 NULL, 0, NULL, info, &size);
2982 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
2985 ok(info->PublicKey.cbData == sizeof(asnEncodedPublicKey),
2986 "Unexpected size %d\n", info->PublicKey.cbData);
2987 ok(!memcmp(info->PublicKey.pbData, asnEncodedPublicKey,
2988 info->PublicKey.cbData), "Unexpected value\n");
2990 HeapFree(GetProcessHeap(), 0, info);
2993 CryptReleaseContext(csp, 0);
2994 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2995 CRYPT_DELETEKEYSET);
2997 CertFreeCertificateContext(cert);
3000 static void testGetPublicKeyLength(void)
3002 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3003 static char oid_rsa_dh[] = szOID_RSA_DH;
3004 static char bogusOID[] = "1.2.3";
3006 CERT_PUBLIC_KEY_INFO info = { { 0 } };
3007 BYTE bogusKey[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
3008 BYTE key[] = { 0x30,0x0f,0x02,0x08,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
3009 0x02,0x03,0x01,0x00,0x01 };
3012 ret = CertGetPublicKeyLength(0, NULL);
3014 /* With an empty public key info */
3015 SetLastError(0xdeadbeef);
3016 ret = CertGetPublicKeyLength(0, &info);
3017 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3018 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3019 ret, GetLastError());
3020 SetLastError(0xdeadbeef);
3021 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3022 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_EOD,
3023 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
3024 ret, GetLastError());
3025 /* With a nearly-empty public key info */
3026 info.Algorithm.pszObjId = oid_rsa_rsa;
3027 SetLastError(0xdeadbeef);
3028 ret = CertGetPublicKeyLength(0, &info);
3029 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3030 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3031 ret, GetLastError());
3032 SetLastError(0xdeadbeef);
3033 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3034 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_EOD,
3035 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
3036 ret, GetLastError());
3037 /* With a bogus key */
3038 info.PublicKey.cbData = sizeof(bogusKey);
3039 info.PublicKey.pbData = bogusKey;
3040 SetLastError(0xdeadbeef);
3041 ret = CertGetPublicKeyLength(0, &info);
3042 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3043 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3044 ret, GetLastError());
3045 SetLastError(0xdeadbeef);
3046 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3047 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_BADTAG,
3048 "Expected length 0 and CRYPT_E_ASN1_BADTAGTAG, got length %d, %08x\n",
3049 ret, GetLastError());
3050 /* With a believable RSA key but a bogus OID */
3051 info.Algorithm.pszObjId = bogusOID;
3052 info.PublicKey.cbData = sizeof(key);
3053 info.PublicKey.pbData = key;
3054 SetLastError(0xdeadbeef);
3055 ret = CertGetPublicKeyLength(0, &info);
3056 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3057 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3058 ret, GetLastError());
3059 SetLastError(0xdeadbeef);
3060 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3061 ok(ret == 56, "Expected length 56, got %d\n", ret);
3062 /* An RSA key with the DH OID */
3063 info.Algorithm.pszObjId = oid_rsa_dh;
3064 SetLastError(0xdeadbeef);
3065 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3066 ok(ret == 0 && GetLastError() == CRYPT_E_ASN1_BADTAG,
3067 "Expected length 0 and CRYPT_E_ASN1_BADTAG, got length %d, %08x\n",
3068 ret, GetLastError());
3069 /* With the RSA OID */
3070 info.Algorithm.pszObjId = oid_rsa_rsa;
3071 SetLastError(0xdeadbeef);
3072 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3073 ok(ret == 56, "Expected length 56, got %d\n", ret);
3074 /* With the RSA OID and a message encoding */
3075 info.Algorithm.pszObjId = oid_rsa_rsa;
3076 SetLastError(0xdeadbeef);
3077 ret = CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &info);
3078 ok(ret == 56, "Expected length 56, got %d\n", ret);
3083 init_function_pointers();
3086 testCertProperties();
3089 testGetSubjectCert();
3090 testGetIssuerCert();
3092 testCryptHashCert();
3094 testSignAndEncodeCert();
3095 testCreateSelfSignCert();
3097 testGetValidUsages();
3098 testCompareCertName();
3099 testCompareIntegerBlob();
3100 testComparePublicKeyInfo();
3101 testHashPublicKeyInfo();
3102 testHashToBeSigned();
3104 testVerifySubjectCert();
3105 testVerifyRevocation();
3106 testAcquireCertPrivateKey();
3107 testGetPublicKeyLength();