source: trunk/src/crypt32/tests/cert.c@ 21311

Last change on this file since 21311 was 21311, checked in by vladest, 16 years ago

Added CRYPT32 and MSCMS APIs support

File size: 147.9 KB
Line 
1/*
2 * crypt32 cert functions tests
3 *
4 * Copyright 2005-2006 Juan Lang
5 *
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.
10 *
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.
15 *
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
19 */
20
21#include <assert.h>
22#include <stdio.h>
23#include <stdarg.h>
24#include <windef.h>
25#include <winbase.h>
26#include <winreg.h>
27#include <winerror.h>
28#include <wincrypt.h>
29
30#include "wine/test.h"
31
32static BOOL (WINAPI *pCertAddStoreToCollection)(HCERTSTORE,HCERTSTORE,DWORD,DWORD);
33static PCCERT_CONTEXT (WINAPI *pCertCreateSelfSignCertificate)(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE,PCERT_NAME_BLOB,DWORD,PCRYPT_KEY_PROV_INFO,PCRYPT_ALGORITHM_IDENTIFIER,PSYSTEMTIME,PSYSTEMTIME,PCERT_EXTENSIONS);
34static BOOL (WINAPI *pCertGetValidUsages)(DWORD,PCCERT_CONTEXT*,int*,LPSTR*,DWORD*);
35static BOOL (WINAPI *pCryptAcquireCertificatePrivateKey)(PCCERT_CONTEXT,DWORD,void*,HCRYPTPROV_OR_NCRYPT_KEY_HANDLE*,DWORD*,BOOL*);
36static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*);
37static BOOL (WINAPI * pCryptVerifyCertificateSignatureEx)
38 (HCRYPTPROV, DWORD, DWORD, void *, DWORD, void *, DWORD, void *);
39
40static BOOL (WINAPI * pCryptAcquireContextA)
41 (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
42
43static void init_function_pointers(void)
44{
45 HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll");
46 HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
47
48#define GET_PROC(dll, func) \
49 p ## func = (void *)GetProcAddress(dll, #func); \
50 if(!p ## func) \
51 trace("GetProcAddress(%s) failed\n", #func);
52
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)
59
60 GET_PROC(hAdvapi32, CryptAcquireContextA)
61
62#undef GET_PROC
63}
64
65static BYTE subjectName[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
66 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
67 0x6e, 0x67, 0x00 };
68static BYTE serialNum[] = { 1 };
69static 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 };
79static BYTE bigCertHash[] = { 0x6e, 0x30, 0x90, 0x71, 0x5f, 0xd9, 0x23,
80 0x56, 0xeb, 0xae, 0x25, 0x40, 0xe6, 0x22, 0xda, 0x19, 0x26, 0x02, 0xa6, 0x08 };
81
82static 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,
92 0x01, 0x01 };
93static 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,
103 0x02, 0x01, 0x01 };
104
105static BYTE subjectName2[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
106 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61,
107 0x6e, 0x67, 0x00 };
108static 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 };
118static 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,
128 0x02, 0x01, 0x01 };
129static BYTE bigCert2Hash[] = { 0x4a, 0x7f, 0x32, 0x1f, 0xcf, 0x3b, 0xc0,
130 0x87, 0x48, 0x2b, 0xa1, 0x86, 0x54, 0x18, 0xe4, 0x3a, 0x0e, 0x53, 0x7e, 0x2b };
131
132static 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 };
144
145static void testAddCert(void)
146{
147 HCERTSTORE store;
148 HCERTSTORE collection;
149 PCCERT_CONTEXT context;
150 PCCERT_CONTEXT copyContext;
151 BOOL ret;
152
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());
156 if (!store)
157 return;
158
159 /* Weird--bad add disposition leads to an access violation in Windows.
160 * Both tests crash on some win9x boxes.
161 */
162 if (0)
163 {
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",
169 GetLastError());
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",
175 GetLastError());
176 }
177
178 /* Weird--can add a cert to the NULL store (does this have special
179 * meaning?)
180 */
181 context = NULL;
182 ret = CertAddEncodedCertificateToStore(0, X509_ASN_ENCODING, bigCert,
183 sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
184 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
185 GetLastError());
186 if (context)
187 CertFreeCertificateContext(context);
188
189 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
190 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
191 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
192 GetLastError());
193 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
194 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
195 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
196 GetLastError());
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",
201 GetLastError());
202 ok(context != NULL, "Expected a context\n");
203 if (context)
204 {
205 CRYPT_DATA_BLOB hash = { sizeof(bigCert2Hash), bigCert2Hash };
206
207 /* Duplicate (AddRef) the context so we can still use it after
208 * deleting it from the store.
209 */
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,
214 0, &hash);
215 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
216 GetLastError());
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
220 * that it fails.
221 */
222 ok(!ret, "Expected failure\n");
223 CertFreeCertificateContext(context);
224 }
225 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
226 sizeof(bigCert2));
227 ok(context != NULL, "Expected a context\n");
228 if (context)
229 {
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);
236 }
237
238 /* Adding a cert with the same issuer name and serial number (but
239 * different subject) as an existing cert succeeds.
240 */
241 context = NULL;
242 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
243 bigCert2WithDifferentSerial, sizeof(bigCert2WithDifferentSerial),
244 CERT_STORE_ADD_NEW, &context);
245 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
246 GetLastError());
247 if (context)
248 CertDeleteCertificateFromStore(context);
249
250 /* Adding a cert with the same subject name and serial number (but
251 * different issuer) as an existing cert succeeds.
252 */
253 context = NULL;
254 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
255 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject),
256 CERT_STORE_ADD_NEW, &context);
257 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
258 GetLastError());
259 if (context)
260 CertDeleteCertificateFromStore(context);
261
262 /* Adding a cert with the same issuer name and serial number (but
263 * different otherwise) as an existing cert succeeds.
264 */
265 context = NULL;
266 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
267 bigCertWithDifferentIssuer, sizeof(bigCertWithDifferentIssuer),
268 CERT_STORE_ADD_NEW, &context);
269 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
270 GetLastError());
271 if (context)
272 CertDeleteCertificateFromStore(context);
273
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)
278 {
279 /* Add store to the collection, but disable updates */
280 pCertAddStoreToCollection(collection, store, 0, 0);
281
282 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2,
283 sizeof(bigCert2));
284 ok(context != NULL, "Expected a context\n");
285 if (context)
286 {
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..
294 */
295 ret = CertAddCertificateContextToStore(collection, context,
296 CERT_STORE_ADD_REPLACE_EXISTING, NULL);
297 ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
298 GetLastError());
299 /* use the existing certificate and ask for a copy of the context*/
300 copyContext = NULL;
301 ret = CertAddCertificateContextToStore(collection, context,
302 CERT_STORE_ADD_USE_EXISTING, &copyContext);
303 ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
304 GetLastError());
305 ok(copyContext != NULL, "Expected on output a non NULL copyContext\n");
306 if (copyContext)
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);
314 }
315
316 CertCloseStore(collection, 0);
317 }
318
319 CertCloseStore(store, 0);
320}
321
322static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
323 PCCERT_CONTEXT context, DWORD propID)
324{
325 BYTE hash[20] = { 0 }, hashProperty[20];
326 BOOL ret;
327 DWORD size;
328 DWORD dwSizeWithNull;
329
330 memset(hash, 0, sizeof(hash));
331 memset(hashProperty, 0, sizeof(hashProperty));
332 size = sizeof(hash);
333 ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
334 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
335 ret = CertGetCertificateContextProperty(context, propID, NULL,
336 &dwSizeWithNull);
337 ok(ret, "algID %08x, propID %d: CertGetCertificateContextProperty failed: %08x\n",
338 algID, propID, GetLastError());
339 ret = CertGetCertificateContextProperty(context, propID, hashProperty,
340 &size);
341 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
342 GetLastError());
343 ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
344 propID);
345 ok(size == dwSizeWithNull, "Unexpected length of hash for property: received %d instead of %d\n",
346 dwSizeWithNull,size);
347}
348
349static CHAR cspNameA[] = "WineCryptTemp";
350static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e','m','p',0 };
351static const BYTE v1CertWithPubKey[] = {
3520x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
3530x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
3540x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
3550x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3560x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
3570x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3580x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
3590x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
3600x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
3610x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
3620x01,0x01 };
363static const BYTE v1CertWithSubjectKeyId[] = {
3640x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
3650x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
3660x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
3670x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3680x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
3690x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
3700x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
3710x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
3720x4c,0x61,0x6e,0x67,0x00 };
373static const BYTE subjectKeyId[] = {
3740x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
375static 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 };
399static const BYTE selfSignedSignatureHash[] = { 0x07,0x5a,0x3e,0xfd,0x0d,0xf6,
400 0x88,0xeb,0x00,0x64,0xbd,0xc9,0xd6,0xea,0x0a,0x7c,0xcc,0x24,0xdb,0x5d };
401
402static void testCertProperties(void)
403{
404 PCCERT_CONTEXT context = CertCreateCertificateContext(X509_ASN_ENCODING,
405 bigCert, sizeof(bigCert));
406 DWORD propID, numProps, access, size;
407 BOOL ret;
408 BYTE hash[20] = { 0 }, hashProperty[20];
409 CRYPT_DATA_BLOB blob;
410 CERT_KEY_CONTEXT keyContext;
411
412 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
413 GetLastError());
414 if (!context)
415 return;
416
417 /* This crashes
418 propID = CertEnumCertificateContextProperties(NULL, 0);
419 */
420
421 propID = 0;
422 numProps = 0;
423 do {
424 propID = CertEnumCertificateContextProperties(context, propID);
425 if (propID)
426 numProps++;
427 } while (propID != 0);
428 ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
429
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);
437 */
438
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);
445 */
446
447 /* These all crash.
448 ret = CertGetCertificateContextProperty(context,
449 CERT_ACCESS_STATE_PROP_ID, 0, NULL);
450 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
451 NULL, NULL);
452 ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
453 hashProperty, NULL);
454 */
455 /* A missing prop */
456 size = 0;
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",
466 GetLastError());
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);
473 */
474
475 /* Can I set the hash to an invalid hash? */
476 blob.pbData = hash;
477 blob.cbData = sizeof(hash);
478 ret = CertSetCertificateContextProperty(context, CERT_HASH_PROP_ID, 0,
479 &blob);
480 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
481 GetLastError());
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,
488 NULL);
489 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
490 GetLastError());
491 checkHash(bigCert, sizeof(bigCert), CALG_SHA1, context,
492 CERT_HASH_PROP_ID);
493
494 /* Now that the hash property is set, we should get one property when
495 * enumerating.
496 */
497 propID = 0;
498 numProps = 0;
499 do {
500 propID = CertEnumCertificateContextProperties(context, propID);
501 if (propID)
502 numProps++;
503 } while (propID != 0);
504 ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
505
506 /* Check a few other implicit properties */
507 checkHash(bigCert, sizeof(bigCert), CALG_MD5, context,
508 CERT_MD5_HASH_PROP_ID);
509
510 /* Getting the signature hash fails with this bogus certificate */
511 size = 0;
512 ret = CertGetCertificateContextProperty(context,
513 CERT_SIGNATURE_HASH_PROP_ID, NULL, &size);
514 ok(!ret &&
515 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
516 GetLastError() == CRYPT_E_NOT_FOUND ||
517 GetLastError() == OSS_DATA_ERROR), /* win9x */
518 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
519
520 /* Test key contexts and handles and such */
521 size = 0;
522 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
523 NULL, &size);
524 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
525 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
526 size = sizeof(CERT_KEY_CONTEXT);
527 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
528 NULL, &size);
529 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
530 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
531 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
532 &keyContext, &size);
533 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
534 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
535 /* Key context with an invalid size */
536 keyContext.cbSize = 0;
537 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
538 0, &keyContext);
539 ok(!ret && GetLastError() == E_INVALIDARG,
540 "Expected E_INVALIDARG, got %08x\n", GetLastError());
541 size = sizeof(keyContext);
542 ret = CertGetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
543 &keyContext, &size);
544 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
545 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
546 keyContext.cbSize = sizeof(keyContext);
547 keyContext.hCryptProv = 0;
548 keyContext.dwKeySpec = AT_SIGNATURE;
549 ret = CertSetCertificateContextProperty(context, CERT_KEY_CONTEXT_PROP_ID,
550 0, &keyContext);
551 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
552 /* Now that that's set, the key prov handle property is also gettable.
553 */
554 size = sizeof(DWORD);
555 ret = CertGetCertificateContextProperty(context,
556 CERT_KEY_PROV_HANDLE_PROP_ID, &keyContext.hCryptProv, &size);
557 ok(ret, "Expected to get the CERT_KEY_PROV_HANDLE_PROP_ID, got %08x\n",
558 GetLastError());
559 /* Remove the key prov handle property.. */
560 ret = CertSetCertificateContextProperty(context,
561 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
562 ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
563 GetLastError());
564 /* and the key context's CSP is set to NULL. */
565 size = sizeof(keyContext);
566 ret = CertGetCertificateContextProperty(context,
567 CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
568 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
569 GetLastError());
570 ok(keyContext.hCryptProv == 0, "Expected no hCryptProv\n");
571
572 /* According to MSDN the subject key id can be stored as a property,
573 * as a subject key extension, or as the SHA1 hash of the public key,
574 * but this cert has none of them:
575 */
576 ret = CertGetCertificateContextProperty(context,
577 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
578 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
579 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
580 CertFreeCertificateContext(context);
581 /* This cert does have a public key, but its subject key identifier still
582 * isn't available: */
583 context = CertCreateCertificateContext(X509_ASN_ENCODING,
584 v1CertWithPubKey, sizeof(v1CertWithPubKey));
585 ret = CertGetCertificateContextProperty(context,
586 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
587 ok(!ret && GetLastError() == ERROR_INVALID_DATA,
588 "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
589 CertFreeCertificateContext(context);
590 /* This cert with a subject key extension can have its key identifier
591 * property retrieved:
592 */
593 context = CertCreateCertificateContext(X509_ASN_ENCODING,
594 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId));
595 ret = CertGetCertificateContextProperty(context,
596 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
597 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
598 if (ret)
599 {
600 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
601
602 if (buf)
603 {
604 ret = CertGetCertificateContextProperty(context,
605 CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
606 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
607 GetLastError());
608 ok(!memcmp(buf, subjectKeyId, size), "Unexpected subject key id\n");
609 HeapFree(GetProcessHeap(), 0, buf);
610 }
611 }
612 CertFreeCertificateContext(context);
613
614 context = CertCreateCertificateContext(X509_ASN_ENCODING,
615 selfSignedCert, sizeof(selfSignedCert));
616 /* Getting the signature hash of a valid (self-signed) cert succeeds */
617 size = 0;
618 ret = CertGetCertificateContextProperty(context,
619 CERT_SIGNATURE_HASH_PROP_ID, NULL, &size);
620 ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
621 ok(size == sizeof(selfSignedSignatureHash), "unexpected size %d\n", size);
622 ret = CertGetCertificateContextProperty(context,
623 CERT_SIGNATURE_HASH_PROP_ID, hashProperty, &size);
624 if (ret)
625 ok(!memcmp(hashProperty, selfSignedSignatureHash, size),
626 "unexpected value\n");
627 CertFreeCertificateContext(context);
628}
629
630static void testDupCert(void)
631{
632 HCERTSTORE store;
633 PCCERT_CONTEXT context, dupContext;
634 BOOL ret;
635
636 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
637 CERT_STORE_CREATE_NEW_FLAG, NULL);
638 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
639 if (!store)
640 return;
641
642 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
643 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context);
644 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
645 GetLastError());
646 ok(context != NULL, "Expected a valid cert context\n");
647 if (context)
648 {
649 ok(context->cbCertEncoded == sizeof(bigCert),
650 "Wrong cert size %d\n", context->cbCertEncoded);
651 ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)),
652 "Unexpected encoded cert in context\n");
653 ok(context->hCertStore == store, "Unexpected store\n");
654
655 dupContext = CertDuplicateCertificateContext(context);
656 ok(dupContext != NULL, "Expected valid duplicate\n");
657 /* Not only is it a duplicate, it's identical: the address is the
658 * same.
659 */
660 ok(dupContext == context, "Expected identical context addresses\n");
661 CertFreeCertificateContext(dupContext);
662 CertFreeCertificateContext(context);
663 }
664 CertCloseStore(store, 0);
665}
666
667static BYTE subjectName3[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
668 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x52, 0x6f, 0x62, 0x20, 0x20, 0x4c, 0x61,
669 0x6e, 0x67, 0x00 };
670static const BYTE iTunesCert0[] = {
6710x30,0x82,0x03,0xc4,0x30,0x82,0x03,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
6720x47,0xbf,0x19,0x95,0xdf,0x8d,0x52,0x46,0x43,0xf7,0xdb,0x6d,0x48,0x0d,0x31,
6730xa4,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
6740x00,0x30,0x81,0x8b,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
6750x5a,0x41,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0c,0x57,0x65,
6760x73,0x74,0x65,0x72,0x6e,0x20,0x43,0x61,0x70,0x65,0x31,0x14,0x30,0x12,0x06,
6770x03,0x55,0x04,0x07,0x13,0x0b,0x44,0x75,0x72,0x62,0x61,0x6e,0x76,0x69,0x6c,
6780x6c,0x65,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x0a,0x13,0x06,0x54,0x68,
6790x61,0x77,0x74,0x65,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14,
6800x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
6810x61,0x74,0x69,0x6f,0x6e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13,
6820x16,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
6830x6d,0x70,0x69,0x6e,0x67,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x33,0x31,
6840x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x33,0x31,
6850x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x53,0x31,0x0b,0x30,
6860x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,
6870x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
6880x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,
6890x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,0x6d,0x65,0x20,
6900x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,0x76,0x69,0x63,
6910x65,0x73,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,
6920x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,
6930x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa9,0xca,0xb2,0xa4,0xcc,0xcd,0x20,
6940xaf,0x0a,0x7d,0x89,0xac,0x87,0x75,0xf0,0xb4,0x4e,0xf1,0xdf,0xc1,0x0f,0xbf,
6950x67,0x61,0xbd,0xa3,0x64,0x1c,0xda,0xbb,0xf9,0xca,0x33,0xab,0x84,0x30,0x89,
6960x58,0x7e,0x8c,0xdb,0x6b,0xdd,0x36,0x9e,0x0f,0xbf,0xd1,0xec,0x78,0xf2,0x77,
6970xa6,0x7e,0x6f,0x3c,0xbf,0x93,0xaf,0x0d,0xba,0x68,0xf4,0x6c,0x94,0xca,0xbd,
6980x52,0x2d,0xab,0x48,0x3d,0xf5,0xb6,0xd5,0x5d,0x5f,0x1b,0x02,0x9f,0xfa,0x2f,
6990x6b,0x1e,0xa4,0xf7,0xa3,0x9a,0xa6,0x1a,0xc8,0x02,0xe1,0x7f,0x4c,0x52,0xe3,
7000x0e,0x60,0xec,0x40,0x1c,0x7e,0xb9,0x0d,0xde,0x3f,0xc7,0xb4,0xdf,0x87,0xbd,
7010x5f,0x7a,0x6a,0x31,0x2e,0x03,0x99,0x81,0x13,0xa8,0x47,0x20,0xce,0x31,0x73,
7020x0d,0x57,0x2d,0xcd,0x78,0x34,0x33,0x95,0x12,0x99,0x12,0xb9,0xde,0x68,0x2f,
7030xaa,0xe6,0xe3,0xc2,0x8a,0x8c,0x2a,0xc3,0x8b,0x21,0x87,0x66,0xbd,0x83,0x58,
7040x57,0x6f,0x75,0xbf,0x3c,0xaa,0x26,0x87,0x5d,0xca,0x10,0x15,0x3c,0x9f,0x84,
7050xea,0x54,0xc1,0x0a,0x6e,0xc4,0xfe,0xc5,0x4a,0xdd,0xb9,0x07,0x11,0x97,0x22,
7060x7c,0xdb,0x3e,0x27,0xd1,0x1e,0x78,0xec,0x9f,0x31,0xc9,0xf1,0xe6,0x22,0x19,
7070xdb,0xc4,0xb3,0x47,0x43,0x9a,0x1a,0x5f,0xa0,0x1e,0x90,0xe4,0x5e,0xf5,0xee,
7080x7c,0xf1,0x7d,0xab,0x62,0x01,0x8f,0xf5,0x4d,0x0b,0xde,0xd0,0x22,0x56,0xa8,
7090x95,0xcd,0xae,0x88,0x76,0xae,0xee,0xba,0x0d,0xf3,0xe4,0x4d,0xd9,0xa0,0xfb,
7100x68,0xa0,0xae,0x14,0x3b,0xb3,0x87,0xc1,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,
7110x81,0xdb,0x30,0x81,0xd8,0x30,0x34,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
7120x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
7130x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,
7140x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,
7150x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
7160xff,0x02,0x01,0x00,0x30,0x41,0x06,0x03,0x55,0x1d,0x1f,0x04,0x3a,0x30,0x38,
7170x30,0x36,0xa0,0x34,0xa0,0x32,0x86,0x30,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
7180x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,
7190x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
7200x6d,0x70,0x69,0x6e,0x67,0x43,0x41,0x2e,0x63,0x72,0x6c,0x30,0x13,0x06,0x03,
7210x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
7220x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,
7230x02,0x01,0x06,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,0x04,0x1d,0x30,0x1b,0xa4,
7240x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0c,0x54,
7250x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,0x33,0x30,0x0d,0x06,0x09,
7260x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,
7270x4a,0x6b,0xf9,0xea,0x58,0xc2,0x44,0x1c,0x31,0x89,0x79,0x99,0x2b,0x96,0xbf,
7280x82,0xac,0x01,0xd6,0x1c,0x4c,0xcd,0xb0,0x8a,0x58,0x6e,0xdf,0x08,0x29,0xa3,
7290x5e,0xc8,0xca,0x93,0x13,0xe7,0x04,0x52,0x0d,0xef,0x47,0x27,0x2f,0x00,0x38,
7300xb0,0xe4,0xc9,0x93,0x4e,0x9a,0xd4,0x22,0x62,0x15,0xf7,0x3f,0x37,0x21,0x4f,
7310x70,0x31,0x80,0xf1,0x8b,0x38,0x87,0xb3,0xe8,0xe8,0x97,0x00,0xfe,0xcf,0x55,
7320x96,0x4e,0x24,0xd2,0xa9,0x27,0x4e,0x7a,0xae,0xb7,0x61,0x41,0xf3,0x2a,0xce,
7330xe7,0xc9,0xd9,0x5e,0xdd,0xbb,0x2b,0x85,0x3e,0xb5,0x9d,0xb5,0xd9,0xe1,0x57,
7340xff,0xbe,0xb4,0xc5,0x7e,0xf5,0xcf,0x0c,0x9e,0xf0,0x97,0xfe,0x2b,0xd3,0x3b,
7350x52,0x1b,0x1b,0x38,0x27,0xf7,0x3f,0x4a };
736static const BYTE iTunesCert1[] = {
7370x30,0x82,0x03,0xff,0x30,0x82,0x02,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
7380x0d,0xe9,0x2b,0xf0,0xd4,0xd8,0x29,0x88,0x18,0x32,0x05,0x09,0x5e,0x9a,0x76,
7390x88,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
7400x00,0x30,0x53,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
7410x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
7420x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,
7430x06,0x03,0x55,0x04,0x03,0x13,0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
7440x20,0x54,0x69,0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,
7450x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,
7460x30,0x33,0x31,0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
7470x30,0x38,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x57,
7480x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,
7490x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,
7500x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2f,0x30,0x2d,0x06,0x03,0x55,
7510x04,0x03,0x13,0x26,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,
7520x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,
7530x76,0x69,0x63,0x65,0x73,0x20,0x53,0x69,0x67,0x6e,0x65,0x72,0x30,0x82,0x01,
7540x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
7550x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,
7560xb2,0x50,0x28,0x48,0xdd,0xd3,0x68,0x7a,0x84,0x18,0x44,0x66,0x75,0x5d,0x7e,
7570xc4,0xb8,0x9f,0x63,0x26,0xff,0x3d,0x43,0x9c,0x7c,0x11,0x38,0x10,0x25,0x55,
7580x73,0xd9,0x75,0x27,0x69,0xfd,0x4e,0xb9,0x20,0x5c,0xd3,0x0a,0xf9,0xa0,0x1b,
7590x2a,0xed,0x55,0x56,0x21,0x61,0xd8,0x1e,0xdb,0xe4,0xbc,0x33,0x6b,0xc7,0xef,
7600xdd,0xa3,0x37,0x65,0x8e,0x1b,0x93,0x0c,0xb6,0x53,0x1e,0x5c,0x7c,0x66,0x35,
7610x5f,0x05,0x8a,0x45,0xfe,0x76,0x4e,0xdf,0x53,0x80,0xa2,0x81,0x20,0x9d,0xae,
7620x88,0x5c,0xa2,0x08,0xf7,0xe5,0x30,0xf9,0xee,0x22,0x37,0x4c,0x42,0x0a,0xce,
7630xdf,0xc6,0x1f,0xc4,0xd6,0x55,0xe9,0x81,0x3f,0xb5,0x52,0xa3,0x2c,0xaa,0x01,
7640x7a,0xf2,0xa2,0xaa,0x8d,0x35,0xfe,0x9f,0xe6,0x5d,0x6a,0x05,0x9f,0x3d,0x6b,
7650xe3,0xbf,0x96,0xc0,0xfe,0xcc,0x60,0xf9,0x40,0xe7,0x07,0xa0,0x44,0xeb,0x81,
7660x51,0x6e,0xa5,0x2a,0xf2,0xb6,0x8a,0x10,0x28,0xed,0x8f,0xdc,0x06,0xa0,0x86,
7670x50,0x9a,0x7b,0x4a,0x08,0x0d,0x30,0x1d,0xca,0x10,0x9e,0x6b,0xf7,0xe9,0x58,
7680xae,0x04,0xa9,0x40,0x99,0xb2,0x28,0xe8,0x8f,0x16,0xac,0x3c,0xe3,0x53,0x6f,
7690x4b,0xd3,0x35,0x9d,0xb5,0x6f,0x64,0x1d,0xb3,0x96,0x2c,0xbb,0x3d,0xe7,0x79,
7700xeb,0x6d,0x7a,0xf9,0x16,0xe6,0x26,0xad,0xaf,0xef,0x99,0x53,0xb7,0x40,0x2c,
7710x95,0xb8,0x79,0xaa,0xfe,0xd4,0x52,0xab,0x29,0x74,0x7e,0x42,0xec,0x39,0x1e,
7720xa2,0x6a,0x16,0xe6,0x59,0xbb,0x24,0x68,0xd8,0x00,0x80,0x43,0x10,0x87,0x80,
7730x6b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xca,0x30,0x81,0xc7,0x30,0x34,0x06,
7740x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,
7750x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,
7760x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
7770x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
7780xff,0x04,0x02,0x30,0x00,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30,
7790x2a,0x30,0x28,0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,
7800x2f,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,
7810x6f,0x6d,0x2f,0x74,0x73,0x73,0x2d,0x63,0x61,0x2e,0x63,0x72,0x6c,0x30,0x16,
7820x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,
7830x06,0x01,0x05,0x05,0x07,0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
7840x01,0xff,0x04,0x04,0x03,0x02,0x06,0xc0,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,
7850x04,0x1d,0x30,0x1b,0xa4,0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,
7860x04,0x03,0x13,0x0c,0x54,0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,
7870x34,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
7880x00,0x03,0x82,0x01,0x01,0x00,0x87,0x78,0x70,0xda,0x4e,0x52,0x01,0x20,0x5b,
7890xe0,0x79,0xc9,0x82,0x30,0xc4,0xfd,0xb9,0x19,0x96,0xbd,0x91,0x00,0xc3,0xbd,
7900xcd,0xcd,0xc6,0xf4,0x0e,0xd8,0xff,0xf9,0x4d,0xc0,0x33,0x62,0x30,0x11,0xc5,
7910xf5,0x74,0x1b,0xd4,0x92,0xde,0x5f,0x9c,0x20,0x13,0xb1,0x7c,0x45,0xbe,0x50,
7920xcd,0x83,0xe7,0x80,0x17,0x83,0xa7,0x27,0x93,0x67,0x13,0x46,0xfb,0xca,0xb8,
7930x98,0x41,0x03,0xcc,0x9b,0x51,0x5b,0x05,0x8b,0x7f,0xa8,0x6f,0xf3,0x1b,0x50,
7940x1b,0x24,0x2e,0xf2,0x69,0x8d,0x6c,0x22,0xf7,0xbb,0xca,0x16,0x95,0xed,0x0c,
7950x74,0xc0,0x68,0x77,0xd9,0xeb,0x99,0x62,0x87,0xc1,0x73,0x90,0xf8,0x89,0x74,
7960x7a,0x23,0xab,0xa3,0x98,0x7b,0x97,0xb1,0xf7,0x8f,0x29,0x71,0x4d,0x2e,0x75,
7970x1b,0x48,0x41,0xda,0xf0,0xb5,0x0d,0x20,0x54,0xd6,0x77,0xa0,0x97,0x82,0x63,
7980x69,0xfd,0x09,0xcf,0x8a,0xf0,0x75,0xbb,0x09,0x9b,0xd9,0xf9,0x11,0x55,0x26,
7990x9a,0x61,0x32,0xbe,0x7a,0x02,0xb0,0x7b,0x86,0xbe,0xa2,0xc3,0x8b,0x22,0x2c,
8000x78,0xd1,0x35,0x76,0xbc,0x92,0x73,0x5c,0xf9,0xb9,0xe6,0x4c,0x15,0x0a,0x23,
8010xcc,0xe4,0xd2,0xd4,0x34,0x2e,0x49,0x40,0x15,0x3c,0x0f,0x60,0x7a,0x24,0xc6,
8020xa5,0x66,0xef,0x96,0xcf,0x70,0xeb,0x3e,0xe7,0xf4,0x0d,0x7e,0xdc,0xd1,0x7c,
8030xa3,0x76,0x71,0x69,0xc1,0x9c,0x4f,0x47,0x30,0x35,0x21,0xb1,0xa2,0xaf,0x1a,
8040x62,0x3c,0x2b,0xd9,0x8e,0xaa,0x2a,0x07,0x7b,0xd8,0x18,0xb3,0x5c,0x7b,0xe2,
8050x9d,0xa5,0x6f,0xfe,0x3c,0x89,0xad };
806static const BYTE iTunesCert2[] = {
8070x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
8080x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75,
8090xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
8100x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
8110x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
8120x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,
8130x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,
8140x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,
8150x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,
8160x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x34,0x30,
8170x37,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30,
8180x37,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,
8190x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,
8200x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
8210x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b,
8220x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,
8230x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,
8240x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,
8250x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,
8260x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,
8270x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,
8280x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,
8290x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,0x53,0x69,
8300x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,0x20,0x43,0x41,0x30,0x82,
8310x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,
8320x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,
8330x00,0xbe,0xbc,0xee,0xbc,0x7e,0xef,0x83,0xeb,0xe0,0x37,0x4f,0xfb,0x03,0x10,
8340x38,0xbe,0x08,0xd2,0x8c,0x7d,0x9d,0xfa,0x92,0x7f,0x19,0x0c,0xc2,0x6b,0xee,
8350x42,0x52,0x8c,0xde,0xd3,0x1c,0x48,0x13,0x25,0xea,0xc1,0x63,0x7a,0xf9,0x51,
8360x65,0xee,0xd3,0xaa,0x3b,0xf5,0xf0,0x94,0x9c,0x2b,0xfb,0xf2,0x66,0xd4,0x24,
8370xda,0xf7,0xf5,0x9f,0x6e,0x19,0x39,0x36,0xbc,0xd0,0xa3,0x76,0x08,0x1e,0x22,
8380x27,0x24,0x6c,0x38,0x91,0x27,0xe2,0x84,0x49,0xae,0x1b,0x8a,0xa1,0xfd,0x25,
8390x82,0x2c,0x10,0x30,0xe8,0x71,0xab,0x28,0xe8,0x77,0x4a,0x51,0xf1,0xec,0xcd,
8400xf8,0xf0,0x54,0xd4,0x6f,0xc0,0xe3,0x6d,0x0a,0x8f,0xd9,0xd8,0x64,0x8d,0x63,
8410xb2,0x2d,0x4e,0x27,0xf6,0x85,0x0e,0xfe,0x6d,0xe3,0x29,0x99,0xe2,0x85,0x47,
8420x7c,0x2d,0x86,0x7f,0xe8,0x57,0x8f,0xad,0x67,0xc2,0x33,0x32,0x91,0x13,0x20,
8430xfc,0xa9,0x23,0x14,0x9a,0x6d,0xc2,0x84,0x4b,0x76,0x68,0x04,0xd5,0x71,0x2c,
8440x5d,0x21,0xfa,0x88,0x0d,0x26,0xfd,0x1f,0x2d,0x91,0x2b,0xe7,0x01,0x55,0x4d,
8450xf2,0x6d,0x35,0x28,0x82,0xdf,0xd9,0x6b,0x5c,0xb6,0xd6,0xd9,0xaa,0x81,0xfd,
8460x5f,0xcd,0x83,0xba,0x63,0x9d,0xd0,0x22,0xfc,0xa9,0x3b,0x42,0x69,0xb2,0x8e,
8470x3a,0xb5,0xbc,0xb4,0x9e,0x0f,0x5e,0xc4,0xea,0x2c,0x82,0x8b,0x28,0xfd,0x53,
8480x08,0x96,0xdd,0xb5,0x01,0x20,0xd1,0xf9,0xa5,0x18,0xe7,0xc0,0xee,0x51,0x70,
8490x37,0xe1,0xb6,0x05,0x48,0x52,0x48,0x6f,0x38,0xea,0xc3,0xe8,0x6c,0x7b,0x44,
8500x84,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xa0,0x30,0x82,0x01,0x9c,
8510x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
8520x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,
8530x3b,0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,
8540x03,0x30,0x2a,0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
8550x16,0x1c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,
8560x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,
8570x30,0x31,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24,
8580xa0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,
8590x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63,
8600x61,0x33,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16,
8610x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2b,
8620x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
8630x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48,
8640x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x01,0x30,0x29,0x06,
8650x03,0x55,0x1d,0x11,0x04,0x22,0x30,0x20,0xa4,0x1e,0x30,0x1c,0x31,0x1a,0x30,
8660x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6c,0x61,0x73,0x73,0x33,0x43,
8670x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x34,0x33,0x30,0x1d,0x06,0x03,0x55,
8680x1d,0x0e,0x04,0x16,0x04,0x14,0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,
8690x36,0x7c,0x68,0xcf,0x5b,0x78,0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x81,0x80,0x06,
8700x03,0x55,0x1d,0x23,0x04,0x79,0x30,0x77,0xa1,0x63,0xa4,0x61,0x30,0x5f,0x31,
8710x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,
8720x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
8730x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,
8740x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6c,
8750x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,
8760x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,
8770x72,0x69,0x74,0x79,0x82,0x10,0x70,0xba,0xe4,0x1d,0x10,0xd9,0x29,0x34,0xb6,
8780x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
8790xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xae,0x3a,0x17,0xb8,
8800x4a,0x7b,0x55,0xfa,0x64,0x55,0xec,0x40,0xa4,0xed,0x49,0x41,0x90,0x99,0x9c,
8810x89,0xbc,0xaf,0x2e,0x1d,0xca,0x78,0x23,0xf9,0x1c,0x19,0x0f,0x7f,0xeb,0x68,
8820xbc,0x32,0xd9,0x88,0x38,0xde,0xdc,0x3f,0xd3,0x89,0xb4,0x3f,0xb1,0x82,0x96,
8830xf1,0xa4,0x5a,0xba,0xed,0x2e,0x26,0xd3,0xde,0x7c,0x01,0x6e,0x00,0x0a,0x00,
8840xa4,0x06,0x92,0x11,0x48,0x09,0x40,0xf9,0x1c,0x18,0x79,0x67,0x23,0x24,0xe0,
8850xbb,0xd5,0xe1,0x50,0xae,0x1b,0xf5,0x0e,0xdd,0xe0,0x2e,0x81,0xcd,0x80,0xa3,
8860x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88,
8870x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f,
8880x5e,0xf6,0x7a,0xb5 };
889static const BYTE iTunesCert3[] = {
8900x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
8910x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6,
8920x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
8930x00,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
8940x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,
8950x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,
8960x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
8970x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,
8980x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,
8990x73,0x20,0x6f,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,
9000x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
9010x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,
9020x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,
9030x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,
9040x6f,0x64,0x65,0x20,0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,
9050x34,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x31,0x37,0x30,
9060x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x38,0x30,0x31,0x32,0x32,0x32,
9070x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,
9080x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
9090x08,0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x12,
9100x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,
9110x69,0x6e,0x6f,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0a,0x14,0x14,0x41,
9120x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x2c,0x20,
9130x49,0x6e,0x63,0x2e,0x31,0x3e,0x30,0x3c,0x06,0x03,0x55,0x04,0x0b,0x13,0x35,
9140x44,0x69,0x67,0x69,0x74,0x61,0x6c,0x20,0x49,0x44,0x20,0x43,0x6c,0x61,0x73,
9150x73,0x20,0x33,0x20,0x2d,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
9160x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x56,0x61,0x6c,0x69,0x64,
9170x61,0x74,0x69,0x6f,0x6e,0x20,0x76,0x32,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,
9180x04,0x03,0x14,0x14,0x41,0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,
9190x74,0x65,0x72,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x30,0x81,0x9f,0x30,0x0d,0x06,
9200x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,
9210x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xd3,0xab,0x3b,0x7f,0xec,0x48,0x84,
9220xce,0xa8,0x1a,0x12,0xf3,0x3c,0x87,0xcb,0x24,0x58,0x96,0x02,0x87,0x66,0x49,
9230xeb,0x89,0xee,0x79,0x44,0x70,0x8d,0xe7,0xd4,0x1f,0x30,0x92,0xc0,0x9c,0x35,
9240x78,0xc0,0xaf,0x1c,0xb6,0x28,0xd3,0xe0,0xe0,0x9d,0xd3,0x49,0x76,0x73,0x57,
9250x19,0x4d,0x8d,0x70,0x85,0x64,0x4d,0x1d,0xc6,0x02,0x3e,0xe5,0x2c,0x66,0x07,
9260xd2,0x27,0x4b,0xd6,0xc8,0x3c,0x93,0xb6,0x15,0x0c,0xde,0x5b,0xd7,0x93,0xdd,
9270xbe,0x85,0x62,0x34,0x17,0x8a,0x05,0x60,0xf0,0x8a,0x1c,0x5a,0x40,0x21,0x8d,
9280x51,0x6c,0xb0,0x62,0xd8,0xb5,0xd4,0xf9,0xb1,0xd0,0x58,0x7a,0x7a,0x82,0x55,
9290xb3,0xf9,0x53,0x71,0xde,0xd2,0xc9,0x37,0x8c,0xf6,0x5a,0x1f,0x2d,0xcd,0x7c,
9300x67,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30,
9310x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06,0x03,0x55,
9320x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x40,0x06,0x03,
9330x55,0x1d,0x1f,0x04,0x39,0x30,0x37,0x30,0x35,0xa0,0x33,0xa0,0x31,0x86,0x2f,
9340x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,
9350x34,0x2d,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,
9360x63,0x6f,0x6d,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2e,0x63,
9370x72,0x6c,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b,0x30,0x39,
9380x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,0x03,0x30,0x2a,
9390x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1c,0x68,
9400x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,
9410x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x30,0x13,0x06,
9420x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
9430x07,0x03,0x03,0x30,0x75,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
9440x04,0x69,0x30,0x67,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,
9450x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,
9460x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x3f,0x06,
9470x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x33,0x68,0x74,0x74,0x70,
9480x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,
9490x61,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,
9500x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,0x61,0x2e,0x63,
9510x65,0x72,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
9520x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,0x36,0x7c,0x68,0xcf,0x5b,0x78,
9530xa8,0xdf,0xb9,0xc5,0x37,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,
9540x42,0x01,0x01,0x04,0x04,0x03,0x02,0x04,0x10,0x30,0x16,0x06,0x0a,0x2b,0x06,
9550x01,0x04,0x01,0x82,0x37,0x02,0x01,0x1b,0x04,0x08,0x30,0x06,0x01,0x01,0x00,
9560x01,0x01,0xff,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
9570x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6a,0xa6,0x06,0xd0,0x33,0x18,0x64,
9580xe2,0x69,0x82,0xee,0x6e,0x36,0x9e,0x9d,0x9a,0x0e,0x18,0xa8,0xac,0x9d,0x10,
9590xed,0x01,0x3c,0xb9,0x61,0x04,0x62,0xf3,0x85,0x8f,0xcc,0x4f,0x2c,0x66,0x35,
9600x54,0x25,0x45,0x8d,0x95,0x1c,0xd2,0x33,0xbe,0x2e,0xdd,0x7f,0x74,0xaf,0x03,
9610x7b,0x86,0x63,0xb0,0xc9,0xe6,0xbd,0xc7,0x8e,0xde,0x03,0x18,0x98,0x82,0xc3,
9620xbb,0xf8,0x15,0x99,0x1a,0xa9,0xdd,0xb9,0x5d,0xb9,0xbd,0x53,0x95,0x25,0x76,
9630xfb,0x5c,0x53,0x90,0xea,0x01,0x0a,0xa0,0xb1,0xbf,0x09,0x1b,0x97,0x8f,0x40,
9640xfa,0x85,0x12,0x74,0x01,0xdb,0xf6,0xdb,0x09,0xd6,0x5f,0x4f,0xd7,0x17,0xb4,
9650xbf,0x9e,0x2f,0x86,0x52,0x5d,0x70,0x24,0x52,0x32,0x1e,0xa5,0x1d,0x39,0x8b,
9660x66,0xf6,0xba,0x9b,0x69,0x8e,0x12,0x60,0xdb,0xb6,0xcf,0xe6,0x0d,0xd6,0x1c,
9670x8f,0xd4,0x5b,0x4b,0x00,0xde,0x21,0x93,0xfb,0x6e,0xc7,0x3d,0xb4,0x66,0x0d,
9680x29,0x0c,0x4e,0xe9,0x3f,0x94,0xd6,0xd6,0xdc,0xec,0xf8,0x53,0x3b,0x62,0xd5,
9690x97,0x50,0x53,0x84,0x17,0xfe,0xe2,0xed,0x4c,0x23,0x0a,0x49,0xce,0x5b,0xe9,
9700x70,0x31,0xc1,0x04,0x02,0x02,0x6c,0xb8,0x52,0xcd,0xc7,0x4e,0x70,0xb4,0x13,
9710xd7,0xe0,0x92,0xba,0x44,0x1a,0x10,0x4c,0x6e,0x45,0xc6,0x86,0x04,0xc6,0x64,
9720xd3,0x9c,0x6e,0xc1,0x9c,0xac,0x74,0x3d,0x77,0x06,0x5e,0x28,0x28,0x5c,0xf5,
9730xe0,0x9c,0x19,0xd8,0xba,0x74,0x81,0x2d,0x67,0x77,0x93,0x8d,0xbf,0xd2,0x52,
9740x00,0xe6,0xa5,0x38,0x4e,0x2e,0x73,0x66,0x7a };
975static BYTE iTunesIssuer[] = {
9760x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
9770x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,
9780x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
9790x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,
9800x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
9810x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,
9820x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,
9830x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,0x73,
9840x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,
9850x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,
9860x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,
9870x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,
9880x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
9890x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,
9900x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,
9910x20,0x43,0x41 };
992static BYTE iTunesSerialNum[] = {
9930x8d,0xf6,0x6a,0xdf,0xd2,0x40,0xfe,0xb6,0xa6,0x61,0x9b,0x9b,
9940xe0,0xa0,0x1a,0x0f };
995
996static void testFindCert(void)
997{
998 HCERTSTORE store;
999 PCCERT_CONTEXT context = NULL, subject;
1000 BOOL ret;
1001 CERT_INFO certInfo = { 0 };
1002 CRYPT_HASH_BLOB blob;
1003 BYTE otherSerialNumber[] = { 2 };
1004
1005 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1006 CERT_STORE_CREATE_NEW_FLAG, NULL);
1007 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1008 if (!store)
1009 return;
1010
1011 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1012 bigCert, sizeof(bigCert), CERT_STORE_ADD_NEW, NULL);
1013 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1014 GetLastError());
1015 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1016 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
1017 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1018 GetLastError());
1019 /* This has the same name as bigCert */
1020 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1021 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1022 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1023 GetLastError());
1024
1025 /* Crashes
1026 context = CertFindCertificateInStore(NULL, 0, 0, 0, NULL, NULL);
1027 */
1028
1029 /* Check first cert's there, by issuer */
1030 certInfo.Subject.pbData = subjectName;
1031 certInfo.Subject.cbData = sizeof(subjectName);
1032 certInfo.SerialNumber.pbData = serialNum;
1033 certInfo.SerialNumber.cbData = sizeof(serialNum);
1034 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1035 CERT_FIND_ISSUER_NAME, &certInfo.Subject, NULL);
1036 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1037 GetLastError());
1038 if (context)
1039 {
1040 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1041 CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
1042 ok(context != NULL, "Expected more than one cert\n");
1043 if (context)
1044 {
1045 context = CertFindCertificateInStore(store, X509_ASN_ENCODING,
1046 0, CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
1047 ok(context == NULL, "Expected precisely two certs\n");
1048 }
1049 }
1050
1051 /* Check second cert's there as well, by subject name */
1052 certInfo.Subject.pbData = subjectName2;
1053 certInfo.Subject.cbData = sizeof(subjectName2);
1054 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1055 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, NULL);
1056 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1057 GetLastError());
1058 if (context)
1059 {
1060 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1061 CERT_FIND_SUBJECT_NAME, &certInfo.Subject, context);
1062 ok(context == NULL, "Expected one cert only\n");
1063 }
1064
1065 /* Strange but true: searching for the subject cert requires you to set
1066 * the issuer, not the subject
1067 */
1068 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1069 CERT_FIND_SUBJECT_CERT, &certInfo.Subject, NULL);
1070 ok(context == NULL, "Expected no certificate\n");
1071 certInfo.Subject.pbData = NULL;
1072 certInfo.Subject.cbData = 0;
1073 certInfo.Issuer.pbData = subjectName2;
1074 certInfo.Issuer.cbData = sizeof(subjectName2);
1075 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1076 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1077 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1078 GetLastError());
1079 if (context)
1080 {
1081 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1082 CERT_FIND_SUBJECT_CERT, &certInfo.Subject, context);
1083 ok(context == NULL, "Expected one cert only\n");
1084 }
1085 /* A non-matching serial number will not match. */
1086 certInfo.SerialNumber.pbData = otherSerialNumber;
1087 certInfo.SerialNumber.cbData = sizeof(otherSerialNumber);
1088 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1089 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1090 ok(context == NULL, "Expected no match\n");
1091 /* No serial number will not match */
1092 certInfo.SerialNumber.cbData = 0;
1093 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1094 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1095 ok(context == NULL, "Expected no match\n");
1096 /* A serial number still won't match if the name doesn't */
1097 certInfo.SerialNumber.pbData = serialNum;
1098 certInfo.SerialNumber.cbData = sizeof(serialNum);
1099 certInfo.Issuer.pbData = subjectName3;
1100 certInfo.Issuer.cbData = sizeof(subjectName3);
1101 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1102 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1103 ok(context == NULL, "Expected no match\n");
1104
1105 /* The nice thing about hashes, they're unique */
1106 blob.pbData = bigCertHash;
1107 blob.cbData = sizeof(bigCertHash);
1108 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1109 CERT_FIND_SHA1_HASH, &blob, NULL);
1110 ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1111 GetLastError());
1112 if (context)
1113 {
1114 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1115 CERT_FIND_SHA1_HASH, &certInfo.Subject, context);
1116 ok(context == NULL, "Expected one cert only\n");
1117 }
1118
1119 CertCloseStore(store, 0);
1120
1121 /* Another subject cert search, using iTunes's certs */
1122 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1123 CERT_STORE_CREATE_NEW_FLAG, NULL);
1124 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1125 iTunesCert0, sizeof(iTunesCert0), CERT_STORE_ADD_NEW, NULL);
1126 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1127 GetLastError());
1128 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1129 iTunesCert1, sizeof(iTunesCert1), CERT_STORE_ADD_NEW, NULL);
1130 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1131 GetLastError());
1132 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1133 iTunesCert2, sizeof(iTunesCert2), CERT_STORE_ADD_NEW, NULL);
1134 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1135 GetLastError());
1136 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1137 iTunesCert3, sizeof(iTunesCert3), CERT_STORE_ADD_NEW, &subject);
1138 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1139 GetLastError());
1140
1141 /* The certInfo's issuer does not match any subject, but the serial
1142 * number does match a cert whose issuer matches certInfo's issuer.
1143 * This yields a match.
1144 */
1145 certInfo.SerialNumber.cbData = sizeof(iTunesSerialNum);
1146 certInfo.SerialNumber.pbData = iTunesSerialNum;
1147 certInfo.Issuer.cbData = sizeof(iTunesIssuer);
1148 certInfo.Issuer.pbData = iTunesIssuer;
1149 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1150 CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1151 ok(context != NULL, "Expected a match\n");
1152 if (context)
1153 {
1154 ret = CertCompareCertificateName(context->dwCertEncodingType,
1155 &certInfo.Issuer, &context->pCertInfo->Subject);
1156 ok(!ret, "Expected subject name not to match\n");
1157 ret = CertCompareCertificateName(context->dwCertEncodingType,
1158 &certInfo.Issuer, &context->pCertInfo->Issuer);
1159 ok(ret, "Expected issuer name to match\n");
1160 ret = CertCompareIntegerBlob(&certInfo.SerialNumber,
1161 &context->pCertInfo->SerialNumber);
1162 ok(ret, "Expected serial number to match\n");
1163 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1164 CERT_FIND_SUBJECT_CERT, &certInfo, context);
1165 ok(context == NULL, "Expected one cert only\n");
1166 }
1167
1168 context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1169 CERT_FIND_ISSUER_OF, subject, NULL);
1170 ok(context != NULL, "Expected an issuer\n");
1171 if (context)
1172 {
1173 PCCERT_CONTEXT none = CertFindCertificateInStore(store,
1174 X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_OF, context, NULL);
1175
1176 ok(!none, "Expected no parent of issuer\n");
1177 CertFreeCertificateContext(context);
1178 }
1179 CertFreeCertificateContext(subject);
1180 CertCloseStore(store, 0);
1181}
1182
1183static void testGetSubjectCert(void)
1184{
1185 HCERTSTORE store;
1186 PCCERT_CONTEXT context1, context2;
1187 CERT_INFO info = { 0 };
1188 BOOL ret;
1189
1190 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1191 CERT_STORE_CREATE_NEW_FLAG, NULL);
1192 ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1193 if (!store)
1194 return;
1195
1196 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1197 bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1198 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1199 GetLastError());
1200 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1201 bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, &context1);
1202 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1203 GetLastError());
1204 ok(context1 != NULL, "Expected a context\n");
1205 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1206 certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1207 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1208 GetLastError());
1209
1210 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1211 NULL);
1212 ok(!context2 && GetLastError() == E_INVALIDARG,
1213 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1214 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1215 &info);
1216 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1217 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1218 info.SerialNumber.cbData = sizeof(serialNum);
1219 info.SerialNumber.pbData = serialNum;
1220 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1221 &info);
1222 ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1223 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1224 info.Issuer.cbData = sizeof(subjectName2);
1225 info.Issuer.pbData = subjectName2;
1226 context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1227 &info);
1228 ok(context2 != NULL,
1229 "CertGetSubjectCertificateFromStore failed: %08x\n", GetLastError());
1230 /* Not only should this find a context, but it should be the same
1231 * (same address) as context1.
1232 */
1233 ok(context1 == context2, "Expected identical context addresses\n");
1234 CertFreeCertificateContext(context2);
1235
1236 CertFreeCertificateContext(context1);
1237 CertCloseStore(store, 0);
1238}
1239
1240/* This expires in 1970 or so */
1241static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
1242 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
1243 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
1244 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1245 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1246 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1247 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
1248 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
1249 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1250 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1251 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1252 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
1253 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
1254 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
1255 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
1256 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
1257 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
1258 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
1259 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
1260 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
1261 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
1262 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
1263 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
1264 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
1265 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
1266
1267/* This expires in 2036 or so */
1268static const BYTE childOfExpired[] = { 0x30, 0x81, 0xcc, 0x30, 0x78, 0xa0,
1269 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
1270 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d,
1271 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63,
1272 0x40, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e,
1273 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x35, 0x30, 0x35,
1274 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x35,
1275 0x30, 0x35, 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x30, 0x15, 0x31, 0x13,
1276 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e,
1277 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03,
1278 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
1279 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x20, 0x3b, 0xdb, 0x4d, 0x67, 0x50,
1280 0xec, 0x73, 0x9d, 0xf9, 0x85, 0x5d, 0x18, 0xe9, 0xb4, 0x98, 0xe3, 0x31, 0xb7,
1281 0x03, 0x0b, 0xc0, 0x39, 0x93, 0x56, 0x81, 0x0a, 0xfc, 0x78, 0xa8, 0x29, 0x42,
1282 0x5f, 0x69, 0xfb, 0xbc, 0x5b, 0xf2, 0xa6, 0x2a, 0xbe, 0x91, 0x2c, 0xfc, 0x89,
1283 0x69, 0x15, 0x18, 0x58, 0xe5, 0x02, 0x75, 0xf7, 0x2a, 0xb6, 0xa9, 0xfb, 0x47,
1284 0x6a, 0x6e, 0x0a, 0x9b, 0xe9, 0xdc };
1285/* chain10_0 -+
1286 * +-> chain7_1
1287 * chain10_1 -+
1288 * A chain with two issuers, only one of whose dates is valid.
1289 */
1290static const BYTE chain10_0[] = {
12910x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
12920x4a,0x30,0x3a,0x42,0xa2,0x5a,0xb3,0x93,0x4d,0x94,0x06,0xad,0x6d,0x1c,0x34,
12930xe6,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
12940x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
12950x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
12960x30,0x5a,0x17,0x0d,0x30,0x36,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
12970x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
12980x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
12990x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
13000x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
13010x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
13020x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
13030x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
13040xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
13050x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
13060x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
13070xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
13080x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
13090x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
13100x81,0x00,0x85,0x6e,0x35,0x2f,0x2c,0x51,0x4f,0xd6,0x2a,0xe4,0x9e,0xd0,0x4b,
13110xe6,0x90,0xfd,0xf7,0x20,0xad,0x76,0x3f,0x93,0xea,0x7f,0x0d,0x1f,0xb3,0x8e,
13120xfd,0xe0,0xe1,0xd6,0xd7,0x9c,0x7d,0x46,0x6b,0x15,0x5c,0xe6,0xc9,0x62,0x3b,
13130x70,0x4a,0x4b,0xb2,0x82,0xe3,0x55,0x0c,0xc4,0x90,0x44,0x06,0x6c,0x86,0x1c,
13140x6d,0x47,0x12,0xda,0x33,0x95,0x5d,0x98,0x43,0xcb,0x7c,0xfa,0x2b,0xee,0xc4,
13150x2d,0xc8,0x95,0x33,0x89,0x08,0x3f,0x9f,0x87,0xea,0x20,0x04,0xaf,0x58,0x4b,
13160x9d,0xc0,0x7c,0x0a,0x1b,0x05,0x31,0x3b,0xbb,0x13,0x58,0x2e,0x3f,0x61,0x6b,
13170x10,0xb4,0xeb,0xb9,0x1a,0x30,0xfd,0xea,0xca,0x29,0x99,0x5f,0x42,0x2b,0x00,
13180xb0,0x08,0xc3,0xf0,0xb6,0xd6,0x6b,0xf9,0x35,0x95 };
1319static const BYTE chain10_1[] = {
13200x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
13210xbf,0x99,0x4f,0x14,0x03,0x77,0x44,0xb8,0x49,0x02,0x70,0xa1,0xb8,0x9c,0xa7,
13220x24,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
13230x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
13240x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
13250x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
13260x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
13270x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
13280x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
13290x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
13300x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
13310x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
13320x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
13330xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
13340x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
13350x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
13360xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
13370x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
13380x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
13390x81,0x00,0xa8,0xec,0x8c,0x34,0xe7,0x2c,0xdf,0x75,0x87,0xc4,0xf7,0xda,0x71,
13400x72,0x29,0xb2,0x48,0xa8,0x2a,0xec,0x7b,0x7d,0x19,0xb9,0x5f,0x1d,0xd9,0x91,
13410x2b,0xc4,0x28,0x7e,0xd6,0xb5,0x91,0x69,0xa5,0x8a,0x1a,0x1f,0x97,0x98,0x46,
13420x9d,0xdf,0x12,0xf6,0x45,0x62,0xad,0x60,0xb6,0xba,0xb0,0xfd,0xf5,0x9f,0xc6,
13430x98,0x05,0x4f,0x4d,0x48,0xdc,0xee,0x69,0xbe,0xb8,0xc4,0xc4,0xd7,0x1b,0xb1,
13440x1f,0x64,0xd6,0x45,0xa7,0xdb,0xb3,0x87,0x63,0x0f,0x54,0xe1,0x3a,0x6b,0x57,
13450x36,0xd7,0x68,0x65,0xcf,0xda,0x57,0x8d,0xcd,0x84,0x75,0x47,0x26,0x2c,0xef,
13460x1e,0x8f,0xc7,0x3b,0xee,0x5d,0x03,0xa6,0xdf,0x3a,0x20,0xb2,0xcc,0xc9,0x09,
13470x2c,0xfe,0x2b,0x79,0xb0,0xca,0x2c,0x9a,0x81,0x6b };
1348static const BYTE chain7_1[] = {
13490x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
13500x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,
13510x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,
13520x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,
13530x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,
13540x35,0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,
13550x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,
13560x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,
13570x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,
13580x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,
13590xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,
13600x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,
13610xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,
13620x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,
13630x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,
13640xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,
13650x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,
13660x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
13670x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9f,0x69,0xfd,0x26,0xd5,0x4b,
13680xe0,0xab,0x12,0x21,0xb9,0xfc,0xf7,0xe0,0x0c,0x09,0x94,0xad,0x27,0xd7,0x9d,
13690xa3,0xcc,0x46,0x2a,0x25,0x9a,0x24,0xa7,0x31,0x58,0x78,0xf5,0xfc,0x30,0xe1,
13700x6d,0xfd,0x59,0xab,0xbe,0x69,0xa0,0xea,0xe3,0x7d,0x7a,0x7b,0xe5,0x85,0xeb,
13710x86,0x6a,0x84,0x3c,0x96,0x01,0x1a,0x70,0xa7,0xb8,0xcb,0xf2,0x11,0xe7,0x52,
13720x9c,0x58,0x2d,0xac,0x63,0xce,0x72,0x4b,0xad,0x62,0xa8,0x1d,0x75,0x96,0xe2,
13730x27,0xf5,0x6f,0xba,0x91,0xf8,0xf1,0xb0,0xbf,0x90,0x24,0x6d,0xba,0x5d,0xd7,
13740x39,0x63,0x3b,0x7c,0x04,0x5d,0x89,0x9d,0x1c,0xf2,0xf7,0xcc,0xdf,0x6e,0x8a,
13750x43,0xa9,0xdd,0x86,0x05,0xa2,0xf3,0x22,0x2d,0x1e,0x70,0xa1,0x59,0xd7,0xa5,
13760x94,0x7d };
1377
1378static void testGetIssuerCert(void)
1379{
1380 BOOL ret;
1381 PCCERT_CONTEXT parent, child, cert1, cert2;
1382 DWORD flags = 0xffffffff;
1383 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1384 CERT_STORE_CREATE_NEW_FLAG, NULL);
1385
1386 ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1387
1388 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1389 expiredCert, sizeof(expiredCert), CERT_STORE_ADD_ALWAYS, NULL);
1390 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1391 GetLastError());
1392
1393 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1394 childOfExpired, sizeof(childOfExpired), CERT_STORE_ADD_ALWAYS, &child);
1395 ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1396 GetLastError());
1397
1398 /* These crash:
1399 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, NULL);
1400 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, NULL);
1401 */
1402 parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, &flags);
1403 ok(!parent && GetLastError() == E_INVALIDARG,
1404 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1405 parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, &flags);
1406 ok(!parent && GetLastError() == E_INVALIDARG,
1407 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1408 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1409 ok(!parent && GetLastError() == E_INVALIDARG,
1410 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1411 /* Confusing: the caller cannot set either of the
1412 * CERT_STORE_NO_*_FLAGs, as these are not checks,
1413 * they're results:
1414 */
1415 flags = CERT_STORE_NO_CRL_FLAG | CERT_STORE_NO_ISSUER_FLAG;
1416 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1417 ok(!parent && GetLastError() == E_INVALIDARG,
1418 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1419 /* Perform no checks */
1420 flags = 0;
1421 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1422 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1423 GetLastError());
1424 if (parent)
1425 CertFreeCertificateContext(parent);
1426 /* Check revocation and signature only */
1427 flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG;
1428 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1429 ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1430 GetLastError());
1431 /* Confusing: CERT_STORE_REVOCATION_FLAG succeeds when there is no CRL by
1432 * setting CERT_STORE_NO_CRL_FLAG.
1433 */
1434 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
1435 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
1436 flags);
1437 if (parent)
1438 CertFreeCertificateContext(parent);
1439 /* Checking time validity is not productive, because while most Windows
1440 * versions return 0 (time valid) because the child is not expired,
1441 * Windows 2003 SP1 returns that it is expired. Thus the range of
1442 * possibilities is covered, and a test verifies nothing.
1443 */
1444
1445 CertFreeCertificateContext(child);
1446 CertCloseStore(store, 0);
1447
1448 flags = 0;
1449 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1450 CERT_STORE_CREATE_NEW_FLAG, NULL);
1451 /* With only the child certificate, no issuer will be found */
1452 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1453 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1454 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1455 ok(parent == NULL, "Expected no issuer\n");
1456 /* Adding an issuer allows one (and only one) issuer to be found */
1457 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1458 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert1);
1459 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1460 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1461 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1462 ok(parent == NULL, "Expected only one issuer\n");
1463 /* Adding a second issuer allows two issuers to be found - and the second
1464 * issuer is found before the first, implying certs are added to the head
1465 * of a list.
1466 */
1467 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1468 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert2);
1469 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1470 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1471 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1472 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1473 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1474 ok(parent == NULL, "Expected no more than two issuers\n");
1475 CertFreeCertificateContext(child);
1476 CertFreeCertificateContext(cert1);
1477 CertFreeCertificateContext(cert2);
1478 CertCloseStore(store, 0);
1479
1480 /* Repeat the test, reversing the order in which issuers are added,
1481 * to show it's order-dependent.
1482 */
1483 store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1484 CERT_STORE_CREATE_NEW_FLAG, NULL);
1485 /* With only the child certificate, no issuer will be found */
1486 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1487 chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1488 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1489 ok(parent == NULL, "Expected no issuer\n");
1490 /* Adding an issuer allows one (and only one) issuer to be found */
1491 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1492 chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert1);
1493 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1494 ok(parent == cert1, "Expected cert1 to be the issuer\n");
1495 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1496 ok(parent == NULL, "Expected only one issuer\n");
1497 /* Adding a second issuer allows two issuers to be found - and the second
1498 * issuer is found before the first, implying certs are added to the head
1499 * of a list.
1500 */
1501 ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1502 chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert2);
1503 parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1504 ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1505 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1506 ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1507 parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1508 ok(parent == NULL, "Expected no more than two issuers\n");
1509 CertFreeCertificateContext(child);
1510 CertFreeCertificateContext(cert1);
1511 CertFreeCertificateContext(cert2);
1512 CertCloseStore(store, 0);
1513}
1514
1515static void testCryptHashCert(void)
1516{
1517 static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b,
1518 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07,
1519 0x09 };
1520 static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee,
1521 0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8,
1522 0xa2 };
1523 static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:";
1524 BOOL ret;
1525 BYTE hash[20];
1526 DWORD hashLen = sizeof(hash);
1527
1528 /* NULL buffer and nonzero length crashes
1529 ret = CryptHashCertificate(0, 0, 0, NULL, size, hash, &hashLen);
1530 empty hash length also crashes
1531 ret = CryptHashCertificate(0, 0, 0, buf, size, hash, NULL);
1532 */
1533 /* Test empty hash */
1534 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), NULL,
1535 &hashLen);
1536 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1537 ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen);
1538 /* Test with empty buffer */
1539 ret = CryptHashCertificate(0, 0, 0, NULL, 0, hash, &hashLen);
1540 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1541 ok(!memcmp(hash, emptyHash, sizeof(emptyHash)),
1542 "Unexpected hash of nothing\n");
1543 /* Test a known value */
1544 ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), hash,
1545 &hashLen);
1546 ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1547 ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
1548}
1549
1550static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen,
1551 const BYTE *sig, unsigned int sigLen)
1552{
1553 HCRYPTHASH hash;
1554 BOOL ret = CryptCreateHash(csp, CALG_SHA1, 0, 0, &hash);
1555
1556 ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
1557 if (ret)
1558 {
1559 BYTE mySig[64];
1560 DWORD mySigSize = sizeof(mySig);
1561
1562 ret = CryptHashData(hash, toSign, toSignLen, 0);
1563 ok(ret, "CryptHashData failed: %08x\n", GetLastError());
1564 /* use the A variant so the test can run on Win9x */
1565 ret = CryptSignHashA(hash, AT_SIGNATURE, NULL, 0, mySig, &mySigSize);
1566 ok(ret, "CryptSignHash failed: %08x\n", GetLastError());
1567 if (ret)
1568 {
1569 ok(mySigSize == sigLen, "Expected sig length %d, got %d\n",
1570 sigLen, mySigSize);
1571 ok(!memcmp(mySig, sig, sigLen), "Unexpected signature\n");
1572 }
1573 CryptDestroyHash(hash);
1574 }
1575}
1576
1577/* Tests signing the certificate described by toBeSigned with the CSP passed in,
1578 * using the algorithm with OID sigOID. The CSP is assumed to be empty, and a
1579 * keyset named AT_SIGNATURE will be added to it. The signing key will be
1580 * stored in *key, and the signature will be stored in sig. sigLen should be
1581 * at least 64 bytes.
1582 */
1583static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1584 LPCSTR sigOID, HCRYPTKEY *key, BYTE *sig, DWORD *sigLen)
1585{
1586 BOOL ret;
1587 DWORD size = 0;
1588 CRYPT_ALGORITHM_IDENTIFIER algoID = { NULL, { 0, NULL } };
1589
1590 /* These all crash
1591 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1592 ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, &size);
1593 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1594 NULL, NULL, NULL, &size);
1595 */
1596 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1597 &algoID, NULL, NULL, &size);
1598 ok(!ret && GetLastError() == NTE_BAD_ALGID,
1599 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1600 algoID.pszObjId = (LPSTR)sigOID;
1601 ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1602 &algoID, NULL, NULL, &size);
1603 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1604 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1605 GetLastError());
1606 ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData,
1607 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1608 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1609 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1610 GetLastError());
1611
1612 /* No keys exist in the new CSP yet.. */
1613 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1614 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1615 ok(!ret && (GetLastError() == NTE_BAD_KEYSET || GetLastError() ==
1616 NTE_NO_KEY), "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %08x\n",
1617 GetLastError());
1618 ret = CryptGenKey(csp, AT_SIGNATURE, 0, key);
1619 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1620 if (ret)
1621 {
1622 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1623 toBeSigned->cbData, &algoID, NULL, NULL, &size);
1624 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1625 ok(size <= *sigLen, "Expected size <= %d, got %d\n", *sigLen, size);
1626 if (ret)
1627 {
1628 ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1629 toBeSigned->cbData, &algoID, NULL, sig, &size);
1630 ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1631 if (ret)
1632 {
1633 *sigLen = size;
1634 verifySig(csp, toBeSigned->pbData, toBeSigned->cbData, sig,
1635 size);
1636 }
1637 }
1638 }
1639}
1640
1641static void testVerifyCertSig(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1642 LPCSTR sigOID, const BYTE *sig, DWORD sigLen)
1643{
1644 CERT_SIGNED_CONTENT_INFO info;
1645 LPBYTE cert = NULL;
1646 DWORD size = 0;
1647 BOOL ret;
1648
1649 if (!pCryptVerifyCertificateSignatureEx)
1650 {
1651 skip("no CryptVerifyCertificateSignatureEx support\n");
1652 return;
1653 }
1654 if (!pCryptEncodeObjectEx)
1655 {
1656 skip("no CryptEncodeObjectEx support\n");
1657 return;
1658 }
1659 ret = pCryptVerifyCertificateSignatureEx(0, 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, 0, 0, NULL, 0, NULL, 0, NULL);
1663 ok(!ret && GetLastError() == E_INVALIDARG,
1664 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1665 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 0, NULL, 0,
1666 NULL, 0, NULL);
1667 ok(!ret && GetLastError() == E_INVALIDARG,
1668 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1669 /* This crashes
1670 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1671 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, NULL, 0, NULL, 0, NULL);
1672 */
1673 info.ToBeSigned.cbData = toBeSigned->cbData;
1674 info.ToBeSigned.pbData = toBeSigned->pbData;
1675 info.SignatureAlgorithm.pszObjId = (LPSTR)sigOID;
1676 info.SignatureAlgorithm.Parameters.cbData = 0;
1677 info.Signature.cbData = sigLen;
1678 info.Signature.pbData = (BYTE *)sig;
1679 info.Signature.cUnusedBits = 0;
1680 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT, &info,
1681 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&cert, &size);
1682 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1683 if (cert)
1684 {
1685 CRYPT_DATA_BLOB certBlob = { 0, NULL };
1686 PCERT_PUBLIC_KEY_INFO pubKeyInfo = NULL;
1687
1688 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1689 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1690 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
1691 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
1692 certBlob.cbData = 1;
1693 certBlob.pbData = (void *)0xdeadbeef;
1694 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1695 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1696 ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
1697 GetLastError() == CRYPT_E_ASN1_EOD /* Win9x */ ||
1698 GetLastError() == CRYPT_E_ASN1_BADTAG /* Win98 */),
1699 "Expected STATUS_ACCESS_VIOLATION, CRYPT_E_ASN1_EOD, OR CRYPT_E_ASN1_BADTAG, got %08x\n",
1700 GetLastError());
1701
1702 certBlob.cbData = size;
1703 certBlob.pbData = cert;
1704 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1705 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1706 ok(!ret && GetLastError() == E_INVALIDARG,
1707 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1708 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1709 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1710 CRYPT_VERIFY_CERT_SIGN_ISSUER_NULL, NULL, 0, NULL);
1711 ok(!ret && GetLastError() == E_INVALIDARG,
1712 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1713 /* This crashes
1714 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1715 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1716 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, NULL, 0, NULL);
1717 */
1718 CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
1719 (LPSTR)sigOID, 0, NULL, NULL, &size);
1720 pubKeyInfo = HeapAlloc(GetProcessHeap(), 0, size);
1721 if (pubKeyInfo)
1722 {
1723 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
1724 X509_ASN_ENCODING, (LPSTR)sigOID, 0, NULL, pubKeyInfo, &size);
1725 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
1726 if (ret)
1727 {
1728 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1729 CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1730 CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pubKeyInfo, 0, NULL);
1731 ok(ret, "CryptVerifyCertificateSignatureEx failed: %08x\n",
1732 GetLastError());
1733 }
1734 HeapFree(GetProcessHeap(), 0, pubKeyInfo);
1735 }
1736 LocalFree(cert);
1737 }
1738}
1739
1740static BYTE emptyCert[] = { 0x30, 0x00 };
1741
1742static void testCertSigs(void)
1743{
1744 HCRYPTPROV csp;
1745 CRYPT_DATA_BLOB toBeSigned = { sizeof(emptyCert), emptyCert };
1746 BOOL ret;
1747 HCRYPTKEY key;
1748 BYTE sig[64];
1749 DWORD sigSize = sizeof(sig);
1750
1751 /* Just in case a previous run failed, delete this thing */
1752 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1753 CRYPT_DELETEKEYSET);
1754 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1755 CRYPT_NEWKEYSET);
1756 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1757
1758 testSignCert(csp, &toBeSigned, szOID_RSA_SHA1RSA, &key, sig, &sigSize);
1759 testVerifyCertSig(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize);
1760
1761 CryptDestroyKey(key);
1762 CryptReleaseContext(csp, 0);
1763 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1764 CRYPT_DELETEKEYSET);
1765}
1766
1767static const BYTE md5SignedEmptyCert[] = {
17680x30,0x56,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
17690x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
17700x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
17710x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
17720x0d,0x02,0x05,0x05,0x00,0x03,0x11,0x00,0xfb,0x0f,0x66,0x82,0x66,0xd9,0xe5,0xf8,
17730xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
1774static const BYTE md5SignedEmptyCertNoNull[] = {
17750x30,0x54,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
17760x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
17770x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
17780x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
17790x0d,0x02,0x05,0x03,0x11,0x00,0x04,0xd9,0xa5,0xe1,0x2b,0x55,0xa2,0xd8,0xf8,0xe5,
17800xd9,0x66,0x82,0x66,0x0f,0xfb };
1781
1782static void testSignAndEncodeCert(void)
1783{
1784 static char oid_rsa_md5rsa[] = szOID_RSA_MD5RSA;
1785 static char oid_rsa_md5[] = szOID_RSA_MD5;
1786 BOOL ret;
1787 DWORD size;
1788 CRYPT_ALGORITHM_IDENTIFIER algID = { 0 };
1789 CERT_INFO info = { 0 };
1790
1791 /* Crash
1792 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1793 NULL);
1794 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1795 &size);
1796 */
1797 ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, &algID, NULL, NULL,
1798 &size);
1799 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1800 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1801 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, NULL, NULL,
1802 &algID, NULL, NULL, &size);
1803 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1804 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1805 ret = CryptSignAndEncodeCertificate(0, 0, 0, X509_CERT_TO_BE_SIGNED, NULL,
1806 &algID, NULL, NULL, &size);
1807 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1808 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1809 /* Crashes on some win9x boxes */
1810 if (0)
1811 {
1812 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1813 X509_CERT_TO_BE_SIGNED, NULL, &algID, NULL, NULL, &size);
1814 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1815 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1816 }
1817 /* Crashes
1818 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1819 X509_CERT_TO_BE_SIGNED, &info, NULL, NULL, NULL, &size);
1820 */
1821 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1822 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1823 ok(!ret &&
1824 (GetLastError() == NTE_BAD_ALGID ||
1825 GetLastError() == OSS_BAD_PTR), /* win9x */
1826 "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1827 algID.pszObjId = oid_rsa_md5rsa;
1828 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1829 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1830 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1831 "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1832 GetLastError());
1833 algID.pszObjId = oid_rsa_md5;
1834 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1835 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1836 /* oid_rsa_md5 not present in some win2k */
1837 if (ret)
1838 {
1839 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
1840
1841 if (buf)
1842 {
1843 ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1844 X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, buf, &size);
1845 ok(ret, "CryptSignAndEncodeCertificate failed: %08x\n",
1846 GetLastError());
1847 /* Tricky: because the NULL parameters may either be omitted or
1848 * included as an asn.1-encoded NULL (0x05,0x00), two different
1849 * values are allowed.
1850 */
1851 ok(size == sizeof(md5SignedEmptyCert) ||
1852 size == sizeof(md5SignedEmptyCertNoNull), "Unexpected size %d\n",
1853 size);
1854 if (size == sizeof(md5SignedEmptyCert))
1855 ok(!memcmp(buf, md5SignedEmptyCert, size),
1856 "Unexpected value\n");
1857 else if (size == sizeof(md5SignedEmptyCertNoNull))
1858 ok(!memcmp(buf, md5SignedEmptyCertNoNull, size),
1859 "Unexpected value\n");
1860 HeapFree(GetProcessHeap(), 0, buf);
1861 }
1862 }
1863}
1864
1865static void testCreateSelfSignCert(void)
1866{
1867 PCCERT_CONTEXT context;
1868 CERT_NAME_BLOB name = { sizeof(subjectName), subjectName };
1869 HCRYPTPROV csp;
1870 BOOL ret;
1871 HCRYPTKEY key;
1872 CRYPT_KEY_PROV_INFO info;
1873
1874 if (!pCertCreateSelfSignCertificate)
1875 {
1876 skip("CertCreateSelfSignCertificate() is not available\n");
1877 return;
1878 }
1879
1880 /* This crashes:
1881 context = pCertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL,
1882 NULL);
1883 * Calling this with no first parameter creates a new key container, which
1884 * lasts beyond the test, so I don't test that. Nb: the generated key
1885 * name is a GUID.
1886 context = pCertCreateSelfSignCertificate(0, &name, 0, NULL, NULL, NULL, NULL,
1887 NULL);
1888 */
1889
1890 /* Acquire a CSP */
1891 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1892 CRYPT_DELETEKEYSET);
1893 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1894 CRYPT_NEWKEYSET);
1895 ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1896
1897 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1898 NULL, NULL);
1899 ok(!context && GetLastError() == NTE_NO_KEY,
1900 "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1901 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
1902 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1903 if (ret)
1904 {
1905 context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1906 NULL, NULL);
1907 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1908 GetLastError());
1909 if (context)
1910 {
1911 DWORD size = 0;
1912 PCRYPT_KEY_PROV_INFO info;
1913
1914 /* The context must have a key provider info property */
1915 ret = CertGetCertificateContextProperty(context,
1916 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1917 ok(ret && size, "Expected non-zero key provider info\n");
1918 if (size)
1919 {
1920 info = HeapAlloc(GetProcessHeap(), 0, size);
1921 if (info)
1922 {
1923 ret = CertGetCertificateContextProperty(context,
1924 CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1925 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1926 GetLastError());
1927 if (ret)
1928 {
1929 /* Sanity-check the key provider */
1930 ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1931 "Unexpected key container\n");
1932 ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1933 "Unexpected provider\n");
1934 ok(info->dwKeySpec == AT_SIGNATURE,
1935 "Expected AT_SIGNATURE, got %d\n", info->dwKeySpec);
1936 }
1937 HeapFree(GetProcessHeap(), 0, info);
1938 }
1939 }
1940
1941 CertFreeCertificateContext(context);
1942 }
1943
1944 CryptDestroyKey(key);
1945 }
1946
1947 CryptReleaseContext(csp, 0);
1948 ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1949 CRYPT_DELETEKEYSET);
1950
1951 /* do the same test with AT_KEYEXCHANGE and key info*/
1952 memset(&info,0,sizeof(info));
1953 info.dwProvType = PROV_RSA_FULL;
1954 info.dwKeySpec = AT_KEYEXCHANGE;
1955 info.pwszProvName = (LPWSTR) MS_DEF_PROV_W;
1956 info.pwszContainerName = cspNameW;
1957 context = pCertCreateSelfSignCertificate(0, &name, 0, &info, NULL, NULL,
1958 NULL, NULL);
1959 ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1960 GetLastError());
1961 if (context)
1962 {
1963 DWORD size = 0;
1964 PCRYPT_KEY_PROV_INFO info;
1965
1966 /* The context must have a key provider info property */
1967 ret = CertGetCertificateContextProperty(context,
1968 CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1969 ok(ret && size, "Expected non-zero key provider info\n");
1970 if (size)
1971 {
1972 info = HeapAlloc(GetProcessHeap(), 0, size);
1973 if (info)
1974 {
1975 ret = CertGetCertificateContextProperty(context,
1976 CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1977 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1978 GetLastError());
1979 if (ret)
1980 {
1981 /* Sanity-check the key provider */
1982 ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1983 "Unexpected key container\n");
1984 ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1985 "Unexpected provider\n");
1986 ok(info->dwKeySpec == AT_KEYEXCHANGE,
1987 "Expected AT_KEYEXCHANGE, got %d\n", info->dwKeySpec);
1988 }
1989 HeapFree(GetProcessHeap(), 0, info);
1990 }
1991 }
1992
1993 CertFreeCertificateContext(context);
1994 }
1995
1996 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1997 CRYPT_DELETEKEYSET);
1998}
1999
2000static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
2001 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
2002
2003static void testKeyUsage(void)
2004{
2005 BOOL ret;
2006 PCCERT_CONTEXT context;
2007 DWORD size;
2008
2009 /* Test base cases */
2010 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, NULL);
2011 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2012 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2013 size = 1;
2014 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
2015 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2016 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2017 size = 0;
2018 ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
2019 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2020 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2021 /* These crash
2022 ret = CertSetEnhancedKeyUsage(NULL, NULL);
2023 usage.cUsageIdentifier = 0;
2024 ret = CertSetEnhancedKeyUsage(NULL, &usage);
2025 */
2026 /* Test with a cert with no enhanced key usage extension */
2027 context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2028 sizeof(bigCert));
2029 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2030 GetLastError());
2031 if (context)
2032 {
2033 static const char oid[] = "1.2.3.4";
2034 BYTE buf[sizeof(CERT_ENHKEY_USAGE) + 2 * (sizeof(LPSTR) + sizeof(oid))];
2035 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2036
2037 ret = CertGetEnhancedKeyUsage(context, 0, NULL, NULL);
2038 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2039 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2040 size = 1;
2041 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &size);
2042 if (ret)
2043 {
2044 /* Windows 2000, ME, or later: even though it succeeded, we expect
2045 * CRYPT_E_NOT_FOUND, which indicates there is no enhanced key
2046 * usage set for this cert (which implies it's valid for all uses.)
2047 */
2048 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2049 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2050 ok(size == sizeof(CERT_ENHKEY_USAGE), "Wrong size %d\n", size);
2051 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2052 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2053 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2054 pUsage->cUsageIdentifier);
2055 }
2056 else
2057 {
2058 /* Windows NT, 95, or 98: it fails, and the last error is
2059 * CRYPT_E_NOT_FOUND.
2060 */
2061 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2062 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2063 }
2064 /* I can add a usage identifier when no key usage has been set */
2065 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2066 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2067 GetLastError());
2068 size = sizeof(buf);
2069 ret = CertGetEnhancedKeyUsage(context,
2070 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2071 ok(ret && GetLastError() == 0,
2072 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2073 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2074 pUsage->cUsageIdentifier);
2075 if (pUsage->cUsageIdentifier)
2076 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2077 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2078 /* Now set an empty key usage */
2079 pUsage->cUsageIdentifier = 0;
2080 ret = CertSetEnhancedKeyUsage(context, pUsage);
2081 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2082 /* Shouldn't find it in the cert */
2083 size = sizeof(buf);
2084 ret = CertGetEnhancedKeyUsage(context,
2085 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2086 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2087 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2088 /* Should find it as an extended property */
2089 ret = CertGetEnhancedKeyUsage(context,
2090 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2091 ok(ret && GetLastError() == 0,
2092 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2093 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2094 pUsage->cUsageIdentifier);
2095 /* Should find it as either */
2096 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2097 ok(ret && GetLastError() == 0,
2098 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2099 ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2100 pUsage->cUsageIdentifier);
2101 /* Add a usage identifier */
2102 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2103 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2104 GetLastError());
2105 size = sizeof(buf);
2106 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2107 ok(ret && GetLastError() == 0,
2108 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2109 ok(pUsage->cUsageIdentifier == 1, "Expected 1 identifier, got %d\n",
2110 pUsage->cUsageIdentifier);
2111 if (pUsage->cUsageIdentifier)
2112 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2113 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2114 /* Re-adding the same usage identifier succeeds, though it only adds
2115 * a duplicate usage identifier on versions prior to Vista
2116 */
2117 ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2118 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2119 GetLastError());
2120 size = sizeof(buf);
2121 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2122 ok(ret && GetLastError() == 0,
2123 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2124 ok(pUsage->cUsageIdentifier == 1 || pUsage->cUsageIdentifier == 2,
2125 "Expected 1 or 2 identifiers, got %d\n", pUsage->cUsageIdentifier);
2126 if (pUsage->cUsageIdentifier)
2127 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2128 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2129 if (pUsage->cUsageIdentifier >= 2)
2130 ok(!strcmp(pUsage->rgpszUsageIdentifier[1], oid),
2131 "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[1]);
2132 /* Now set a NULL extended property--this deletes the property. */
2133 ret = CertSetEnhancedKeyUsage(context, NULL);
2134 ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2135 SetLastError(0xbaadcafe);
2136 size = sizeof(buf);
2137 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2138 ok(GetLastError() == CRYPT_E_NOT_FOUND,
2139 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2140
2141 CertFreeCertificateContext(context);
2142 }
2143 /* Now test with a cert with an enhanced key usage extension */
2144 context = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2145 sizeof(certWithUsage));
2146 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2147 GetLastError());
2148 if (context)
2149 {
2150 LPBYTE buf = NULL;
2151 DWORD bufSize = 0, i;
2152
2153 /* The size may depend on what flags are used to query it, so I
2154 * realloc the buffer for each test.
2155 */
2156 ret = CertGetEnhancedKeyUsage(context,
2157 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2158 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2159 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2160 if (buf)
2161 {
2162 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2163
2164 /* Should find it in the cert */
2165 size = bufSize;
2166 ret = CertGetEnhancedKeyUsage(context,
2167 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2168 ok(ret && GetLastError() == 0,
2169 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2170 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2171 pUsage->cUsageIdentifier);
2172 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2173 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2174 "Expected %s, got %s\n", keyUsages[i],
2175 pUsage->rgpszUsageIdentifier[i]);
2176 HeapFree(GetProcessHeap(), 0, buf);
2177 }
2178 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2179 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2180 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2181 if (buf)
2182 {
2183 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2184
2185 /* Should find it as either */
2186 size = bufSize;
2187 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2188 /* In Windows, GetLastError returns CRYPT_E_NOT_FOUND not found
2189 * here, even though the return is successful and the usage id
2190 * count is positive. I don't enforce that here.
2191 */
2192 ok(ret,
2193 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2194 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2195 pUsage->cUsageIdentifier);
2196 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2197 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2198 "Expected %s, got %s\n", keyUsages[i],
2199 pUsage->rgpszUsageIdentifier[i]);
2200 HeapFree(GetProcessHeap(), 0, buf);
2201 }
2202 /* Shouldn't find it as an extended property */
2203 ret = CertGetEnhancedKeyUsage(context,
2204 CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &size);
2205 ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2206 "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2207 /* Adding a usage identifier overrides the cert's usage!? */
2208 ret = CertAddEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2209 ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2210 GetLastError());
2211 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2212 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2213 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2214 if (buf)
2215 {
2216 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2217
2218 /* Should find it as either */
2219 size = bufSize;
2220 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2221 ok(ret,
2222 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2223 ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2224 pUsage->cUsageIdentifier);
2225 ok(!strcmp(pUsage->rgpszUsageIdentifier[0], szOID_RSA_RSA),
2226 "Expected %s, got %s\n", szOID_RSA_RSA,
2227 pUsage->rgpszUsageIdentifier[0]);
2228 HeapFree(GetProcessHeap(), 0, buf);
2229 }
2230 /* But querying the cert directly returns its usage */
2231 ret = CertGetEnhancedKeyUsage(context,
2232 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2233 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2234 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2235 if (buf)
2236 {
2237 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2238
2239 size = bufSize;
2240 ret = CertGetEnhancedKeyUsage(context,
2241 CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2242 ok(ret,
2243 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2244 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2245 pUsage->cUsageIdentifier);
2246 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2247 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2248 "Expected %s, got %s\n", keyUsages[i],
2249 pUsage->rgpszUsageIdentifier[i]);
2250 HeapFree(GetProcessHeap(), 0, buf);
2251 }
2252 /* And removing the only usage identifier in the extended property
2253 * results in the cert's key usage being found.
2254 */
2255 ret = CertRemoveEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2256 ok(ret, "CertRemoveEnhancedKeyUsage failed: %08x\n", GetLastError());
2257 ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2258 ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2259 buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2260 if (buf)
2261 {
2262 PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2263
2264 /* Should find it as either */
2265 size = bufSize;
2266 ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2267 ok(ret,
2268 "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2269 ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2270 pUsage->cUsageIdentifier);
2271 for (i = 0; i < pUsage->cUsageIdentifier; i++)
2272 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2273 "Expected %s, got %s\n", keyUsages[i],
2274 pUsage->rgpszUsageIdentifier[i]);
2275 HeapFree(GetProcessHeap(), 0, buf);
2276 }
2277
2278 CertFreeCertificateContext(context);
2279 }
2280}
2281
2282static const BYTE cert2WithUsage[] = {
22830x30,0x81,0x89,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
22840x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
22850x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
22860x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
22870x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
22880x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
22890x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x25,0x30,0x23,
22900x30,0x21,0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x17,0x30,0x15,0x06,
22910x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x2a,0x86,0x48,0x86,
22920xf7,0x0d,0x01,0x01,0x01 };
2293
2294static void testGetValidUsages(void)
2295{
2296 static const LPCSTR expectedOIDs[] = {
2297 "1.3.6.1.5.5.7.3.3",
2298 "1.3.6.1.5.5.7.3.2",
2299 "1.2.840.113549.1.1.1",
2300 };
2301 static const LPCSTR expectedOIDs2[] = {
2302 "1.3.6.1.5.5.7.3.2",
2303 "1.2.840.113549.1.1.1",
2304 };
2305 BOOL ret;
2306 int numOIDs;
2307 DWORD size;
2308 LPSTR *oids = NULL;
2309 PCCERT_CONTEXT contexts[3];
2310
2311 if (!pCertGetValidUsages)
2312 {
2313 skip("CertGetValidUsages() is not available\n");
2314 return;
2315 }
2316
2317 /* Crash
2318 ret = pCertGetValidUsages(0, NULL, NULL, NULL, NULL);
2319 ret = pCertGetValidUsages(0, NULL, NULL, NULL, &size);
2320 */
2321 contexts[0] = NULL;
2322 numOIDs = size = 0xdeadbeef;
2323 SetLastError(0xdeadbeef);
2324 ret = pCertGetValidUsages(1, &contexts[0], &numOIDs, NULL, &size);
2325 ok(ret, "CertGetValidUsages failed: %d\n", GetLastError());
2326 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2327 ok(size == 0, "Expected size 0, got %d\n", size);
2328 contexts[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2329 sizeof(bigCert));
2330 contexts[1] = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2331 sizeof(certWithUsage));
2332 contexts[2] = CertCreateCertificateContext(X509_ASN_ENCODING,
2333 cert2WithUsage, sizeof(cert2WithUsage));
2334 numOIDs = size = 0xdeadbeef;
2335 ret = pCertGetValidUsages(0, NULL, &numOIDs, NULL, &size);
2336 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2337 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2338 ok(size == 0, "Expected size 0, got %d\n", size);
2339 numOIDs = size = 0xdeadbeef;
2340 ret = pCertGetValidUsages(1, contexts, &numOIDs, NULL, &size);
2341 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2342 ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2343 ok(size == 0, "Expected size 0, got %d\n", size);
2344 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, NULL, &size);
2345 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2346 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2347 ok(size, "Expected non-zero size\n");
2348 oids = HeapAlloc(GetProcessHeap(), 0, size);
2349 if (oids)
2350 {
2351 int i;
2352 DWORD smallSize = 1;
2353
2354 SetLastError(0xdeadbeef);
2355 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &smallSize);
2356 ok(!ret && GetLastError() == ERROR_MORE_DATA,
2357 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
2358 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2359 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2360 for (i = 0; i < numOIDs; i++)
2361 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2362 oids[i]);
2363 HeapFree(GetProcessHeap(), 0, oids);
2364 }
2365 numOIDs = size = 0xdeadbeef;
2366 /* Oddly enough, this crashes when the number of contexts is not 1:
2367 ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2368 * but setting size to 0 allows it to succeed:
2369 */
2370 size = 0;
2371 ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2372 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2373 ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2374 ok(size, "Expected non-zero size\n");
2375 oids = HeapAlloc(GetProcessHeap(), 0, size);
2376 if (oids)
2377 {
2378 int i;
2379
2380 ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2381 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2382 for (i = 0; i < numOIDs; i++)
2383 ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2384 oids[i]);
2385 HeapFree(GetProcessHeap(), 0, oids);
2386 }
2387 numOIDs = 0xdeadbeef;
2388 size = 0;
2389 ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, NULL, &size);
2390 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2391 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2392 ok(size, "Expected non-zero size\n");
2393 oids = HeapAlloc(GetProcessHeap(), 0, size);
2394 if (oids)
2395 {
2396 int i;
2397
2398 ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, oids, &size);
2399 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2400 for (i = 0; i < numOIDs; i++)
2401 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2402 oids[i]);
2403 HeapFree(GetProcessHeap(), 0, oids);
2404 }
2405 numOIDs = 0xdeadbeef;
2406 size = 0;
2407 ret = pCertGetValidUsages(3, contexts, &numOIDs, NULL, &size);
2408 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2409 ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2410 ok(size, "Expected non-zero size\n");
2411 oids = HeapAlloc(GetProcessHeap(), 0, size);
2412 if (oids)
2413 {
2414 int i;
2415
2416 ret = pCertGetValidUsages(3, contexts, &numOIDs, oids, &size);
2417 ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2418 for (i = 0; i < numOIDs; i++)
2419 ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2420 oids[i]);
2421 HeapFree(GetProcessHeap(), 0, oids);
2422 }
2423 CertFreeCertificateContext(contexts[0]);
2424 CertFreeCertificateContext(contexts[1]);
2425 CertFreeCertificateContext(contexts[2]);
2426}
2427
2428static void testCompareCertName(void)
2429{
2430 static BYTE bogus[] = { 1, 2, 3, 4 };
2431 static BYTE bogusPrime[] = { 0, 1, 2, 3, 4 };
2432 static BYTE emptyPrime[] = { 0x30, 0x00, 0x01 };
2433 BOOL ret;
2434 CERT_NAME_BLOB blob1, blob2;
2435
2436 /* crashes
2437 ret = CertCompareCertificateName(0, NULL, NULL);
2438 */
2439 /* An empty name checks against itself.. */
2440 blob1.pbData = emptyCert;
2441 blob1.cbData = sizeof(emptyCert);
2442 ret = CertCompareCertificateName(0, &blob1, &blob1);
2443 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2444 /* It doesn't have to be a valid encoded name.. */
2445 blob1.pbData = bogus;
2446 blob1.cbData = sizeof(bogus);
2447 ret = CertCompareCertificateName(0, &blob1, &blob1);
2448 ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2449 /* Leading zeroes matter.. */
2450 blob2.pbData = bogusPrime;
2451 blob2.cbData = sizeof(bogusPrime);
2452 ret = CertCompareCertificateName(0, &blob1, &blob2);
2453 ok(!ret, "Expected failure\n");
2454 /* As do trailing extra bytes. */
2455 blob2.pbData = emptyPrime;
2456 blob2.cbData = sizeof(emptyPrime);
2457 ret = CertCompareCertificateName(0, &blob1, &blob2);
2458 ok(!ret, "Expected failure\n");
2459}
2460
2461static BYTE int1[] = { 0x88, 0xff, 0xff, 0xff };
2462static BYTE int2[] = { 0x88, 0xff };
2463static BYTE int3[] = { 0x23, 0xff };
2464static BYTE int4[] = { 0x7f, 0x00 };
2465static BYTE int5[] = { 0x7f };
2466static BYTE int6[] = { 0x80, 0x00, 0x00, 0x00 };
2467static BYTE int7[] = { 0x80, 0x00 };
2468
2469static struct IntBlobTest
2470{
2471 CRYPT_INTEGER_BLOB blob1;
2472 CRYPT_INTEGER_BLOB blob2;
2473 BOOL areEqual;
2474} intBlobs[] = {
2475 { { sizeof(int1), int1 }, { sizeof(int2), int2 }, TRUE },
2476 { { sizeof(int3), int3 }, { sizeof(int3), int3 }, TRUE },
2477 { { sizeof(int4), int4 }, { sizeof(int5), int5 }, TRUE },
2478 { { sizeof(int6), int6 }, { sizeof(int7), int7 }, TRUE },
2479 { { sizeof(int1), int1 }, { sizeof(int7), int7 }, FALSE },
2480};
2481
2482static void testCompareIntegerBlob(void)
2483{
2484 DWORD i;
2485 BOOL ret;
2486
2487 for (i = 0; i < sizeof(intBlobs) / sizeof(intBlobs[0]); i++)
2488 {
2489 ret = CertCompareIntegerBlob(&intBlobs[i].blob1, &intBlobs[i].blob2);
2490 ok(ret == intBlobs[i].areEqual,
2491 "%d: expected blobs %s compare\n", i, intBlobs[i].areEqual ?
2492 "to" : "not to");
2493 }
2494}
2495
2496static void testComparePublicKeyInfo(void)
2497{
2498 BOOL ret;
2499 CERT_PUBLIC_KEY_INFO info1 = { { 0 } }, info2 = { { 0 } };
2500 static CHAR oid_rsa_rsa[] = szOID_RSA_RSA;
2501 static CHAR oid_rsa_sha1rsa[] = szOID_RSA_SHA1RSA;
2502 static CHAR oid_x957_dsa[] = szOID_X957_DSA;
2503 static BYTE bits1[] = { 1, 0 };
2504 static BYTE bits2[] = { 0 };
2505 static BYTE bits3[] = { 1 };
2506 static BYTE bits4[] = { 0x30,8, 2,1,0x81, 2,3,1,0,1 };
2507 static BYTE bits5[] = { 0x30,9, 2,2,0,0x81, 2,3,1,0,1 };
2508 static BYTE bits6[] = { 0x30,9, 2,2,0,0x82, 2,3,1,0,1 };
2509
2510 /* crashes
2511 ret = CertComparePublicKeyInfo(0, NULL, NULL);
2512 */
2513 /* Empty public keys compare */
2514 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2515 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2516 /* Different OIDs appear to compare */
2517 info1.Algorithm.pszObjId = oid_rsa_rsa;
2518 info2.Algorithm.pszObjId = oid_rsa_sha1rsa;
2519 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2520 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2521 info2.Algorithm.pszObjId = oid_x957_dsa;
2522 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2523 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2524 info1.PublicKey.cbData = sizeof(bits1);
2525 info1.PublicKey.pbData = bits1;
2526 info1.PublicKey.cUnusedBits = 0;
2527 info2.PublicKey.cbData = sizeof(bits1);
2528 info2.PublicKey.pbData = bits1;
2529 info2.PublicKey.cUnusedBits = 0;
2530 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2531 ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2532 info2.Algorithm.pszObjId = oid_rsa_rsa;
2533 info1.PublicKey.cbData = sizeof(bits4);
2534 info1.PublicKey.pbData = bits4;
2535 info1.PublicKey.cUnusedBits = 0;
2536 info2.PublicKey.cbData = sizeof(bits5);
2537 info2.PublicKey.pbData = bits5;
2538 info2.PublicKey.cUnusedBits = 0;
2539 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2540 ok(!ret, "CertComparePublicKeyInfo: as raw binary: keys should be unequal\n");
2541 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2542 ok(ret ||
2543 broken(!ret), /* win9x */
2544 "CertComparePublicKeyInfo: as ASN.1 encoded: keys should be equal\n");
2545 info1.PublicKey.cUnusedBits = 1;
2546 info2.PublicKey.cUnusedBits = 5;
2547 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2548 ok(ret ||
2549 broken(!ret), /* win9x */
2550 "CertComparePublicKeyInfo: ASN.1 encoding should ignore cUnusedBits\n");
2551 info1.PublicKey.cUnusedBits = 0;
2552 info2.PublicKey.cUnusedBits = 0;
2553 info1.PublicKey.cbData--; /* kill one byte, make ASN.1 encoded data invalid */
2554 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2555 ok(!ret, "CertComparePublicKeyInfo: comparing bad ASN.1 encoded key should fail\n");
2556 /* Even though they compare in their used bits, these do not compare */
2557 info1.PublicKey.cbData = sizeof(bits2);
2558 info1.PublicKey.pbData = bits2;
2559 info1.PublicKey.cUnusedBits = 0;
2560 info2.PublicKey.cbData = sizeof(bits3);
2561 info2.PublicKey.pbData = bits3;
2562 info2.PublicKey.cUnusedBits = 1;
2563 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2564 /* Simple (non-comparing) case */
2565 ok(!ret, "Expected keys not to compare\n");
2566 info2.PublicKey.cbData = sizeof(bits1);
2567 info2.PublicKey.pbData = bits1;
2568 info2.PublicKey.cUnusedBits = 0;
2569 ret = CertComparePublicKeyInfo(0, &info1, &info2);
2570 ok(!ret, "Expected keys not to compare\n");
2571 /* ASN.1 encoded non-comparing case */
2572 info1.PublicKey.cbData = sizeof(bits5);
2573 info1.PublicKey.pbData = bits5;
2574 info1.PublicKey.cUnusedBits = 0;
2575 info2.PublicKey.cbData = sizeof(bits6);
2576 info2.PublicKey.pbData = bits6;
2577 info2.PublicKey.cUnusedBits = 0;
2578 ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2579 ok(!ret, "CertComparePublicKeyInfo: different keys should be unequal\n");
2580}
2581
2582static void testHashPublicKeyInfo(void)
2583{
2584 BOOL ret;
2585 CERT_PUBLIC_KEY_INFO info = { { 0 } };
2586 DWORD len;
2587
2588 /* Crash
2589 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, NULL);
2590 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, &info, NULL, NULL);
2591 */
2592 ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, &len);
2593 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2594 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2595 /* Crashes on some win9x boxes */
2596 if (0)
2597 {
2598 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, NULL, NULL, &len);
2599 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2600 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2601 }
2602 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, NULL, &len);
2603 ok(ret ||
2604 broken(!ret), /* win9x */
2605 "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2606 if (ret)
2607 {
2608 ok(len == 16, "Expected hash size 16, got %d\n", len);
2609 if (len == 16)
2610 {
2611 static const BYTE emptyHash[] = { 0xb8,0x51,0x3a,0x31,0x0e,0x9f,0x40,
2612 0x36,0x9c,0x92,0x45,0x1b,0x9d,0xc8,0xf9,0xf6 };
2613 BYTE buf[16];
2614
2615 ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, buf,
2616 &len);
2617 ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2618 ok(!memcmp(buf, emptyHash, len), "Unexpected hash\n");
2619 }
2620 }
2621}
2622
2623static const BYTE md5SignedEmptyCertHash[] = { 0xfb,0x0f,0x66,0x82,0x66,0xd9,
2624 0xe5,0xf8,0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
2625
2626static void testHashToBeSigned(void)
2627{
2628 BOOL ret;
2629 DWORD size;
2630 BYTE hash[16];
2631
2632 /* Crash */
2633 if (0)
2634 {
2635 ret = CryptHashToBeSigned(0, 0, NULL, 0, NULL, NULL);
2636 }
2637 SetLastError(0xdeadbeef);
2638 ret = CryptHashToBeSigned(0, 0, NULL, 0, NULL, &size);
2639 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2640 "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
2641 SetLastError(0xdeadbeef);
2642 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, NULL, 0, NULL, &size);
2643 ok(!ret &&
2644 (GetLastError() == CRYPT_E_ASN1_EOD ||
2645 GetLastError() == OSS_BAD_ARG), /* win9x */
2646 "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2647 /* Can't sign anything: has to be asn.1 encoded, at least */
2648 SetLastError(0xdeadbeef);
2649 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, int1, sizeof(int1),
2650 NULL, &size);
2651 ok(!ret &&
2652 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2653 GetLastError() == OSS_MORE_INPUT), /* win9x */
2654 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2655 /* Can't be empty, either */
2656 SetLastError(0xdeadbeef);
2657 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, emptyCert,
2658 sizeof(emptyCert), NULL, &size);
2659 ok(!ret &&
2660 (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2661 GetLastError() == OSS_DATA_ERROR), /* win9x */
2662 "expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2663 /* Signing a cert works */
2664 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert,
2665 sizeof(md5SignedEmptyCert), NULL, &size);
2666 ok(ret ||
2667 broken(!ret), /* win9x */
2668 "CryptHashToBeSigned failed: %08x\n", GetLastError());
2669 if (ret)
2670 {
2671 ok(size == sizeof(md5SignedEmptyCertHash), "unexpected size %d\n", size);
2672 }
2673
2674 ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert,
2675 sizeof(md5SignedEmptyCert), hash, &size);
2676 ok(!memcmp(hash, md5SignedEmptyCertHash, size), "unexpected value\n");
2677}
2678
2679static void testCompareCert(void)
2680{
2681 CERT_INFO info1 = { 0 }, info2 = { 0 };
2682 BOOL ret;
2683
2684 /* Crashes
2685 ret = CertCompareCertificate(X509_ASN_ENCODING, NULL, NULL);
2686 */
2687
2688 /* Certs with the same issuer and serial number are equal, even if they
2689 * differ in other respects (like subject).
2690 */
2691 info1.SerialNumber.pbData = serialNum;
2692 info1.SerialNumber.cbData = sizeof(serialNum);
2693 info1.Issuer.pbData = subjectName;
2694 info1.Issuer.cbData = sizeof(subjectName);
2695 info1.Subject.pbData = subjectName2;
2696 info1.Subject.cbData = sizeof(subjectName2);
2697 info2.SerialNumber.pbData = serialNum;
2698 info2.SerialNumber.cbData = sizeof(serialNum);
2699 info2.Issuer.pbData = subjectName;
2700 info2.Issuer.cbData = sizeof(subjectName);
2701 info2.Subject.pbData = subjectName;
2702 info2.Subject.cbData = sizeof(subjectName);
2703 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2704 ok(ret, "Expected certs to be equal\n");
2705
2706 info2.Issuer.pbData = subjectName2;
2707 info2.Issuer.cbData = sizeof(subjectName2);
2708 ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2709 ok(!ret, "Expected certs not to be equal\n");
2710}
2711
2712static void testVerifySubjectCert(void)
2713{
2714 BOOL ret;
2715 DWORD flags;
2716 PCCERT_CONTEXT context1, context2;
2717
2718 /* Crashes
2719 ret = CertVerifySubjectCertificateContext(NULL, NULL, NULL);
2720 */
2721 flags = 0;
2722 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2723 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2724 GetLastError());
2725 flags = CERT_STORE_NO_CRL_FLAG;
2726 ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2727 ok(!ret && GetLastError() == E_INVALIDARG,
2728 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2729
2730 flags = 0;
2731 context1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2732 sizeof(bigCert));
2733 ret = CertVerifySubjectCertificateContext(NULL, context1, &flags);
2734 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2735 GetLastError());
2736 ret = CertVerifySubjectCertificateContext(context1, NULL, &flags);
2737 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2738 GetLastError());
2739 ret = CertVerifySubjectCertificateContext(context1, context1, &flags);
2740 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2741 GetLastError());
2742
2743 context2 = CertCreateCertificateContext(X509_ASN_ENCODING,
2744 bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject));
2745 SetLastError(0xdeadbeef);
2746 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2747 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2748 GetLastError());
2749 flags = CERT_STORE_REVOCATION_FLAG;
2750 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2751 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2752 GetLastError());
2753 ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
2754 "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
2755 flags);
2756 flags = CERT_STORE_SIGNATURE_FLAG;
2757 ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2758 ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2759 GetLastError());
2760 ok(flags == CERT_STORE_SIGNATURE_FLAG,
2761 "Expected CERT_STORE_SIGNATURE_FLAG, got %08x\n", flags);
2762 CertFreeCertificateContext(context2);
2763
2764 CertFreeCertificateContext(context1);
2765}
2766
2767static void testVerifyRevocation(void)
2768{
2769 BOOL ret;
2770 CERT_REVOCATION_STATUS status = { 0 };
2771 PCCERT_CONTEXT cert = CertCreateCertificateContext(X509_ASN_ENCODING,
2772 bigCert, sizeof(bigCert));
2773
2774 /* Crash
2775 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL);
2776 */
2777 SetLastError(0xdeadbeef);
2778 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2779 ok(!ret && GetLastError() == E_INVALIDARG,
2780 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2781 status.cbSize = sizeof(status);
2782 ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2783 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2784 ret = CertVerifyRevocation(0, 2, 0, NULL, 0, NULL, &status);
2785 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2786 ret = CertVerifyRevocation(2, 0, 0, NULL, 0, NULL, &status);
2787 ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2788 SetLastError(0xdeadbeef);
2789 ret = CertVerifyRevocation(0, 0, 1, (void **)&cert, 0, NULL, &status);
2790 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2791 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2792 SetLastError(0xdeadbeef);
2793 ret = CertVerifyRevocation(0, 2, 1, (void **)&cert, 0, NULL, &status);
2794 ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2795 "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2796
2797 CertFreeCertificateContext(cert);
2798}
2799
2800static BYTE privKey[] = {
2801 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
2802 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
2803 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
2804 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
2805 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
2806 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
2807 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
2808 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
2809 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
2810 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
2811 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
2812 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
2813 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
2814 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
2815 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
2816 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
2817 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
2818 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
2819 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
2820 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
2821 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
2822 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
2823 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
2824 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
2825
2826static const BYTE exportedPublicKeyBlob[] = {
28270x06,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x31,0x00,0x02,0x00,0x00,
28280x01,0x00,0x01,0x00,0x79,0x10,0x1c,0xd0,0x6b,0x10,0x18,0x30,0x94,0x61,0xdc,0x0e,
28290xcb,0x96,0x4e,0x21,0x3f,0x79,0xcd,0xa9,0x17,0x62,0xbc,0xbb,0x61,0x4c,0xe0,0x75,
28300x38,0x6c,0xf3,0xde,0x60,0x86,0x03,0x97,0x65,0xeb,0x1e,0x6b,0xdb,0x53,0x85,0xad,
28310x68,0x21,0xf1,0x5d,0xe7,0x1f,0xe6,0x53,0xb4,0xbb,0x59,0x3e,0x14,0x27,0xb1,0x83,
28320xa7,0x3a,0x54,0xe2 };
2833
2834static const BYTE asnEncodedPublicKey[] = {
28350x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,
28360xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
28370x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,
28380x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
28390x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
2840
2841static void testAcquireCertPrivateKey(void)
2842{
2843 BOOL ret;
2844 PCCERT_CONTEXT cert;
2845 HCRYPTPROV csp;
2846 DWORD size, keySpec;
2847 BOOL callerFree;
2848 CRYPT_KEY_PROV_INFO keyProvInfo;
2849 HCRYPTKEY key;
2850 WCHAR ms_def_prov_w[MAX_PATH];
2851
2852 if (!pCryptAcquireCertificatePrivateKey)
2853 {
2854 skip("CryptAcquireCertificatePrivateKey() is not available\n");
2855 return;
2856 }
2857
2858 lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
2859
2860 keyProvInfo.pwszContainerName = cspNameW;
2861 keyProvInfo.pwszProvName = ms_def_prov_w;
2862 keyProvInfo.dwProvType = PROV_RSA_FULL;
2863 keyProvInfo.dwFlags = 0;
2864 keyProvInfo.cProvParam = 0;
2865 keyProvInfo.rgProvParam = NULL;
2866 keyProvInfo.dwKeySpec = AT_SIGNATURE;
2867
2868 pCryptAcquireContextA(NULL, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2869 CRYPT_DELETEKEYSET);
2870
2871 cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
2872 sizeof(selfSignedCert));
2873
2874 /* Crash
2875 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL, NULL);
2876 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL,
2877 &callerFree);
2878 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, &keySpec,
2879 NULL);
2880 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, NULL, NULL);
2881 ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, &keySpec,
2882 &callerFree);
2883 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, NULL, NULL, NULL);
2884 */
2885
2886 /* Missing private key */
2887 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, NULL, NULL);
2888 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2889 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2890 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2891 &callerFree);
2892 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2893 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2894 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2895 &keyProvInfo);
2896 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2897 &callerFree);
2898 ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2899 "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2900
2901 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2902 CRYPT_NEWKEYSET);
2903 ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
2904 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
2905 if (ret)
2906 {
2907 HCRYPTPROV certCSP;
2908 DWORD size;
2909 CERT_KEY_CONTEXT keyContext;
2910
2911 /* Don't cache provider */
2912 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2913 &keySpec, &callerFree);
2914 ok(ret ||
2915 broken(!ret), /* win95 */
2916 "CryptAcquireCertificatePrivateKey failed: %08x\n",
2917 GetLastError());
2918 if (ret)
2919 {
2920 ok(callerFree, "Expected callerFree to be TRUE\n");
2921 CryptReleaseContext(certCSP, 0);
2922 }
2923
2924 ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2925 NULL, NULL);
2926 ok(ret ||
2927 broken(!ret), /* win95 */
2928 "CryptAcquireCertificatePrivateKey failed: %08x\n",
2929 GetLastError());
2930 CryptReleaseContext(certCSP, 0);
2931
2932 /* Use the key prov info's caching (there shouldn't be any) */
2933 ret = pCryptAcquireCertificatePrivateKey(cert,
2934 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2935 &callerFree);
2936 ok(ret ||
2937 broken(!ret), /* win95 */
2938 "CryptAcquireCertificatePrivateKey failed: %08x\n",
2939 GetLastError());
2940 if (ret)
2941 {
2942 ok(callerFree, "Expected callerFree to be TRUE\n");
2943 CryptReleaseContext(certCSP, 0);
2944 }
2945
2946 /* Cache it (and check that it's cached) */
2947 ret = pCryptAcquireCertificatePrivateKey(cert,
2948 CRYPT_ACQUIRE_CACHE_FLAG, NULL, &certCSP, &keySpec, &callerFree);
2949 ok(ret ||
2950 broken(!ret), /* win95 */
2951 "CryptAcquireCertificatePrivateKey failed: %08x\n",
2952 GetLastError());
2953 ok(!callerFree, "Expected callerFree to be FALSE\n");
2954 size = sizeof(keyContext);
2955 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2956 &keyContext, &size);
2957 ok(ret ||
2958 broken(!ret), /* win95 */
2959 "CertGetCertificateContextProperty failed: %08x\n",
2960 GetLastError());
2961
2962 /* Remove the cached provider */
2963 CryptReleaseContext(keyContext.hCryptProv, 0);
2964 CertSetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID, 0,
2965 NULL);
2966 /* Allow caching via the key prov info */
2967 keyProvInfo.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
2968 CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2969 &keyProvInfo);
2970 /* Now use the key prov info's caching */
2971 ret = pCryptAcquireCertificatePrivateKey(cert,
2972 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2973 &callerFree);
2974 ok(ret ||
2975 broken(!ret), /* win95 */
2976 "CryptAcquireCertificatePrivateKey failed: %08x\n",
2977 GetLastError());
2978 ok(!callerFree, "Expected callerFree to be FALSE\n");
2979 size = sizeof(keyContext);
2980 ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2981 &keyContext, &size);
2982 ok(ret ||
2983 broken(!ret), /* win95 */
2984 "CertGetCertificateContextProperty failed: %08x\n",
2985 GetLastError());
2986 CryptReleaseContext(certCSP, 0);
2987
2988 CryptDestroyKey(key);
2989 }
2990
2991 /* Some sanity-checking on public key exporting */
2992 ret = CryptImportPublicKeyInfo(csp, X509_ASN_ENCODING,
2993 &cert->pCertInfo->SubjectPublicKeyInfo, &key);
2994 ok(ret, "CryptImportPublicKeyInfo failed: %08x\n", GetLastError());
2995 if (ret)
2996 {
2997 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, NULL, &size);
2998 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
2999 if (ret)
3000 {
3001 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size), encodedKey;
3002
3003 ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, buf, &size);
3004 ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
3005 ok(size == sizeof(exportedPublicKeyBlob), "Unexpected size %d\n",
3006 size);
3007 ok(!memcmp(buf, exportedPublicKeyBlob, size), "Unexpected value\n");
3008 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB,
3009 buf, CRYPT_ENCODE_ALLOC_FLAG, NULL, &encodedKey, &size);
3010 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3011 if (ret)
3012 {
3013 ok(size == sizeof(asnEncodedPublicKey), "Unexpected size %d\n",
3014 size);
3015 ok(!memcmp(encodedKey, asnEncodedPublicKey, size),
3016 "Unexpected value\n");
3017 LocalFree(encodedKey);
3018 }
3019 HeapFree(GetProcessHeap(), 0, buf);
3020 }
3021 CryptDestroyKey(key);
3022 }
3023 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
3024 NULL, 0, NULL, NULL, &size);
3025 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
3026 if (ret)
3027 {
3028 PCERT_PUBLIC_KEY_INFO info = HeapAlloc(GetProcessHeap(), 0, size);
3029
3030 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
3031 NULL, 0, NULL, info, &size);
3032 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
3033 if (ret)
3034 {
3035 ok(info->PublicKey.cbData == sizeof(asnEncodedPublicKey),
3036 "Unexpected size %d\n", info->PublicKey.cbData);
3037 ok(!memcmp(info->PublicKey.pbData, asnEncodedPublicKey,
3038 info->PublicKey.cbData), "Unexpected value\n");
3039 }
3040 HeapFree(GetProcessHeap(), 0, info);
3041 }
3042
3043 CryptReleaseContext(csp, 0);
3044 pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
3045 CRYPT_DELETEKEYSET);
3046
3047 CertFreeCertificateContext(cert);
3048}
3049
3050static void testGetPublicKeyLength(void)
3051{
3052 static char oid_rsa_rsa[] = szOID_RSA_RSA;
3053 static char oid_rsa_dh[] = szOID_RSA_DH;
3054 static char bogusOID[] = "1.2.3";
3055 DWORD ret;
3056 CERT_PUBLIC_KEY_INFO info = { { 0 } };
3057 BYTE bogusKey[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
3058 BYTE key[] = { 0x30,0x0f,0x02,0x08,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
3059 0x02,0x03,0x01,0x00,0x01 };
3060
3061 /* Crashes
3062 ret = CertGetPublicKeyLength(0, NULL);
3063 */
3064 /* With an empty public key info */
3065 SetLastError(0xdeadbeef);
3066 ret = CertGetPublicKeyLength(0, &info);
3067 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3068 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3069 ret, GetLastError());
3070 SetLastError(0xdeadbeef);
3071 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3072 ok(ret == 0 &&
3073 (GetLastError() == CRYPT_E_ASN1_EOD ||
3074 GetLastError() == OSS_BAD_ARG), /* win9x */
3075 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
3076 ret, GetLastError());
3077 /* With a nearly-empty public key info */
3078 info.Algorithm.pszObjId = oid_rsa_rsa;
3079 SetLastError(0xdeadbeef);
3080 ret = CertGetPublicKeyLength(0, &info);
3081 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3082 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3083 ret, GetLastError());
3084 SetLastError(0xdeadbeef);
3085 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3086 ok(ret == 0 &&
3087 (GetLastError() == CRYPT_E_ASN1_EOD ||
3088 GetLastError() == OSS_BAD_ARG), /* win9x */
3089 "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
3090 ret, GetLastError());
3091 /* With a bogus key */
3092 info.PublicKey.cbData = sizeof(bogusKey);
3093 info.PublicKey.pbData = bogusKey;
3094 SetLastError(0xdeadbeef);
3095 ret = CertGetPublicKeyLength(0, &info);
3096 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3097 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3098 ret, GetLastError());
3099 SetLastError(0xdeadbeef);
3100 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3101 ok(ret == 0 &&
3102 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3103 GetLastError() == OSS_PDU_MISMATCH), /* win9x */
3104 "Expected length 0 and CRYPT_E_ASN1_BADTAGTAG, got length %d, %08x\n",
3105 ret, GetLastError());
3106 /* With a believable RSA key but a bogus OID */
3107 info.Algorithm.pszObjId = bogusOID;
3108 info.PublicKey.cbData = sizeof(key);
3109 info.PublicKey.pbData = key;
3110 SetLastError(0xdeadbeef);
3111 ret = CertGetPublicKeyLength(0, &info);
3112 ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3113 "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3114 ret, GetLastError());
3115 SetLastError(0xdeadbeef);
3116 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3117 ok(ret == 56, "Expected length 56, got %d\n", ret);
3118 /* An RSA key with the DH OID */
3119 info.Algorithm.pszObjId = oid_rsa_dh;
3120 SetLastError(0xdeadbeef);
3121 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3122 ok(ret == 0 &&
3123 (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3124 GetLastError() == E_INVALIDARG), /* win9x */
3125 "Expected length 0 and CRYPT_E_ASN1_BADTAG, got length %d, %08x\n",
3126 ret, GetLastError());
3127 /* With the RSA OID */
3128 info.Algorithm.pszObjId = oid_rsa_rsa;
3129 SetLastError(0xdeadbeef);
3130 ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3131 ok(ret == 56, "Expected length 56, got %d\n", ret);
3132 /* With the RSA OID and a message encoding */
3133 info.Algorithm.pszObjId = oid_rsa_rsa;
3134 SetLastError(0xdeadbeef);
3135 ret = CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &info);
3136 ok(ret == 56, "Expected length 56, got %d\n", ret);
3137}
3138
3139START_TEST(cert)
3140{
3141 init_function_pointers();
3142
3143 testAddCert();
3144 testCertProperties();
3145 testDupCert();
3146 testFindCert();
3147 testGetSubjectCert();
3148 testGetIssuerCert();
3149
3150 testCryptHashCert();
3151 testCertSigs();
3152 testSignAndEncodeCert();
3153 testCreateSelfSignCert();
3154 testKeyUsage();
3155 testGetValidUsages();
3156 testCompareCertName();
3157 testCompareIntegerBlob();
3158 testComparePublicKeyInfo();
3159 testHashPublicKeyInfo();
3160 testHashToBeSigned();
3161 testCompareCert();
3162 testVerifySubjectCert();
3163 testVerifyRevocation();
3164 testAcquireCertPrivateKey();
3165 testGetPublicKeyLength();
3166}
Note: See TracBrowser for help on using the repository browser.