user32/tests: Fix some window test failures on various Windows platforms.
[wine] / dlls / crypt32 / tests / cert.c
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
32 static BOOL (WINAPI *pCertAddStoreToCollection)(HCERTSTORE,HCERTSTORE,DWORD,DWORD);
33 static PCCERT_CONTEXT (WINAPI *pCertCreateSelfSignCertificate)(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE,PCERT_NAME_BLOB,DWORD,PCRYPT_KEY_PROV_INFO,PCRYPT_ALGORITHM_IDENTIFIER,PSYSTEMTIME,PSYSTEMTIME,PCERT_EXTENSIONS);
34 static BOOL (WINAPI *pCertGetValidUsages)(DWORD,PCCERT_CONTEXT*,int*,LPSTR*,DWORD*);
35 static BOOL (WINAPI *pCryptAcquireCertificatePrivateKey)(PCCERT_CONTEXT,DWORD,void*,HCRYPTPROV_OR_NCRYPT_KEY_HANDLE*,DWORD*,BOOL*);
36 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*);
37 static BOOL (WINAPI * pCryptVerifyCertificateSignatureEx)
38                         (HCRYPTPROV, DWORD, DWORD, void *, DWORD, void *, DWORD, void *);
39
40 static BOOL (WINAPI * pCryptAcquireContextA)
41                         (HCRYPTPROV *, LPCSTR, LPCSTR, DWORD, DWORD);
42
43 static 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
65 static BYTE subjectName[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
66  0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
67  0x6e, 0x67, 0x00 };
68 static BYTE serialNum[] = { 1 };
69 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
70  0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
71  0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
72  0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
73  0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
74  0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
75  0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
76  0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
77  0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
78  0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
79 static BYTE bigCertHash[] = { 0x6e, 0x30, 0x90, 0x71, 0x5f, 0xd9, 0x23,
80  0x56, 0xeb, 0xae, 0x25, 0x40, 0xe6, 0x22, 0xda, 0x19, 0x26, 0x02, 0xa6, 0x08 };
81
82 static const BYTE bigCertWithDifferentSubject[] = { 0x30, 0x7a, 0x02, 0x01, 0x02,
83  0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
84  0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67,
85  0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31,
86  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
87  0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15,
88  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c,
89  0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06,
90  0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
91  0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
92  0x01, 0x01 };
93 static const BYTE bigCertWithDifferentIssuer[] = { 0x30, 0x7a, 0x02, 0x01,
94  0x01, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
95  0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
96  0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
97  0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
98  0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
99  0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
100  0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
101  0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
102  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
103  0x02, 0x01, 0x01 };
104
105 static BYTE subjectName2[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
106  0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61,
107  0x6e, 0x67, 0x00 };
108 static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
109  0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
110  0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
111  0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
112  0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
113  0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
114  0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20,
115  0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
116  0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
117  0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
118 static const BYTE bigCert2WithDifferentSerial[] = { 0x30, 0x7a, 0x02, 0x01,
119  0x02, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
120  0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
121  0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
122  0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
123  0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
124  0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41,
125  0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
126  0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
127  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
128  0x02, 0x01, 0x01 };
129 static BYTE bigCert2Hash[] = { 0x4a, 0x7f, 0x32, 0x1f, 0xcf, 0x3b, 0xc0,
130  0x87, 0x48, 0x2b, 0xa1, 0x86, 0x54, 0x18, 0xe4, 0x3a, 0x0e, 0x53, 0x7e, 0x2b };
131
132 static const BYTE certWithUsage[] = { 0x30, 0x81, 0x93, 0x02, 0x01, 0x01, 0x30,
133  0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
134  0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00,
135  0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
136  0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
137  0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31,
138  0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61,
139  0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00,
140  0x03, 0x01, 0x00, 0xa3, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x1d,
141  0x25, 0x01, 0x01, 0xff, 0x04, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01,
142  0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
143  0x03, 0x02, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
144
145 static 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
322 static 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
349 static CHAR cspNameA[] = "WineCryptTemp";
350 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e','m','p',0 };
351 static const BYTE v1CertWithPubKey[] = {
352 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
353 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
354 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
355 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
356 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
357 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
358 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
359 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
360 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
361 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
362 0x01,0x01 };
363 static const BYTE v1CertWithSubjectKeyId[] = {
364 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
365 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
366 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
367 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
368 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
369 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
370 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
371 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
372 0x4c,0x61,0x6e,0x67,0x00 };
373 static const BYTE subjectKeyId[] = {
374 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
375 static const BYTE selfSignedCert[] = {
376  0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
377  0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
378  0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
379  0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
380  0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
381  0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
382  0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
383  0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
384  0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
385  0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
386  0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
387  0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
388  0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
389  0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
390  0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
391  0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
392  0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
393  0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
394  0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
395  0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
396  0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
397  0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
398  0xa8, 0x76, 0x57, 0x92, 0x36 };
399 static const BYTE selfSignedSignatureHash[] = { 0x07,0x5a,0x3e,0xfd,0x0d,0xf6,
400  0x88,0xeb,0x00,0x64,0xbd,0xc9,0xd6,0xea,0x0a,0x7c,0xcc,0x24,0xdb,0x5d };
401
402 static 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(keyContext.hCryptProv);
555     ret = CertGetCertificateContextProperty(context,
556      CERT_KEY_PROV_HANDLE_PROP_ID, &keyContext.hCryptProv, &size);
557     ok(ret, "Expected to get the CERT_KEY_PROV_HANDLE_PROP_ID, got %08x\n",
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
630 static 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     SetLastError(0xdeadbeef);
667     context = CertDuplicateCertificateContext(NULL);
668     ok(context == NULL, "Expected context to be NULL\n");
669 }
670
671 static BYTE subjectName3[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
672  0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x52, 0x6f, 0x62, 0x20, 0x20, 0x4c, 0x61,
673  0x6e, 0x67, 0x00 };
674 static const BYTE iTunesCert0[] = {
675 0x30,0x82,0x03,0xc4,0x30,0x82,0x03,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
676 0x47,0xbf,0x19,0x95,0xdf,0x8d,0x52,0x46,0x43,0xf7,0xdb,0x6d,0x48,0x0d,0x31,
677 0xa4,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
678 0x00,0x30,0x81,0x8b,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
679 0x5a,0x41,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0c,0x57,0x65,
680 0x73,0x74,0x65,0x72,0x6e,0x20,0x43,0x61,0x70,0x65,0x31,0x14,0x30,0x12,0x06,
681 0x03,0x55,0x04,0x07,0x13,0x0b,0x44,0x75,0x72,0x62,0x61,0x6e,0x76,0x69,0x6c,
682 0x6c,0x65,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x0a,0x13,0x06,0x54,0x68,
683 0x61,0x77,0x74,0x65,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14,
684 0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
685 0x61,0x74,0x69,0x6f,0x6e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13,
686 0x16,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
687 0x6d,0x70,0x69,0x6e,0x67,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x33,0x31,
688 0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x33,0x31,
689 0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x53,0x31,0x0b,0x30,
690 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,
691 0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
692 0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,
693 0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,0x6d,0x65,0x20,
694 0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,0x76,0x69,0x63,
695 0x65,0x73,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,
696 0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,
697 0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa9,0xca,0xb2,0xa4,0xcc,0xcd,0x20,
698 0xaf,0x0a,0x7d,0x89,0xac,0x87,0x75,0xf0,0xb4,0x4e,0xf1,0xdf,0xc1,0x0f,0xbf,
699 0x67,0x61,0xbd,0xa3,0x64,0x1c,0xda,0xbb,0xf9,0xca,0x33,0xab,0x84,0x30,0x89,
700 0x58,0x7e,0x8c,0xdb,0x6b,0xdd,0x36,0x9e,0x0f,0xbf,0xd1,0xec,0x78,0xf2,0x77,
701 0xa6,0x7e,0x6f,0x3c,0xbf,0x93,0xaf,0x0d,0xba,0x68,0xf4,0x6c,0x94,0xca,0xbd,
702 0x52,0x2d,0xab,0x48,0x3d,0xf5,0xb6,0xd5,0x5d,0x5f,0x1b,0x02,0x9f,0xfa,0x2f,
703 0x6b,0x1e,0xa4,0xf7,0xa3,0x9a,0xa6,0x1a,0xc8,0x02,0xe1,0x7f,0x4c,0x52,0xe3,
704 0x0e,0x60,0xec,0x40,0x1c,0x7e,0xb9,0x0d,0xde,0x3f,0xc7,0xb4,0xdf,0x87,0xbd,
705 0x5f,0x7a,0x6a,0x31,0x2e,0x03,0x99,0x81,0x13,0xa8,0x47,0x20,0xce,0x31,0x73,
706 0x0d,0x57,0x2d,0xcd,0x78,0x34,0x33,0x95,0x12,0x99,0x12,0xb9,0xde,0x68,0x2f,
707 0xaa,0xe6,0xe3,0xc2,0x8a,0x8c,0x2a,0xc3,0x8b,0x21,0x87,0x66,0xbd,0x83,0x58,
708 0x57,0x6f,0x75,0xbf,0x3c,0xaa,0x26,0x87,0x5d,0xca,0x10,0x15,0x3c,0x9f,0x84,
709 0xea,0x54,0xc1,0x0a,0x6e,0xc4,0xfe,0xc5,0x4a,0xdd,0xb9,0x07,0x11,0x97,0x22,
710 0x7c,0xdb,0x3e,0x27,0xd1,0x1e,0x78,0xec,0x9f,0x31,0xc9,0xf1,0xe6,0x22,0x19,
711 0xdb,0xc4,0xb3,0x47,0x43,0x9a,0x1a,0x5f,0xa0,0x1e,0x90,0xe4,0x5e,0xf5,0xee,
712 0x7c,0xf1,0x7d,0xab,0x62,0x01,0x8f,0xf5,0x4d,0x0b,0xde,0xd0,0x22,0x56,0xa8,
713 0x95,0xcd,0xae,0x88,0x76,0xae,0xee,0xba,0x0d,0xf3,0xe4,0x4d,0xd9,0xa0,0xfb,
714 0x68,0xa0,0xae,0x14,0x3b,0xb3,0x87,0xc1,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,
715 0x81,0xdb,0x30,0x81,0xd8,0x30,0x34,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
716 0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
717 0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,
718 0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,
719 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
720 0xff,0x02,0x01,0x00,0x30,0x41,0x06,0x03,0x55,0x1d,0x1f,0x04,0x3a,0x30,0x38,
721 0x30,0x36,0xa0,0x34,0xa0,0x32,0x86,0x30,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
722 0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,
723 0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
724 0x6d,0x70,0x69,0x6e,0x67,0x43,0x41,0x2e,0x63,0x72,0x6c,0x30,0x13,0x06,0x03,
725 0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
726 0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,
727 0x02,0x01,0x06,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,0x04,0x1d,0x30,0x1b,0xa4,
728 0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0c,0x54,
729 0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,0x33,0x30,0x0d,0x06,0x09,
730 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,
731 0x4a,0x6b,0xf9,0xea,0x58,0xc2,0x44,0x1c,0x31,0x89,0x79,0x99,0x2b,0x96,0xbf,
732 0x82,0xac,0x01,0xd6,0x1c,0x4c,0xcd,0xb0,0x8a,0x58,0x6e,0xdf,0x08,0x29,0xa3,
733 0x5e,0xc8,0xca,0x93,0x13,0xe7,0x04,0x52,0x0d,0xef,0x47,0x27,0x2f,0x00,0x38,
734 0xb0,0xe4,0xc9,0x93,0x4e,0x9a,0xd4,0x22,0x62,0x15,0xf7,0x3f,0x37,0x21,0x4f,
735 0x70,0x31,0x80,0xf1,0x8b,0x38,0x87,0xb3,0xe8,0xe8,0x97,0x00,0xfe,0xcf,0x55,
736 0x96,0x4e,0x24,0xd2,0xa9,0x27,0x4e,0x7a,0xae,0xb7,0x61,0x41,0xf3,0x2a,0xce,
737 0xe7,0xc9,0xd9,0x5e,0xdd,0xbb,0x2b,0x85,0x3e,0xb5,0x9d,0xb5,0xd9,0xe1,0x57,
738 0xff,0xbe,0xb4,0xc5,0x7e,0xf5,0xcf,0x0c,0x9e,0xf0,0x97,0xfe,0x2b,0xd3,0x3b,
739 0x52,0x1b,0x1b,0x38,0x27,0xf7,0x3f,0x4a };
740 static const BYTE iTunesCert1[] = {
741 0x30,0x82,0x03,0xff,0x30,0x82,0x02,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
742 0x0d,0xe9,0x2b,0xf0,0xd4,0xd8,0x29,0x88,0x18,0x32,0x05,0x09,0x5e,0x9a,0x76,
743 0x88,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
744 0x00,0x30,0x53,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
745 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
746 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,
747 0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
748 0x20,0x54,0x69,0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,
749 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,
750 0x30,0x33,0x31,0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
751 0x30,0x38,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x57,
752 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,
753 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,
754 0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2f,0x30,0x2d,0x06,0x03,0x55,
755 0x04,0x03,0x13,0x26,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,
756 0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,
757 0x76,0x69,0x63,0x65,0x73,0x20,0x53,0x69,0x67,0x6e,0x65,0x72,0x30,0x82,0x01,
758 0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
759 0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,
760 0xb2,0x50,0x28,0x48,0xdd,0xd3,0x68,0x7a,0x84,0x18,0x44,0x66,0x75,0x5d,0x7e,
761 0xc4,0xb8,0x9f,0x63,0x26,0xff,0x3d,0x43,0x9c,0x7c,0x11,0x38,0x10,0x25,0x55,
762 0x73,0xd9,0x75,0x27,0x69,0xfd,0x4e,0xb9,0x20,0x5c,0xd3,0x0a,0xf9,0xa0,0x1b,
763 0x2a,0xed,0x55,0x56,0x21,0x61,0xd8,0x1e,0xdb,0xe4,0xbc,0x33,0x6b,0xc7,0xef,
764 0xdd,0xa3,0x37,0x65,0x8e,0x1b,0x93,0x0c,0xb6,0x53,0x1e,0x5c,0x7c,0x66,0x35,
765 0x5f,0x05,0x8a,0x45,0xfe,0x76,0x4e,0xdf,0x53,0x80,0xa2,0x81,0x20,0x9d,0xae,
766 0x88,0x5c,0xa2,0x08,0xf7,0xe5,0x30,0xf9,0xee,0x22,0x37,0x4c,0x42,0x0a,0xce,
767 0xdf,0xc6,0x1f,0xc4,0xd6,0x55,0xe9,0x81,0x3f,0xb5,0x52,0xa3,0x2c,0xaa,0x01,
768 0x7a,0xf2,0xa2,0xaa,0x8d,0x35,0xfe,0x9f,0xe6,0x5d,0x6a,0x05,0x9f,0x3d,0x6b,
769 0xe3,0xbf,0x96,0xc0,0xfe,0xcc,0x60,0xf9,0x40,0xe7,0x07,0xa0,0x44,0xeb,0x81,
770 0x51,0x6e,0xa5,0x2a,0xf2,0xb6,0x8a,0x10,0x28,0xed,0x8f,0xdc,0x06,0xa0,0x86,
771 0x50,0x9a,0x7b,0x4a,0x08,0x0d,0x30,0x1d,0xca,0x10,0x9e,0x6b,0xf7,0xe9,0x58,
772 0xae,0x04,0xa9,0x40,0x99,0xb2,0x28,0xe8,0x8f,0x16,0xac,0x3c,0xe3,0x53,0x6f,
773 0x4b,0xd3,0x35,0x9d,0xb5,0x6f,0x64,0x1d,0xb3,0x96,0x2c,0xbb,0x3d,0xe7,0x79,
774 0xeb,0x6d,0x7a,0xf9,0x16,0xe6,0x26,0xad,0xaf,0xef,0x99,0x53,0xb7,0x40,0x2c,
775 0x95,0xb8,0x79,0xaa,0xfe,0xd4,0x52,0xab,0x29,0x74,0x7e,0x42,0xec,0x39,0x1e,
776 0xa2,0x6a,0x16,0xe6,0x59,0xbb,0x24,0x68,0xd8,0x00,0x80,0x43,0x10,0x87,0x80,
777 0x6b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xca,0x30,0x81,0xc7,0x30,0x34,0x06,
778 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,
779 0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,
780 0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
781 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
782 0xff,0x04,0x02,0x30,0x00,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30,
783 0x2a,0x30,0x28,0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,
784 0x2f,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,
785 0x6f,0x6d,0x2f,0x74,0x73,0x73,0x2d,0x63,0x61,0x2e,0x63,0x72,0x6c,0x30,0x16,
786 0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,
787 0x06,0x01,0x05,0x05,0x07,0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
788 0x01,0xff,0x04,0x04,0x03,0x02,0x06,0xc0,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,
789 0x04,0x1d,0x30,0x1b,0xa4,0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,
790 0x04,0x03,0x13,0x0c,0x54,0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,
791 0x34,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
792 0x00,0x03,0x82,0x01,0x01,0x00,0x87,0x78,0x70,0xda,0x4e,0x52,0x01,0x20,0x5b,
793 0xe0,0x79,0xc9,0x82,0x30,0xc4,0xfd,0xb9,0x19,0x96,0xbd,0x91,0x00,0xc3,0xbd,
794 0xcd,0xcd,0xc6,0xf4,0x0e,0xd8,0xff,0xf9,0x4d,0xc0,0x33,0x62,0x30,0x11,0xc5,
795 0xf5,0x74,0x1b,0xd4,0x92,0xde,0x5f,0x9c,0x20,0x13,0xb1,0x7c,0x45,0xbe,0x50,
796 0xcd,0x83,0xe7,0x80,0x17,0x83,0xa7,0x27,0x93,0x67,0x13,0x46,0xfb,0xca,0xb8,
797 0x98,0x41,0x03,0xcc,0x9b,0x51,0x5b,0x05,0x8b,0x7f,0xa8,0x6f,0xf3,0x1b,0x50,
798 0x1b,0x24,0x2e,0xf2,0x69,0x8d,0x6c,0x22,0xf7,0xbb,0xca,0x16,0x95,0xed,0x0c,
799 0x74,0xc0,0x68,0x77,0xd9,0xeb,0x99,0x62,0x87,0xc1,0x73,0x90,0xf8,0x89,0x74,
800 0x7a,0x23,0xab,0xa3,0x98,0x7b,0x97,0xb1,0xf7,0x8f,0x29,0x71,0x4d,0x2e,0x75,
801 0x1b,0x48,0x41,0xda,0xf0,0xb5,0x0d,0x20,0x54,0xd6,0x77,0xa0,0x97,0x82,0x63,
802 0x69,0xfd,0x09,0xcf,0x8a,0xf0,0x75,0xbb,0x09,0x9b,0xd9,0xf9,0x11,0x55,0x26,
803 0x9a,0x61,0x32,0xbe,0x7a,0x02,0xb0,0x7b,0x86,0xbe,0xa2,0xc3,0x8b,0x22,0x2c,
804 0x78,0xd1,0x35,0x76,0xbc,0x92,0x73,0x5c,0xf9,0xb9,0xe6,0x4c,0x15,0x0a,0x23,
805 0xcc,0xe4,0xd2,0xd4,0x34,0x2e,0x49,0x40,0x15,0x3c,0x0f,0x60,0x7a,0x24,0xc6,
806 0xa5,0x66,0xef,0x96,0xcf,0x70,0xeb,0x3e,0xe7,0xf4,0x0d,0x7e,0xdc,0xd1,0x7c,
807 0xa3,0x76,0x71,0x69,0xc1,0x9c,0x4f,0x47,0x30,0x35,0x21,0xb1,0xa2,0xaf,0x1a,
808 0x62,0x3c,0x2b,0xd9,0x8e,0xaa,0x2a,0x07,0x7b,0xd8,0x18,0xb3,0x5c,0x7b,0xe2,
809 0x9d,0xa5,0x6f,0xfe,0x3c,0x89,0xad };
810 static const BYTE iTunesCert2[] = {
811 0x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
812 0x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75,
813 0xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
814 0x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
815 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
816 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,
817 0x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,
818 0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,
819 0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,
820 0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x34,0x30,
821 0x37,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30,
822 0x37,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,
823 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,
824 0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
825 0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b,
826 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,
827 0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,
828 0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,
829 0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,
830 0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,
831 0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,
832 0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,
833 0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,0x53,0x69,
834 0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,0x20,0x43,0x41,0x30,0x82,
835 0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,
836 0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,
837 0x00,0xbe,0xbc,0xee,0xbc,0x7e,0xef,0x83,0xeb,0xe0,0x37,0x4f,0xfb,0x03,0x10,
838 0x38,0xbe,0x08,0xd2,0x8c,0x7d,0x9d,0xfa,0x92,0x7f,0x19,0x0c,0xc2,0x6b,0xee,
839 0x42,0x52,0x8c,0xde,0xd3,0x1c,0x48,0x13,0x25,0xea,0xc1,0x63,0x7a,0xf9,0x51,
840 0x65,0xee,0xd3,0xaa,0x3b,0xf5,0xf0,0x94,0x9c,0x2b,0xfb,0xf2,0x66,0xd4,0x24,
841 0xda,0xf7,0xf5,0x9f,0x6e,0x19,0x39,0x36,0xbc,0xd0,0xa3,0x76,0x08,0x1e,0x22,
842 0x27,0x24,0x6c,0x38,0x91,0x27,0xe2,0x84,0x49,0xae,0x1b,0x8a,0xa1,0xfd,0x25,
843 0x82,0x2c,0x10,0x30,0xe8,0x71,0xab,0x28,0xe8,0x77,0x4a,0x51,0xf1,0xec,0xcd,
844 0xf8,0xf0,0x54,0xd4,0x6f,0xc0,0xe3,0x6d,0x0a,0x8f,0xd9,0xd8,0x64,0x8d,0x63,
845 0xb2,0x2d,0x4e,0x27,0xf6,0x85,0x0e,0xfe,0x6d,0xe3,0x29,0x99,0xe2,0x85,0x47,
846 0x7c,0x2d,0x86,0x7f,0xe8,0x57,0x8f,0xad,0x67,0xc2,0x33,0x32,0x91,0x13,0x20,
847 0xfc,0xa9,0x23,0x14,0x9a,0x6d,0xc2,0x84,0x4b,0x76,0x68,0x04,0xd5,0x71,0x2c,
848 0x5d,0x21,0xfa,0x88,0x0d,0x26,0xfd,0x1f,0x2d,0x91,0x2b,0xe7,0x01,0x55,0x4d,
849 0xf2,0x6d,0x35,0x28,0x82,0xdf,0xd9,0x6b,0x5c,0xb6,0xd6,0xd9,0xaa,0x81,0xfd,
850 0x5f,0xcd,0x83,0xba,0x63,0x9d,0xd0,0x22,0xfc,0xa9,0x3b,0x42,0x69,0xb2,0x8e,
851 0x3a,0xb5,0xbc,0xb4,0x9e,0x0f,0x5e,0xc4,0xea,0x2c,0x82,0x8b,0x28,0xfd,0x53,
852 0x08,0x96,0xdd,0xb5,0x01,0x20,0xd1,0xf9,0xa5,0x18,0xe7,0xc0,0xee,0x51,0x70,
853 0x37,0xe1,0xb6,0x05,0x48,0x52,0x48,0x6f,0x38,0xea,0xc3,0xe8,0x6c,0x7b,0x44,
854 0x84,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xa0,0x30,0x82,0x01,0x9c,
855 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
856 0x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,
857 0x3b,0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,
858 0x03,0x30,0x2a,0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
859 0x16,0x1c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,
860 0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,
861 0x30,0x31,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24,
862 0xa0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,
863 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63,
864 0x61,0x33,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16,
865 0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2b,
866 0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
867 0x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48,
868 0x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x01,0x30,0x29,0x06,
869 0x03,0x55,0x1d,0x11,0x04,0x22,0x30,0x20,0xa4,0x1e,0x30,0x1c,0x31,0x1a,0x30,
870 0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6c,0x61,0x73,0x73,0x33,0x43,
871 0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x34,0x33,0x30,0x1d,0x06,0x03,0x55,
872 0x1d,0x0e,0x04,0x16,0x04,0x14,0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,
873 0x36,0x7c,0x68,0xcf,0x5b,0x78,0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x81,0x80,0x06,
874 0x03,0x55,0x1d,0x23,0x04,0x79,0x30,0x77,0xa1,0x63,0xa4,0x61,0x30,0x5f,0x31,
875 0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,
876 0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
877 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,
878 0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6c,
879 0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,
880 0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,
881 0x72,0x69,0x74,0x79,0x82,0x10,0x70,0xba,0xe4,0x1d,0x10,0xd9,0x29,0x34,0xb6,
882 0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
883 0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xae,0x3a,0x17,0xb8,
884 0x4a,0x7b,0x55,0xfa,0x64,0x55,0xec,0x40,0xa4,0xed,0x49,0x41,0x90,0x99,0x9c,
885 0x89,0xbc,0xaf,0x2e,0x1d,0xca,0x78,0x23,0xf9,0x1c,0x19,0x0f,0x7f,0xeb,0x68,
886 0xbc,0x32,0xd9,0x88,0x38,0xde,0xdc,0x3f,0xd3,0x89,0xb4,0x3f,0xb1,0x82,0x96,
887 0xf1,0xa4,0x5a,0xba,0xed,0x2e,0x26,0xd3,0xde,0x7c,0x01,0x6e,0x00,0x0a,0x00,
888 0xa4,0x06,0x92,0x11,0x48,0x09,0x40,0xf9,0x1c,0x18,0x79,0x67,0x23,0x24,0xe0,
889 0xbb,0xd5,0xe1,0x50,0xae,0x1b,0xf5,0x0e,0xdd,0xe0,0x2e,0x81,0xcd,0x80,0xa3,
890 0x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88,
891 0x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f,
892 0x5e,0xf6,0x7a,0xb5 };
893 static const BYTE iTunesCert3[] = {
894 0x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
895 0x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6,
896 0x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
897 0x00,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
898 0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,
899 0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,
900 0x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
901 0x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,
902 0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,
903 0x73,0x20,0x6f,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,
904 0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
905 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,
906 0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,
907 0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,
908 0x6f,0x64,0x65,0x20,0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,
909 0x34,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x31,0x37,0x30,
910 0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x38,0x30,0x31,0x32,0x32,0x32,
911 0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,
912 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
913 0x08,0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x12,
914 0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,
915 0x69,0x6e,0x6f,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0a,0x14,0x14,0x41,
916 0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x2c,0x20,
917 0x49,0x6e,0x63,0x2e,0x31,0x3e,0x30,0x3c,0x06,0x03,0x55,0x04,0x0b,0x13,0x35,
918 0x44,0x69,0x67,0x69,0x74,0x61,0x6c,0x20,0x49,0x44,0x20,0x43,0x6c,0x61,0x73,
919 0x73,0x20,0x33,0x20,0x2d,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
920 0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x56,0x61,0x6c,0x69,0x64,
921 0x61,0x74,0x69,0x6f,0x6e,0x20,0x76,0x32,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,
922 0x04,0x03,0x14,0x14,0x41,0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,
923 0x74,0x65,0x72,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x30,0x81,0x9f,0x30,0x0d,0x06,
924 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,
925 0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xd3,0xab,0x3b,0x7f,0xec,0x48,0x84,
926 0xce,0xa8,0x1a,0x12,0xf3,0x3c,0x87,0xcb,0x24,0x58,0x96,0x02,0x87,0x66,0x49,
927 0xeb,0x89,0xee,0x79,0x44,0x70,0x8d,0xe7,0xd4,0x1f,0x30,0x92,0xc0,0x9c,0x35,
928 0x78,0xc0,0xaf,0x1c,0xb6,0x28,0xd3,0xe0,0xe0,0x9d,0xd3,0x49,0x76,0x73,0x57,
929 0x19,0x4d,0x8d,0x70,0x85,0x64,0x4d,0x1d,0xc6,0x02,0x3e,0xe5,0x2c,0x66,0x07,
930 0xd2,0x27,0x4b,0xd6,0xc8,0x3c,0x93,0xb6,0x15,0x0c,0xde,0x5b,0xd7,0x93,0xdd,
931 0xbe,0x85,0x62,0x34,0x17,0x8a,0x05,0x60,0xf0,0x8a,0x1c,0x5a,0x40,0x21,0x8d,
932 0x51,0x6c,0xb0,0x62,0xd8,0xb5,0xd4,0xf9,0xb1,0xd0,0x58,0x7a,0x7a,0x82,0x55,
933 0xb3,0xf9,0x53,0x71,0xde,0xd2,0xc9,0x37,0x8c,0xf6,0x5a,0x1f,0x2d,0xcd,0x7c,
934 0x67,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30,
935 0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06,0x03,0x55,
936 0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x40,0x06,0x03,
937 0x55,0x1d,0x1f,0x04,0x39,0x30,0x37,0x30,0x35,0xa0,0x33,0xa0,0x31,0x86,0x2f,
938 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,
939 0x34,0x2d,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,
940 0x63,0x6f,0x6d,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2e,0x63,
941 0x72,0x6c,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b,0x30,0x39,
942 0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,0x03,0x30,0x2a,
943 0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1c,0x68,
944 0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,
945 0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x30,0x13,0x06,
946 0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
947 0x07,0x03,0x03,0x30,0x75,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
948 0x04,0x69,0x30,0x67,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,
949 0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,
950 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x3f,0x06,
951 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x33,0x68,0x74,0x74,0x70,
952 0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,
953 0x61,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,
954 0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,0x61,0x2e,0x63,
955 0x65,0x72,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
956 0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,0x36,0x7c,0x68,0xcf,0x5b,0x78,
957 0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,
958 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x04,0x10,0x30,0x16,0x06,0x0a,0x2b,0x06,
959 0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x1b,0x04,0x08,0x30,0x06,0x01,0x01,0x00,
960 0x01,0x01,0xff,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
961 0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6a,0xa6,0x06,0xd0,0x33,0x18,0x64,
962 0xe2,0x69,0x82,0xee,0x6e,0x36,0x9e,0x9d,0x9a,0x0e,0x18,0xa8,0xac,0x9d,0x10,
963 0xed,0x01,0x3c,0xb9,0x61,0x04,0x62,0xf3,0x85,0x8f,0xcc,0x4f,0x2c,0x66,0x35,
964 0x54,0x25,0x45,0x8d,0x95,0x1c,0xd2,0x33,0xbe,0x2e,0xdd,0x7f,0x74,0xaf,0x03,
965 0x7b,0x86,0x63,0xb0,0xc9,0xe6,0xbd,0xc7,0x8e,0xde,0x03,0x18,0x98,0x82,0xc3,
966 0xbb,0xf8,0x15,0x99,0x1a,0xa9,0xdd,0xb9,0x5d,0xb9,0xbd,0x53,0x95,0x25,0x76,
967 0xfb,0x5c,0x53,0x90,0xea,0x01,0x0a,0xa0,0xb1,0xbf,0x09,0x1b,0x97,0x8f,0x40,
968 0xfa,0x85,0x12,0x74,0x01,0xdb,0xf6,0xdb,0x09,0xd6,0x5f,0x4f,0xd7,0x17,0xb4,
969 0xbf,0x9e,0x2f,0x86,0x52,0x5d,0x70,0x24,0x52,0x32,0x1e,0xa5,0x1d,0x39,0x8b,
970 0x66,0xf6,0xba,0x9b,0x69,0x8e,0x12,0x60,0xdb,0xb6,0xcf,0xe6,0x0d,0xd6,0x1c,
971 0x8f,0xd4,0x5b,0x4b,0x00,0xde,0x21,0x93,0xfb,0x6e,0xc7,0x3d,0xb4,0x66,0x0d,
972 0x29,0x0c,0x4e,0xe9,0x3f,0x94,0xd6,0xd6,0xdc,0xec,0xf8,0x53,0x3b,0x62,0xd5,
973 0x97,0x50,0x53,0x84,0x17,0xfe,0xe2,0xed,0x4c,0x23,0x0a,0x49,0xce,0x5b,0xe9,
974 0x70,0x31,0xc1,0x04,0x02,0x02,0x6c,0xb8,0x52,0xcd,0xc7,0x4e,0x70,0xb4,0x13,
975 0xd7,0xe0,0x92,0xba,0x44,0x1a,0x10,0x4c,0x6e,0x45,0xc6,0x86,0x04,0xc6,0x64,
976 0xd3,0x9c,0x6e,0xc1,0x9c,0xac,0x74,0x3d,0x77,0x06,0x5e,0x28,0x28,0x5c,0xf5,
977 0xe0,0x9c,0x19,0xd8,0xba,0x74,0x81,0x2d,0x67,0x77,0x93,0x8d,0xbf,0xd2,0x52,
978 0x00,0xe6,0xa5,0x38,0x4e,0x2e,0x73,0x66,0x7a };
979 static BYTE iTunesIssuer[] = {
980 0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
981 0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,
982 0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
983 0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,
984 0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
985 0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,
986 0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,
987 0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,0x73,
988 0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,
989 0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,
990 0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,
991 0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,
992 0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
993 0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,
994 0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,
995 0x20,0x43,0x41 };
996 static BYTE iTunesSerialNum[] = {
997 0x8d,0xf6,0x6a,0xdf,0xd2,0x40,0xfe,0xb6,0xa6,0x61,0x9b,0x9b,
998 0xe0,0xa0,0x1a,0x0f };
999
1000 static void testFindCert(void)
1001 {
1002     HCERTSTORE store;
1003     PCCERT_CONTEXT context = NULL, subject;
1004     BOOL ret;
1005     CERT_INFO certInfo = { 0 };
1006     CRYPT_HASH_BLOB blob;
1007     BYTE otherSerialNumber[] = { 2 };
1008
1009     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1010      CERT_STORE_CREATE_NEW_FLAG, NULL);
1011     ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1012     if (!store)
1013         return;
1014
1015     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1016      bigCert, sizeof(bigCert), CERT_STORE_ADD_NEW, NULL);
1017     ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1018      GetLastError());
1019     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1020      bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, NULL);
1021     ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1022      GetLastError());
1023     /* This has the same name as bigCert */
1024     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1025      certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1026     ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1027      GetLastError());
1028
1029     /* Crashes
1030     context = CertFindCertificateInStore(NULL, 0, 0, 0, NULL, NULL);
1031      */
1032
1033     /* Check first cert's there, by issuer */
1034     certInfo.Subject.pbData = subjectName;
1035     certInfo.Subject.cbData = sizeof(subjectName);
1036     certInfo.SerialNumber.pbData = serialNum;
1037     certInfo.SerialNumber.cbData = sizeof(serialNum);
1038     context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1039      CERT_FIND_ISSUER_NAME, &certInfo.Subject, NULL);
1040     ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1041      GetLastError());
1042     if (context)
1043     {
1044         context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1045          CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
1046         ok(context != NULL, "Expected more than one cert\n");
1047         if (context)
1048         {
1049             context = CertFindCertificateInStore(store, X509_ASN_ENCODING,
1050              0, CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
1051             ok(context == NULL, "Expected precisely two certs\n");
1052         }
1053     }
1054
1055     /* Check second cert's there as well, by subject name */
1056     certInfo.Subject.pbData = subjectName2;
1057     certInfo.Subject.cbData = sizeof(subjectName2);
1058     context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1059      CERT_FIND_SUBJECT_NAME, &certInfo.Subject, NULL);
1060     ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1061      GetLastError());
1062     if (context)
1063     {
1064         context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1065          CERT_FIND_SUBJECT_NAME, &certInfo.Subject, context);
1066         ok(context == NULL, "Expected one cert only\n");
1067     }
1068
1069     /* Strange but true: searching for the subject cert requires you to set
1070      * the issuer, not the subject
1071      */
1072     context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1073      CERT_FIND_SUBJECT_CERT, &certInfo.Subject, NULL);
1074     ok(context == NULL, "Expected no certificate\n");
1075     certInfo.Subject.pbData = NULL;
1076     certInfo.Subject.cbData = 0;
1077     certInfo.Issuer.pbData = subjectName2;
1078     certInfo.Issuer.cbData = sizeof(subjectName2);
1079     context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1080      CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1081     ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1082      GetLastError());
1083     if (context)
1084     {
1085         context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1086          CERT_FIND_SUBJECT_CERT, &certInfo.Subject, context);
1087         ok(context == NULL, "Expected one cert only\n");
1088     }
1089     /* A non-matching serial number will not match. */
1090     certInfo.SerialNumber.pbData = otherSerialNumber;
1091     certInfo.SerialNumber.cbData = sizeof(otherSerialNumber);
1092     context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1093      CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1094     ok(context == NULL, "Expected no match\n");
1095     /* No serial number will not match */
1096     certInfo.SerialNumber.cbData = 0;
1097     context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1098      CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1099     ok(context == NULL, "Expected no match\n");
1100     /* A serial number still won't match if the name doesn't */
1101     certInfo.SerialNumber.pbData = serialNum;
1102     certInfo.SerialNumber.cbData = sizeof(serialNum);
1103     certInfo.Issuer.pbData = subjectName3;
1104     certInfo.Issuer.cbData = sizeof(subjectName3);
1105     context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1106      CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1107     ok(context == NULL, "Expected no match\n");
1108
1109     /* The nice thing about hashes, they're unique */
1110     blob.pbData = bigCertHash;
1111     blob.cbData = sizeof(bigCertHash);
1112     context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1113      CERT_FIND_SHA1_HASH, &blob, NULL);
1114     ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1115      GetLastError());
1116     if (context)
1117     {
1118         context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1119          CERT_FIND_SHA1_HASH, &certInfo.Subject, context);
1120         ok(context == NULL, "Expected one cert only\n");
1121     }
1122
1123     CertCloseStore(store, 0);
1124
1125     /* Another subject cert search, using iTunes's certs */
1126     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1127      CERT_STORE_CREATE_NEW_FLAG, NULL);
1128     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1129      iTunesCert0, sizeof(iTunesCert0), CERT_STORE_ADD_NEW, NULL);
1130     ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1131      GetLastError());
1132     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1133      iTunesCert1, sizeof(iTunesCert1), CERT_STORE_ADD_NEW, NULL);
1134     ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1135      GetLastError());
1136     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1137      iTunesCert2, sizeof(iTunesCert2), CERT_STORE_ADD_NEW, NULL);
1138     ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1139      GetLastError());
1140     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1141      iTunesCert3, sizeof(iTunesCert3), CERT_STORE_ADD_NEW, &subject);
1142     ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1143      GetLastError());
1144
1145     /* The certInfo's issuer does not match any subject, but the serial
1146      * number does match a cert whose issuer matches certInfo's issuer.
1147      * This yields a match.
1148      */
1149     certInfo.SerialNumber.cbData = sizeof(iTunesSerialNum);
1150     certInfo.SerialNumber.pbData = iTunesSerialNum;
1151     certInfo.Issuer.cbData = sizeof(iTunesIssuer);
1152     certInfo.Issuer.pbData = iTunesIssuer;
1153     context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1154      CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1155     ok(context != NULL, "Expected a match\n");
1156     if (context)
1157     {
1158         ret = CertCompareCertificateName(context->dwCertEncodingType,
1159          &certInfo.Issuer, &context->pCertInfo->Subject);
1160         ok(!ret, "Expected subject name not to match\n");
1161         ret = CertCompareCertificateName(context->dwCertEncodingType,
1162          &certInfo.Issuer, &context->pCertInfo->Issuer);
1163         ok(ret, "Expected issuer name to match\n");
1164         ret = CertCompareIntegerBlob(&certInfo.SerialNumber,
1165          &context->pCertInfo->SerialNumber);
1166         ok(ret, "Expected serial number to match\n");
1167         context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1168          CERT_FIND_SUBJECT_CERT, &certInfo, context);
1169         ok(context == NULL, "Expected one cert only\n");
1170     }
1171
1172     context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0,
1173      CERT_FIND_ISSUER_OF, subject, NULL);
1174     ok(context != NULL, "Expected an issuer\n");
1175     if (context)
1176     {
1177         PCCERT_CONTEXT none = CertFindCertificateInStore(store,
1178          X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_OF, context, NULL);
1179
1180         ok(!none, "Expected no parent of issuer\n");
1181         CertFreeCertificateContext(context);
1182     }
1183     CertFreeCertificateContext(subject);
1184     CertCloseStore(store, 0);
1185 }
1186
1187 static void testGetSubjectCert(void)
1188 {
1189     HCERTSTORE store;
1190     PCCERT_CONTEXT context1, context2;
1191     CERT_INFO info = { 0 };
1192     BOOL ret;
1193
1194     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1195      CERT_STORE_CREATE_NEW_FLAG, NULL);
1196     ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1197     if (!store)
1198         return;
1199
1200     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1201      bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL);
1202     ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1203      GetLastError());
1204     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1205      bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, &context1);
1206     ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1207      GetLastError());
1208     ok(context1 != NULL, "Expected a context\n");
1209     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1210      certWithUsage, sizeof(certWithUsage), CERT_STORE_ADD_NEW, NULL);
1211     ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1212      GetLastError());
1213
1214     context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1215      NULL);
1216     ok(!context2 && GetLastError() == E_INVALIDARG,
1217      "Expected E_INVALIDARG, got %08x\n", GetLastError());
1218     context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1219      &info);
1220     ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1221      "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1222     info.SerialNumber.cbData = sizeof(serialNum);
1223     info.SerialNumber.pbData = serialNum;
1224     context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1225      &info);
1226     ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1227      "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1228     info.Issuer.cbData = sizeof(subjectName2);
1229     info.Issuer.pbData = subjectName2;
1230     context2 = CertGetSubjectCertificateFromStore(store, X509_ASN_ENCODING,
1231      &info);
1232     ok(context2 != NULL,
1233      "CertGetSubjectCertificateFromStore failed: %08x\n", GetLastError());
1234     /* Not only should this find a context, but it should be the same
1235      * (same address) as context1.
1236      */
1237     ok(context1 == context2, "Expected identical context addresses\n");
1238     CertFreeCertificateContext(context2);
1239
1240     CertFreeCertificateContext(context1);
1241     CertCloseStore(store, 0);
1242 }
1243
1244 /* This expires in 1970 or so */
1245 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
1246  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
1247  0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
1248  0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1249  0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1250  0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1251  0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
1252  0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
1253  0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1254  0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1255  0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1256  0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
1257  0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
1258  0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
1259  0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
1260  0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
1261  0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
1262  0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
1263  0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
1264  0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
1265  0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
1266  0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
1267  0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
1268  0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
1269  0x49, 0xe5, 0xf9, 0x65, 0xf3 };
1270
1271 /* This expires in 2036 or so */
1272 static const BYTE childOfExpired[] = { 0x30, 0x81, 0xcc, 0x30, 0x78, 0xa0,
1273  0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
1274  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d,
1275  0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63,
1276  0x40, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e,
1277  0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x35, 0x30, 0x35,
1278  0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x35,
1279  0x30, 0x35, 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x30, 0x15, 0x31, 0x13,
1280  0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e,
1281  0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03,
1282  0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
1283  0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x20, 0x3b, 0xdb, 0x4d, 0x67, 0x50,
1284  0xec, 0x73, 0x9d, 0xf9, 0x85, 0x5d, 0x18, 0xe9, 0xb4, 0x98, 0xe3, 0x31, 0xb7,
1285  0x03, 0x0b, 0xc0, 0x39, 0x93, 0x56, 0x81, 0x0a, 0xfc, 0x78, 0xa8, 0x29, 0x42,
1286  0x5f, 0x69, 0xfb, 0xbc, 0x5b, 0xf2, 0xa6, 0x2a, 0xbe, 0x91, 0x2c, 0xfc, 0x89,
1287  0x69, 0x15, 0x18, 0x58, 0xe5, 0x02, 0x75, 0xf7, 0x2a, 0xb6, 0xa9, 0xfb, 0x47,
1288  0x6a, 0x6e, 0x0a, 0x9b, 0xe9, 0xdc };
1289 /* chain10_0 -+
1290  *            +-> chain7_1
1291  * chain10_1 -+
1292  * A chain with two issuers, only one of whose dates is valid.
1293  */
1294 static const BYTE chain10_0[] = {
1295 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1296 0x4a,0x30,0x3a,0x42,0xa2,0x5a,0xb3,0x93,0x4d,0x94,0x06,0xad,0x6d,0x1c,0x34,
1297 0xe6,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1298 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1299 0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1300 0x30,0x5a,0x17,0x0d,0x30,0x36,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1301 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1302 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1303 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1304 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1305 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1306 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1307 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1308 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1309 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1310 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1311 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1312 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1313 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1314 0x81,0x00,0x85,0x6e,0x35,0x2f,0x2c,0x51,0x4f,0xd6,0x2a,0xe4,0x9e,0xd0,0x4b,
1315 0xe6,0x90,0xfd,0xf7,0x20,0xad,0x76,0x3f,0x93,0xea,0x7f,0x0d,0x1f,0xb3,0x8e,
1316 0xfd,0xe0,0xe1,0xd6,0xd7,0x9c,0x7d,0x46,0x6b,0x15,0x5c,0xe6,0xc9,0x62,0x3b,
1317 0x70,0x4a,0x4b,0xb2,0x82,0xe3,0x55,0x0c,0xc4,0x90,0x44,0x06,0x6c,0x86,0x1c,
1318 0x6d,0x47,0x12,0xda,0x33,0x95,0x5d,0x98,0x43,0xcb,0x7c,0xfa,0x2b,0xee,0xc4,
1319 0x2d,0xc8,0x95,0x33,0x89,0x08,0x3f,0x9f,0x87,0xea,0x20,0x04,0xaf,0x58,0x4b,
1320 0x9d,0xc0,0x7c,0x0a,0x1b,0x05,0x31,0x3b,0xbb,0x13,0x58,0x2e,0x3f,0x61,0x6b,
1321 0x10,0xb4,0xeb,0xb9,0x1a,0x30,0xfd,0xea,0xca,0x29,0x99,0x5f,0x42,0x2b,0x00,
1322 0xb0,0x08,0xc3,0xf0,0xb6,0xd6,0x6b,0xf9,0x35,0x95 };
1323 static const BYTE chain10_1[] = {
1324 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1325 0xbf,0x99,0x4f,0x14,0x03,0x77,0x44,0xb8,0x49,0x02,0x70,0xa1,0xb8,0x9c,0xa7,
1326 0x24,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1327 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1328 0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1329 0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1330 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1331 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1332 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1333 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1334 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1335 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1336 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1337 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1338 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1339 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1340 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1341 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1342 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1343 0x81,0x00,0xa8,0xec,0x8c,0x34,0xe7,0x2c,0xdf,0x75,0x87,0xc4,0xf7,0xda,0x71,
1344 0x72,0x29,0xb2,0x48,0xa8,0x2a,0xec,0x7b,0x7d,0x19,0xb9,0x5f,0x1d,0xd9,0x91,
1345 0x2b,0xc4,0x28,0x7e,0xd6,0xb5,0x91,0x69,0xa5,0x8a,0x1a,0x1f,0x97,0x98,0x46,
1346 0x9d,0xdf,0x12,0xf6,0x45,0x62,0xad,0x60,0xb6,0xba,0xb0,0xfd,0xf5,0x9f,0xc6,
1347 0x98,0x05,0x4f,0x4d,0x48,0xdc,0xee,0x69,0xbe,0xb8,0xc4,0xc4,0xd7,0x1b,0xb1,
1348 0x1f,0x64,0xd6,0x45,0xa7,0xdb,0xb3,0x87,0x63,0x0f,0x54,0xe1,0x3a,0x6b,0x57,
1349 0x36,0xd7,0x68,0x65,0xcf,0xda,0x57,0x8d,0xcd,0x84,0x75,0x47,0x26,0x2c,0xef,
1350 0x1e,0x8f,0xc7,0x3b,0xee,0x5d,0x03,0xa6,0xdf,0x3a,0x20,0xb2,0xcc,0xc9,0x09,
1351 0x2c,0xfe,0x2b,0x79,0xb0,0xca,0x2c,0x9a,0x81,0x6b };
1352 static const BYTE chain7_1[] = {
1353 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
1354 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,
1355 0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,
1356 0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,
1357 0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,
1358 0x35,0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,
1359 0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,
1360 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,
1361 0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,
1362 0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,
1363 0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,
1364 0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,
1365 0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,
1366 0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,
1367 0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,
1368 0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,
1369 0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,
1370 0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1371 0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9f,0x69,0xfd,0x26,0xd5,0x4b,
1372 0xe0,0xab,0x12,0x21,0xb9,0xfc,0xf7,0xe0,0x0c,0x09,0x94,0xad,0x27,0xd7,0x9d,
1373 0xa3,0xcc,0x46,0x2a,0x25,0x9a,0x24,0xa7,0x31,0x58,0x78,0xf5,0xfc,0x30,0xe1,
1374 0x6d,0xfd,0x59,0xab,0xbe,0x69,0xa0,0xea,0xe3,0x7d,0x7a,0x7b,0xe5,0x85,0xeb,
1375 0x86,0x6a,0x84,0x3c,0x96,0x01,0x1a,0x70,0xa7,0xb8,0xcb,0xf2,0x11,0xe7,0x52,
1376 0x9c,0x58,0x2d,0xac,0x63,0xce,0x72,0x4b,0xad,0x62,0xa8,0x1d,0x75,0x96,0xe2,
1377 0x27,0xf5,0x6f,0xba,0x91,0xf8,0xf1,0xb0,0xbf,0x90,0x24,0x6d,0xba,0x5d,0xd7,
1378 0x39,0x63,0x3b,0x7c,0x04,0x5d,0x89,0x9d,0x1c,0xf2,0xf7,0xcc,0xdf,0x6e,0x8a,
1379 0x43,0xa9,0xdd,0x86,0x05,0xa2,0xf3,0x22,0x2d,0x1e,0x70,0xa1,0x59,0xd7,0xa5,
1380 0x94,0x7d };
1381
1382 static void testGetIssuerCert(void)
1383 {
1384     BOOL ret;
1385     PCCERT_CONTEXT parent, child, cert1, cert2;
1386     DWORD flags = 0xffffffff;
1387     HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1388      CERT_STORE_CREATE_NEW_FLAG, NULL);
1389
1390     ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1391
1392     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1393      expiredCert, sizeof(expiredCert), CERT_STORE_ADD_ALWAYS, NULL);
1394     ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1395      GetLastError());
1396
1397     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1398      childOfExpired, sizeof(childOfExpired), CERT_STORE_ADD_ALWAYS, &child);
1399     ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1400      GetLastError());
1401
1402     /* These crash:
1403     parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, NULL);
1404     parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, NULL);
1405      */
1406     parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, &flags);
1407     ok(!parent && GetLastError() == E_INVALIDARG,
1408      "Expected E_INVALIDARG, got %08x\n", GetLastError());
1409     parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, &flags);
1410     ok(!parent && GetLastError() == E_INVALIDARG,
1411      "Expected E_INVALIDARG, got %08x\n", GetLastError());
1412     parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1413     ok(!parent && GetLastError() == E_INVALIDARG,
1414      "Expected E_INVALIDARG, got %08x\n", GetLastError());
1415     /* Confusing: the caller cannot set either of the
1416      * CERT_STORE_NO_*_FLAGs, as these are not checks,
1417      * they're results:
1418      */
1419     flags = CERT_STORE_NO_CRL_FLAG | CERT_STORE_NO_ISSUER_FLAG;
1420     parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1421     ok(!parent && GetLastError() == E_INVALIDARG,
1422      "Expected E_INVALIDARG, got %08x\n", GetLastError());
1423     /* Perform no checks */
1424     flags = 0;
1425     parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1426     ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1427      GetLastError());
1428     if (parent)
1429         CertFreeCertificateContext(parent);
1430     /* Check revocation and signature only */
1431     flags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG;
1432     parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1433     ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1434      GetLastError());
1435     /* Confusing: CERT_STORE_REVOCATION_FLAG succeeds when there is no CRL by
1436      * setting CERT_STORE_NO_CRL_FLAG.
1437      */
1438     ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
1439      "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
1440      flags);
1441     if (parent)
1442         CertFreeCertificateContext(parent);
1443     /* Checking time validity is not productive, because while most Windows
1444      * versions return 0 (time valid) because the child is not expired,
1445      * Windows 2003 SP1 returns that it is expired.  Thus the range of
1446      * possibilities is covered, and a test verifies nothing.
1447      */
1448
1449     CertFreeCertificateContext(child);
1450     CertCloseStore(store, 0);
1451
1452     flags = 0;
1453     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1454      CERT_STORE_CREATE_NEW_FLAG, NULL);
1455     /* With only the child certificate, no issuer will be found */
1456     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1457      chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1458     parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1459     ok(parent == NULL, "Expected no issuer\n");
1460     /* Adding an issuer allows one (and only one) issuer to be found */
1461     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1462      chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert1);
1463     parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1464     ok(parent == cert1, "Expected cert1 to be the issuer\n");
1465     parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1466     ok(parent == NULL, "Expected only one issuer\n");
1467     /* Adding a second issuer allows two issuers to be found - and the second
1468      * issuer is found before the first, implying certs are added to the head
1469      * of a list.
1470      */
1471     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1472      chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert2);
1473     parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1474     ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1475     parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1476     ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1477     parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1478     ok(parent == NULL, "Expected no more than two issuers\n");
1479     CertFreeCertificateContext(child);
1480     CertFreeCertificateContext(cert1);
1481     CertFreeCertificateContext(cert2);
1482     CertCloseStore(store, 0);
1483
1484     /* Repeat the test, reversing the order in which issuers are added,
1485      * to show it's order-dependent.
1486      */
1487     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1488      CERT_STORE_CREATE_NEW_FLAG, NULL);
1489     /* With only the child certificate, no issuer will be found */
1490     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1491      chain7_1, sizeof(chain7_1), CERT_STORE_ADD_ALWAYS, &child);
1492     parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1493     ok(parent == NULL, "Expected no issuer\n");
1494     /* Adding an issuer allows one (and only one) issuer to be found */
1495     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1496      chain10_0, sizeof(chain10_0), CERT_STORE_ADD_ALWAYS, &cert1);
1497     parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1498     ok(parent == cert1, "Expected cert1 to be the issuer\n");
1499     parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1500     ok(parent == NULL, "Expected only one issuer\n");
1501     /* Adding a second issuer allows two issuers to be found - and the second
1502      * issuer is found before the first, implying certs are added to the head
1503      * of a list.
1504      */
1505     ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
1506      chain10_1, sizeof(chain10_1), CERT_STORE_ADD_ALWAYS, &cert2);
1507     parent = CertGetIssuerCertificateFromStore(store, child, NULL, &flags);
1508     ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1509     parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1510     ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1511     parent = CertGetIssuerCertificateFromStore(store, child, parent, &flags);
1512     ok(parent == NULL, "Expected no more than two issuers\n");
1513     CertFreeCertificateContext(child);
1514     CertFreeCertificateContext(cert1);
1515     CertFreeCertificateContext(cert2);
1516     CertCloseStore(store, 0);
1517 }
1518
1519 static void testCryptHashCert(void)
1520 {
1521     static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b,
1522      0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07,
1523      0x09 };
1524     static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee,
1525      0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8,
1526      0xa2 };
1527     static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:";
1528     BOOL ret;
1529     BYTE hash[20];
1530     DWORD hashLen = sizeof(hash);
1531
1532     /* NULL buffer and nonzero length crashes
1533     ret = CryptHashCertificate(0, 0, 0, NULL, size, hash, &hashLen);
1534        empty hash length also crashes
1535     ret = CryptHashCertificate(0, 0, 0, buf, size, hash, NULL);
1536      */
1537     /* Test empty hash */
1538     ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), NULL,
1539      &hashLen);
1540     ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1541     ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen);
1542     /* Test with empty buffer */
1543     ret = CryptHashCertificate(0, 0, 0, NULL, 0, hash, &hashLen);
1544     ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1545     ok(!memcmp(hash, emptyHash, sizeof(emptyHash)),
1546      "Unexpected hash of nothing\n");
1547     /* Test a known value */
1548     ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), hash,
1549      &hashLen);
1550     ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1551     ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
1552 }
1553
1554 static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen,
1555  const BYTE *sig, unsigned int sigLen)
1556 {
1557     HCRYPTHASH hash;
1558     BOOL ret = CryptCreateHash(csp, CALG_SHA1, 0, 0, &hash);
1559
1560     ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
1561     if (ret)
1562     {
1563         BYTE mySig[64];
1564         DWORD mySigSize = sizeof(mySig);
1565
1566         ret = CryptHashData(hash, toSign, toSignLen, 0);
1567         ok(ret, "CryptHashData failed: %08x\n", GetLastError());
1568         /* use the A variant so the test can run on Win9x */
1569         ret = CryptSignHashA(hash, AT_SIGNATURE, NULL, 0, mySig, &mySigSize);
1570         ok(ret, "CryptSignHash failed: %08x\n", GetLastError());
1571         if (ret)
1572         {
1573             ok(mySigSize == sigLen, "Expected sig length %d, got %d\n",
1574              sigLen, mySigSize);
1575             ok(!memcmp(mySig, sig, sigLen), "Unexpected signature\n");
1576         }
1577         CryptDestroyHash(hash);
1578     }
1579 }
1580
1581 /* Tests signing the certificate described by toBeSigned with the CSP passed in,
1582  * using the algorithm with OID sigOID.  The CSP is assumed to be empty, and a
1583  * keyset named AT_SIGNATURE will be added to it.  The signing key will be
1584  * stored in *key, and the signature will be stored in sig.  sigLen should be
1585  * at least 64 bytes.
1586  */
1587 static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1588  LPCSTR sigOID, HCRYPTKEY *key, BYTE *sig, DWORD *sigLen)
1589 {
1590     BOOL ret;
1591     DWORD size = 0;
1592     CRYPT_ALGORITHM_IDENTIFIER algoID = { NULL, { 0, NULL } };
1593
1594     /* These all crash
1595     ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1596     ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, &size);
1597     ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1598      NULL, NULL, NULL, &size);
1599      */
1600     ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1601      &algoID, NULL, NULL, &size);
1602     ok(!ret && GetLastError() == NTE_BAD_ALGID, 
1603      "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1604     algoID.pszObjId = (LPSTR)sigOID;
1605     ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1606      &algoID, NULL, NULL, &size);
1607     ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1608      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1609      GetLastError());
1610     ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData,
1611      toBeSigned->cbData, &algoID, NULL, NULL, &size);
1612     ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1613      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1614      GetLastError());
1615
1616     /* No keys exist in the new CSP yet.. */
1617     ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1618      toBeSigned->cbData, &algoID, NULL, NULL, &size);
1619     ok(!ret && (GetLastError() == NTE_BAD_KEYSET || GetLastError() ==
1620      NTE_NO_KEY), "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %08x\n",
1621      GetLastError());
1622     ret = CryptGenKey(csp, AT_SIGNATURE, 0, key);
1623     ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1624     if (ret)
1625     {
1626         ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1627          toBeSigned->cbData, &algoID, NULL, NULL, &size);
1628         ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1629         ok(size <= *sigLen, "Expected size <= %d, got %d\n", *sigLen, size);
1630         if (ret)
1631         {
1632             ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1633              toBeSigned->cbData, &algoID, NULL, sig, &size);
1634             ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1635             if (ret)
1636             {
1637                 *sigLen = size;
1638                 verifySig(csp, toBeSigned->pbData, toBeSigned->cbData, sig,
1639                  size);
1640             }
1641         }
1642     }
1643 }
1644
1645 static void testVerifyCertSig(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1646  LPCSTR sigOID, const BYTE *sig, DWORD sigLen)
1647 {
1648     CERT_SIGNED_CONTENT_INFO info;
1649     LPBYTE cert = NULL;
1650     DWORD size = 0;
1651     BOOL ret;
1652
1653     if (!pCryptVerifyCertificateSignatureEx)
1654     {
1655         skip("no CryptVerifyCertificateSignatureEx support\n");
1656         return;
1657     }
1658     if (!pCryptEncodeObjectEx)
1659     {
1660         skip("no CryptEncodeObjectEx support\n");
1661         return;
1662     }
1663     ret = pCryptVerifyCertificateSignatureEx(0, 0, 0, NULL, 0, NULL, 0, NULL);
1664     ok(!ret && GetLastError() == E_INVALIDARG,
1665      "Expected E_INVALIDARG, got %08x\n", GetLastError());
1666     ret = pCryptVerifyCertificateSignatureEx(csp, 0, 0, NULL, 0, NULL, 0, NULL);
1667     ok(!ret && GetLastError() == E_INVALIDARG,
1668      "Expected E_INVALIDARG, got %08x\n", GetLastError());
1669     ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 0, NULL, 0,
1670      NULL, 0, NULL);
1671     ok(!ret && GetLastError() == E_INVALIDARG,
1672      "Expected E_INVALIDARG, got %08x\n", GetLastError());
1673     /* This crashes
1674     ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1675      CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, NULL, 0, NULL, 0, NULL);
1676      */
1677     info.ToBeSigned.cbData = toBeSigned->cbData;
1678     info.ToBeSigned.pbData = toBeSigned->pbData;
1679     info.SignatureAlgorithm.pszObjId = (LPSTR)sigOID;
1680     info.SignatureAlgorithm.Parameters.cbData = 0;
1681     info.Signature.cbData = sigLen;
1682     info.Signature.pbData = (BYTE *)sig;
1683     info.Signature.cUnusedBits = 0;
1684     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT, &info,
1685      CRYPT_ENCODE_ALLOC_FLAG, NULL, &cert, &size);
1686     ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1687     if (cert)
1688     {
1689         CRYPT_DATA_BLOB certBlob = { 0, NULL };
1690         PCERT_PUBLIC_KEY_INFO pubKeyInfo = NULL;
1691
1692         ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1693          CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1694         ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
1695          "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
1696         certBlob.cbData = 1;
1697         certBlob.pbData = (void *)0xdeadbeef;
1698         ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1699          CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1700         ok(!ret && (GetLastError() == STATUS_ACCESS_VIOLATION ||
1701                     GetLastError() == CRYPT_E_ASN1_EOD /* Win9x */ ||
1702                     GetLastError() == CRYPT_E_ASN1_BADTAG /* Win98 */),
1703          "Expected STATUS_ACCESS_VIOLATION, CRYPT_E_ASN1_EOD, OR CRYPT_E_ASN1_BADTAG, got %08x\n",
1704          GetLastError());
1705
1706         certBlob.cbData = size;
1707         certBlob.pbData = cert;
1708         ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1709          CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1710         ok(!ret && GetLastError() == E_INVALIDARG,
1711          "Expected E_INVALIDARG, got %08x\n", GetLastError());
1712         ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1713          CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1714          CRYPT_VERIFY_CERT_SIGN_ISSUER_NULL, NULL, 0, NULL);
1715         ok(!ret && GetLastError() == E_INVALIDARG,
1716          "Expected E_INVALIDARG, got %08x\n", GetLastError());
1717         /* This crashes
1718         ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1719          CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1720          CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, NULL, 0, NULL);
1721          */
1722         CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
1723          (LPSTR)sigOID, 0, NULL, NULL, &size);
1724         pubKeyInfo = HeapAlloc(GetProcessHeap(), 0, size);
1725         if (pubKeyInfo)
1726         {
1727             ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
1728              X509_ASN_ENCODING, (LPSTR)sigOID, 0, NULL, pubKeyInfo, &size);
1729             ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
1730             if (ret)
1731             {
1732                 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1733                  CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
1734                  CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pubKeyInfo, 0, NULL);
1735                 ok(ret, "CryptVerifyCertificateSignatureEx failed: %08x\n",
1736                  GetLastError());
1737             }
1738             HeapFree(GetProcessHeap(), 0, pubKeyInfo);
1739         }
1740         LocalFree(cert);
1741     }
1742 }
1743
1744 static BYTE emptyCert[] = { 0x30, 0x00 };
1745
1746 static void testCertSigs(void)
1747 {
1748     HCRYPTPROV csp;
1749     CRYPT_DATA_BLOB toBeSigned = { sizeof(emptyCert), emptyCert };
1750     BOOL ret;
1751     HCRYPTKEY key;
1752     BYTE sig[64];
1753     DWORD sigSize = sizeof(sig);
1754
1755     /* Just in case a previous run failed, delete this thing */
1756     pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1757      CRYPT_DELETEKEYSET);
1758     ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1759      CRYPT_NEWKEYSET);
1760     ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1761
1762     testSignCert(csp, &toBeSigned, szOID_RSA_SHA1RSA, &key, sig, &sigSize);
1763     testVerifyCertSig(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize);
1764
1765     CryptDestroyKey(key);
1766     CryptReleaseContext(csp, 0);
1767     ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1768      CRYPT_DELETEKEYSET);
1769 }
1770
1771 static const BYTE md5SignedEmptyCert[] = {
1772 0x30,0x56,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1773 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
1774 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
1775 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1776 0x0d,0x02,0x05,0x05,0x00,0x03,0x11,0x00,0xfb,0x0f,0x66,0x82,0x66,0xd9,0xe5,0xf8,
1777 0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
1778 static const BYTE md5SignedEmptyCertNoNull[] = {
1779 0x30,0x54,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
1780 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
1781 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
1782 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
1783 0x0d,0x02,0x05,0x03,0x11,0x00,0x04,0xd9,0xa5,0xe1,0x2b,0x55,0xa2,0xd8,0xf8,0xe5,
1784 0xd9,0x66,0x82,0x66,0x0f,0xfb };
1785
1786 static void testSignAndEncodeCert(void)
1787 {
1788     static char oid_rsa_md5rsa[] = szOID_RSA_MD5RSA;
1789     static char oid_rsa_md5[] = szOID_RSA_MD5;
1790     BOOL ret;
1791     DWORD size;
1792     CRYPT_ALGORITHM_IDENTIFIER algID = { 0 };
1793     CERT_INFO info = { 0 };
1794
1795     /* Crash
1796     ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1797      NULL);
1798     ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
1799      &size);
1800      */
1801     ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, &algID, NULL, NULL,
1802      &size);
1803     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1804      "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1805     ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, NULL, NULL,
1806      &algID, NULL, NULL, &size);
1807     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1808      "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1809     ret = CryptSignAndEncodeCertificate(0, 0, 0, X509_CERT_TO_BE_SIGNED, NULL,
1810      &algID, NULL, NULL, &size);
1811     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
1812      "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1813     /* Crashes on some win9x boxes */
1814     if (0)
1815     {
1816         ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1817          X509_CERT_TO_BE_SIGNED, NULL, &algID, NULL, NULL, &size);
1818         ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1819          "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1820     }
1821     /* Crashes
1822     ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1823      X509_CERT_TO_BE_SIGNED, &info, NULL, NULL, NULL, &size);
1824      */
1825     ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1826      X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1827     ok(!ret &&
1828      (GetLastError() == NTE_BAD_ALGID ||
1829       GetLastError() == OSS_BAD_PTR), /* win9x */
1830      "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1831     algID.pszObjId = oid_rsa_md5rsa;
1832     ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1833      X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1834     ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID),
1835      "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1836      GetLastError());
1837     algID.pszObjId = oid_rsa_md5;
1838     ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1839      X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
1840     /* oid_rsa_md5 not present in some win2k */
1841     if (ret)
1842     {
1843         LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size);
1844
1845         if (buf)
1846         {
1847             ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
1848              X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, buf, &size);
1849             ok(ret, "CryptSignAndEncodeCertificate failed: %08x\n",
1850              GetLastError());
1851             /* Tricky: because the NULL parameters may either be omitted or
1852              * included as an asn.1-encoded NULL (0x05,0x00), two different
1853              * values are allowed.
1854              */
1855             ok(size == sizeof(md5SignedEmptyCert) ||
1856              size == sizeof(md5SignedEmptyCertNoNull), "Unexpected size %d\n",
1857              size);
1858             if (size == sizeof(md5SignedEmptyCert))
1859                 ok(!memcmp(buf, md5SignedEmptyCert, size),
1860                  "Unexpected value\n");
1861             else if (size == sizeof(md5SignedEmptyCertNoNull))
1862                 ok(!memcmp(buf, md5SignedEmptyCertNoNull, size),
1863                  "Unexpected value\n");
1864             HeapFree(GetProcessHeap(), 0, buf);
1865         }
1866     }
1867 }
1868
1869 static void testCreateSelfSignCert(void)
1870 {
1871     PCCERT_CONTEXT context;
1872     CERT_NAME_BLOB name = { sizeof(subjectName), subjectName };
1873     HCRYPTPROV csp;
1874     BOOL ret;
1875     HCRYPTKEY key;
1876     CRYPT_KEY_PROV_INFO info;
1877
1878     if (!pCertCreateSelfSignCertificate)
1879     {
1880         skip("CertCreateSelfSignCertificate() is not available\n");
1881         return;
1882     }
1883
1884     /* This crashes:
1885     context = pCertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL,
1886      NULL);
1887      * Calling this with no first parameter creates a new key container, which
1888      * lasts beyond the test, so I don't test that.  Nb: the generated key
1889      * name is a GUID.
1890     context = pCertCreateSelfSignCertificate(0, &name, 0, NULL, NULL, NULL, NULL,
1891      NULL);
1892      */
1893
1894     /* Acquire a CSP */
1895     pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1896      CRYPT_DELETEKEYSET);
1897     ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1898      CRYPT_NEWKEYSET);
1899     ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
1900
1901     context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1902      NULL, NULL);
1903     ok(!context && GetLastError() == NTE_NO_KEY,
1904      "Expected NTE_NO_KEY, got %08x\n", GetLastError());
1905     ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
1906     ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1907     if (ret)
1908     {
1909         context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
1910          NULL, NULL);
1911         ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1912          GetLastError());
1913         if (context)
1914         {
1915             DWORD size = 0;
1916             PCRYPT_KEY_PROV_INFO info;
1917
1918             /* The context must have a key provider info property */
1919             ret = CertGetCertificateContextProperty(context,
1920              CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1921             ok(ret && size, "Expected non-zero key provider info\n");
1922             if (size)
1923             {
1924                 info = HeapAlloc(GetProcessHeap(), 0, size);
1925                 if (info)
1926                 {
1927                     ret = CertGetCertificateContextProperty(context,
1928                      CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1929                     ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1930                      GetLastError());
1931                     if (ret)
1932                     {
1933                         /* Sanity-check the key provider */
1934                         ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1935                          "Unexpected key container\n");
1936                         ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1937                          "Unexpected provider\n");
1938                         ok(info->dwKeySpec == AT_SIGNATURE,
1939                          "Expected AT_SIGNATURE, got %d\n", info->dwKeySpec);
1940                     }
1941                     HeapFree(GetProcessHeap(), 0, info);
1942                 }
1943             }
1944
1945             CertFreeCertificateContext(context);
1946         }
1947
1948         CryptDestroyKey(key);
1949     }
1950
1951     CryptReleaseContext(csp, 0);
1952     ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
1953      CRYPT_DELETEKEYSET);
1954
1955     /* do the same test with AT_KEYEXCHANGE  and key info*/
1956     memset(&info,0,sizeof(info));
1957     info.dwProvType = PROV_RSA_FULL;
1958     info.dwKeySpec = AT_KEYEXCHANGE;
1959     info.pwszProvName = (LPWSTR) MS_DEF_PROV_W;
1960     info.pwszContainerName = cspNameW;
1961     context = pCertCreateSelfSignCertificate(0, &name, 0, &info, NULL, NULL,
1962         NULL, NULL);
1963     ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
1964         GetLastError());
1965     if (context)
1966     {
1967         DWORD size = 0;
1968         PCRYPT_KEY_PROV_INFO info;
1969
1970         /* The context must have a key provider info property */
1971         ret = CertGetCertificateContextProperty(context,
1972             CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
1973         ok(ret && size, "Expected non-zero key provider info\n");
1974         if (size)
1975         {
1976             info = HeapAlloc(GetProcessHeap(), 0, size);
1977             if (info)
1978             {
1979                 ret = CertGetCertificateContextProperty(context,
1980                     CERT_KEY_PROV_INFO_PROP_ID, info, &size);
1981                 ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
1982                     GetLastError());
1983                 if (ret)
1984                 {
1985                     /* Sanity-check the key provider */
1986                     ok(!lstrcmpW(info->pwszContainerName, cspNameW),
1987                         "Unexpected key container\n");
1988                     ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
1989                         "Unexpected provider\n");
1990                     ok(info->dwKeySpec == AT_KEYEXCHANGE,
1991                         "Expected AT_KEYEXCHANGE, got %d\n", info->dwKeySpec);
1992                 }
1993                 HeapFree(GetProcessHeap(), 0, info);
1994             }
1995         }
1996
1997         CertFreeCertificateContext(context);
1998     }
1999
2000     pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2001         CRYPT_DELETEKEYSET);
2002 }
2003
2004 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
2005  szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
2006
2007 static void testKeyUsage(void)
2008 {
2009     BOOL ret;
2010     PCCERT_CONTEXT context;
2011     DWORD size;
2012
2013     /* Test base cases */
2014     ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, NULL);
2015     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2016      "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2017     size = 1;
2018     ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
2019     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2020      "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2021     size = 0;
2022     ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
2023     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2024      "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2025     /* These crash
2026     ret = CertSetEnhancedKeyUsage(NULL, NULL);
2027     usage.cUsageIdentifier = 0;
2028     ret = CertSetEnhancedKeyUsage(NULL, &usage);
2029      */
2030     /* Test with a cert with no enhanced key usage extension */
2031     context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2032      sizeof(bigCert));
2033     ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2034      GetLastError());
2035     if (context)
2036     {
2037         static const char oid[] = "1.2.3.4";
2038         BYTE buf[sizeof(CERT_ENHKEY_USAGE) + 2 * (sizeof(LPSTR) + sizeof(oid))];
2039         PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2040
2041         ret = CertGetEnhancedKeyUsage(context, 0, NULL, NULL);
2042         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2043          "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2044         size = 1;
2045         ret = CertGetEnhancedKeyUsage(context, 0, NULL, &size);
2046         if (ret)
2047         {
2048             /* Windows 2000, ME, or later: even though it succeeded, we expect
2049              * CRYPT_E_NOT_FOUND, which indicates there is no enhanced key
2050              * usage set for this cert (which implies it's valid for all uses.)
2051              */
2052             ok(GetLastError() == CRYPT_E_NOT_FOUND,
2053              "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2054             ok(size == sizeof(CERT_ENHKEY_USAGE), "Wrong size %d\n", size);
2055             ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2056             ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2057             ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2058              pUsage->cUsageIdentifier);
2059         }
2060         else
2061         {
2062             /* Windows NT, 95, or 98: it fails, and the last error is
2063              * CRYPT_E_NOT_FOUND.
2064              */
2065             ok(GetLastError() == CRYPT_E_NOT_FOUND,
2066              "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2067         }
2068         /* I can add a usage identifier when no key usage has been set */
2069         ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2070         ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2071          GetLastError());
2072         size = sizeof(buf);
2073         ret = CertGetEnhancedKeyUsage(context,
2074          CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2075         ok(ret && GetLastError() == 0,
2076          "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2077         ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2078          pUsage->cUsageIdentifier);
2079         if (pUsage->cUsageIdentifier)
2080             ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2081              "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2082         /* Now set an empty key usage */
2083         pUsage->cUsageIdentifier = 0;
2084         ret = CertSetEnhancedKeyUsage(context, pUsage);
2085         ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2086         /* Shouldn't find it in the cert */
2087         size = sizeof(buf);
2088         ret = CertGetEnhancedKeyUsage(context,
2089          CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2090         ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2091          "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2092         /* Should find it as an extended property */
2093         ret = CertGetEnhancedKeyUsage(context,
2094          CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2095         ok(ret && GetLastError() == 0,
2096          "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2097         ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2098          pUsage->cUsageIdentifier);
2099         /* Should find it as either */
2100         ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2101         ok(ret && GetLastError() == 0,
2102          "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2103         ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2104          pUsage->cUsageIdentifier);
2105         /* Add a usage identifier */
2106         ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2107         ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2108          GetLastError());
2109         size = sizeof(buf);
2110         ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2111         ok(ret && GetLastError() == 0,
2112          "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2113         ok(pUsage->cUsageIdentifier == 1, "Expected 1 identifier, got %d\n",
2114          pUsage->cUsageIdentifier);
2115         if (pUsage->cUsageIdentifier)
2116             ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2117              "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2118         /* Re-adding the same usage identifier succeeds, though it only adds
2119          * a duplicate usage identifier on versions prior to Vista
2120          */
2121         ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
2122         ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2123          GetLastError());
2124         size = sizeof(buf);
2125         ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2126         ok(ret && GetLastError() == 0,
2127          "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2128         ok(pUsage->cUsageIdentifier == 1 || pUsage->cUsageIdentifier == 2,
2129          "Expected 1 or 2 identifiers, got %d\n", pUsage->cUsageIdentifier);
2130         if (pUsage->cUsageIdentifier)
2131             ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2132              "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2133         if (pUsage->cUsageIdentifier >= 2)
2134             ok(!strcmp(pUsage->rgpszUsageIdentifier[1], oid),
2135              "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[1]);
2136         /* Now set a NULL extended property--this deletes the property. */
2137         ret = CertSetEnhancedKeyUsage(context, NULL);
2138         ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2139         SetLastError(0xbaadcafe);
2140         size = sizeof(buf);
2141         ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2142         ok(GetLastError() == CRYPT_E_NOT_FOUND,
2143          "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2144
2145         CertFreeCertificateContext(context);
2146     }
2147     /* Now test with a cert with an enhanced key usage extension */
2148     context = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2149      sizeof(certWithUsage));
2150     ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2151      GetLastError());
2152     if (context)
2153     {
2154         LPBYTE buf = NULL;
2155         DWORD bufSize = 0, i;
2156
2157         /* The size may depend on what flags are used to query it, so I
2158          * realloc the buffer for each test.
2159          */
2160         ret = CertGetEnhancedKeyUsage(context,
2161          CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2162         ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2163         buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2164         if (buf)
2165         {
2166             PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2167
2168             /* Should find it in the cert */
2169             size = bufSize;
2170             ret = CertGetEnhancedKeyUsage(context,
2171              CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2172             ok(ret && GetLastError() == 0,
2173              "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2174             ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2175              pUsage->cUsageIdentifier);
2176             for (i = 0; i < pUsage->cUsageIdentifier; i++)
2177                 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2178                  "Expected %s, got %s\n", keyUsages[i],
2179                  pUsage->rgpszUsageIdentifier[i]);
2180             HeapFree(GetProcessHeap(), 0, buf);
2181         }
2182         ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2183         ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2184         buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2185         if (buf)
2186         {
2187             PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2188
2189             /* Should find it as either */
2190             size = bufSize;
2191             ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2192             /* In Windows, GetLastError returns CRYPT_E_NOT_FOUND not found
2193              * here, even though the return is successful and the usage id
2194              * count is positive.  I don't enforce that here.
2195              */
2196             ok(ret,
2197              "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2198             ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2199              pUsage->cUsageIdentifier);
2200             for (i = 0; i < pUsage->cUsageIdentifier; i++)
2201                 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2202                  "Expected %s, got %s\n", keyUsages[i],
2203                  pUsage->rgpszUsageIdentifier[i]);
2204             HeapFree(GetProcessHeap(), 0, buf);
2205         }
2206         /* Shouldn't find it as an extended property */
2207         ret = CertGetEnhancedKeyUsage(context,
2208          CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &size);
2209         ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
2210          "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2211         /* Adding a usage identifier overrides the cert's usage!? */
2212         ret = CertAddEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2213         ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2214          GetLastError());
2215         ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2216         ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2217         buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2218         if (buf)
2219         {
2220             PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2221
2222             /* Should find it as either */
2223             size = bufSize;
2224             ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2225             ok(ret,
2226              "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2227             ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2228              pUsage->cUsageIdentifier);
2229             ok(!strcmp(pUsage->rgpszUsageIdentifier[0], szOID_RSA_RSA),
2230              "Expected %s, got %s\n", szOID_RSA_RSA,
2231              pUsage->rgpszUsageIdentifier[0]);
2232             HeapFree(GetProcessHeap(), 0, buf);
2233         }
2234         /* But querying the cert directly returns its usage */
2235         ret = CertGetEnhancedKeyUsage(context,
2236          CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
2237         ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2238         buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2239         if (buf)
2240         {
2241             PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2242
2243             size = bufSize;
2244             ret = CertGetEnhancedKeyUsage(context,
2245              CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
2246             ok(ret,
2247              "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2248             ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2249              pUsage->cUsageIdentifier);
2250             for (i = 0; i < pUsage->cUsageIdentifier; i++)
2251                 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2252                  "Expected %s, got %s\n", keyUsages[i],
2253                  pUsage->rgpszUsageIdentifier[i]);
2254             HeapFree(GetProcessHeap(), 0, buf);
2255         }
2256         /* And removing the only usage identifier in the extended property
2257          * results in the cert's key usage being found.
2258          */
2259         ret = CertRemoveEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
2260         ok(ret, "CertRemoveEnhancedKeyUsage failed: %08x\n", GetLastError());
2261         ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
2262         ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2263         buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
2264         if (buf)
2265         {
2266             PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
2267
2268             /* Should find it as either */
2269             size = bufSize;
2270             ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2271             ok(ret,
2272              "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2273             ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2274              pUsage->cUsageIdentifier);
2275             for (i = 0; i < pUsage->cUsageIdentifier; i++)
2276                 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2277                  "Expected %s, got %s\n", keyUsages[i],
2278                  pUsage->rgpszUsageIdentifier[i]);
2279             HeapFree(GetProcessHeap(), 0, buf);
2280         }
2281
2282         CertFreeCertificateContext(context);
2283     }
2284 }
2285
2286 static const BYTE cert2WithUsage[] = {
2287 0x30,0x81,0x89,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2288 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2289 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2290 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2291 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2292 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2293 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x25,0x30,0x23,
2294 0x30,0x21,0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x17,0x30,0x15,0x06,
2295 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x2a,0x86,0x48,0x86,
2296 0xf7,0x0d,0x01,0x01,0x01 };
2297
2298 static void testGetValidUsages(void)
2299 {
2300     static const LPCSTR expectedOIDs[] = {
2301      "1.3.6.1.5.5.7.3.3",
2302      "1.3.6.1.5.5.7.3.2",
2303      "1.2.840.113549.1.1.1",
2304     };
2305     static const LPCSTR expectedOIDs2[] = {
2306      "1.3.6.1.5.5.7.3.2",
2307      "1.2.840.113549.1.1.1",
2308     };
2309     BOOL ret;
2310     int numOIDs;
2311     DWORD size;
2312     LPSTR *oids = NULL;
2313     PCCERT_CONTEXT contexts[3];
2314
2315     if (!pCertGetValidUsages)
2316     {
2317         skip("CertGetValidUsages() is not available\n");
2318         return;
2319     }
2320
2321     /* Crash
2322     ret = pCertGetValidUsages(0, NULL, NULL, NULL, NULL);
2323     ret = pCertGetValidUsages(0, NULL, NULL, NULL, &size);
2324      */
2325     contexts[0] = NULL;
2326     numOIDs = size = 0xdeadbeef;
2327     SetLastError(0xdeadbeef);
2328     ret = pCertGetValidUsages(1, &contexts[0], &numOIDs, NULL, &size);
2329     ok(ret, "CertGetValidUsages failed: %d\n", GetLastError());
2330     ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2331     ok(size == 0, "Expected size 0, got %d\n", size);
2332     contexts[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2333      sizeof(bigCert));
2334     contexts[1] = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
2335      sizeof(certWithUsage));
2336     contexts[2] = CertCreateCertificateContext(X509_ASN_ENCODING,
2337      cert2WithUsage, sizeof(cert2WithUsage));
2338     numOIDs = size = 0xdeadbeef;
2339     ret = pCertGetValidUsages(0, NULL, &numOIDs, NULL, &size);
2340     ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2341     ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2342     ok(size == 0, "Expected size 0, got %d\n", size);
2343     numOIDs = size = 0xdeadbeef;
2344     ret = pCertGetValidUsages(1, contexts, &numOIDs, NULL, &size);
2345     ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2346     ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2347     ok(size == 0, "Expected size 0, got %d\n", size);
2348     ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, NULL, &size);
2349     ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2350     ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2351     ok(size, "Expected non-zero size\n");
2352     oids = HeapAlloc(GetProcessHeap(), 0, size);
2353     if (oids)
2354     {
2355         int i;
2356         DWORD smallSize = 1;
2357
2358         SetLastError(0xdeadbeef);
2359         ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &smallSize);
2360         ok(!ret && GetLastError() == ERROR_MORE_DATA,
2361          "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
2362         ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2363         ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2364         for (i = 0; i < numOIDs; i++)
2365             ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2366              oids[i]);
2367         HeapFree(GetProcessHeap(), 0, oids);
2368     }
2369     numOIDs = size = 0xdeadbeef;
2370     /* Oddly enough, this crashes when the number of contexts is not 1:
2371     ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2372      * but setting size to 0 allows it to succeed:
2373      */
2374     size = 0;
2375     ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2376     ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2377     ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2378     ok(size, "Expected non-zero size\n");
2379     oids = HeapAlloc(GetProcessHeap(), 0, size);
2380     if (oids)
2381     {
2382         int i;
2383
2384         ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2385         ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2386         for (i = 0; i < numOIDs; i++)
2387             ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2388              oids[i]);
2389         HeapFree(GetProcessHeap(), 0, oids);
2390     }
2391     numOIDs = 0xdeadbeef;
2392     size = 0;
2393     ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, NULL, &size);
2394     ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2395     ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2396     ok(size, "Expected non-zero size\n");
2397     oids = HeapAlloc(GetProcessHeap(), 0, size);
2398     if (oids)
2399     {
2400         int i;
2401
2402         ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, oids, &size);
2403         ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2404         for (i = 0; i < numOIDs; i++)
2405             ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2406              oids[i]);
2407         HeapFree(GetProcessHeap(), 0, oids);
2408     }
2409     numOIDs = 0xdeadbeef;
2410     size = 0;
2411     ret = pCertGetValidUsages(3, contexts, &numOIDs, NULL, &size);
2412     ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2413     ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2414     ok(size, "Expected non-zero size\n");
2415     oids = HeapAlloc(GetProcessHeap(), 0, size);
2416     if (oids)
2417     {
2418         int i;
2419
2420         ret = pCertGetValidUsages(3, contexts, &numOIDs, oids, &size);
2421         ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2422         for (i = 0; i < numOIDs; i++)
2423             ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2424              oids[i]);
2425         HeapFree(GetProcessHeap(), 0, oids);
2426     }
2427     CertFreeCertificateContext(contexts[0]);
2428     CertFreeCertificateContext(contexts[1]);
2429     CertFreeCertificateContext(contexts[2]);
2430 }
2431
2432 static void testCompareCertName(void)
2433 {
2434     static BYTE bogus[] = { 1, 2, 3, 4 };
2435     static BYTE bogusPrime[] = { 0, 1, 2, 3, 4 };
2436     static BYTE emptyPrime[] = { 0x30, 0x00, 0x01 };
2437     BOOL ret;
2438     CERT_NAME_BLOB blob1, blob2;
2439
2440     /* crashes
2441     ret = CertCompareCertificateName(0, NULL, NULL);
2442      */
2443     /* An empty name checks against itself.. */
2444     blob1.pbData = emptyCert;
2445     blob1.cbData = sizeof(emptyCert);
2446     ret = CertCompareCertificateName(0, &blob1, &blob1);
2447     ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2448     /* It doesn't have to be a valid encoded name.. */
2449     blob1.pbData = bogus;
2450     blob1.cbData = sizeof(bogus);
2451     ret = CertCompareCertificateName(0, &blob1, &blob1);
2452     ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2453     /* Leading zeroes matter.. */
2454     blob2.pbData = bogusPrime;
2455     blob2.cbData = sizeof(bogusPrime);
2456     ret = CertCompareCertificateName(0, &blob1, &blob2);
2457     ok(!ret, "Expected failure\n");
2458     /* As do trailing extra bytes. */
2459     blob2.pbData = emptyPrime;
2460     blob2.cbData = sizeof(emptyPrime);
2461     ret = CertCompareCertificateName(0, &blob1, &blob2);
2462     ok(!ret, "Expected failure\n");
2463 }
2464
2465 static BYTE int1[] = { 0x88, 0xff, 0xff, 0xff };
2466 static BYTE int2[] = { 0x88, 0xff };
2467 static BYTE int3[] = { 0x23, 0xff };
2468 static BYTE int4[] = { 0x7f, 0x00 };
2469 static BYTE int5[] = { 0x7f };
2470 static BYTE int6[] = { 0x80, 0x00, 0x00, 0x00 };
2471 static BYTE int7[] = { 0x80, 0x00 };
2472
2473 static struct IntBlobTest
2474 {
2475     CRYPT_INTEGER_BLOB blob1;
2476     CRYPT_INTEGER_BLOB blob2;
2477     BOOL areEqual;
2478 } intBlobs[] = {
2479  { { sizeof(int1), int1 }, { sizeof(int2), int2 }, TRUE },
2480  { { sizeof(int3), int3 }, { sizeof(int3), int3 }, TRUE },
2481  { { sizeof(int4), int4 }, { sizeof(int5), int5 }, TRUE },
2482  { { sizeof(int6), int6 }, { sizeof(int7), int7 }, TRUE },
2483  { { sizeof(int1), int1 }, { sizeof(int7), int7 }, FALSE },
2484 };
2485
2486 static void testCompareIntegerBlob(void)
2487 {
2488     DWORD i;
2489     BOOL ret;
2490
2491     for (i = 0; i < sizeof(intBlobs) / sizeof(intBlobs[0]); i++)
2492     {
2493         ret = CertCompareIntegerBlob(&intBlobs[i].blob1, &intBlobs[i].blob2);
2494         ok(ret == intBlobs[i].areEqual,
2495          "%d: expected blobs %s compare\n", i, intBlobs[i].areEqual ?
2496          "to" : "not to");
2497     }
2498 }
2499
2500 static void testComparePublicKeyInfo(void)
2501 {
2502     BOOL ret;
2503     CERT_PUBLIC_KEY_INFO info1 = { { 0 } }, info2 = { { 0 } };
2504     static CHAR oid_rsa_rsa[]     = szOID_RSA_RSA;
2505     static CHAR oid_rsa_sha1rsa[] = szOID_RSA_SHA1RSA;
2506     static CHAR oid_x957_dsa[]    = szOID_X957_DSA;
2507     static BYTE bits1[] = { 1, 0 };
2508     static BYTE bits2[] = { 0 };
2509     static BYTE bits3[] = { 1 };
2510     static BYTE bits4[] = { 0x30,8, 2,1,0x81, 2,3,1,0,1 };
2511     static BYTE bits5[] = { 0x30,9, 2,2,0,0x81, 2,3,1,0,1 };
2512     static BYTE bits6[] = { 0x30,9, 2,2,0,0x82, 2,3,1,0,1 };
2513
2514     /* crashes
2515     ret = CertComparePublicKeyInfo(0, NULL, NULL);
2516      */
2517     /* Empty public keys compare */
2518     ret = CertComparePublicKeyInfo(0, &info1, &info2);
2519     ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2520     /* Different OIDs appear to compare */
2521     info1.Algorithm.pszObjId = oid_rsa_rsa;
2522     info2.Algorithm.pszObjId = oid_rsa_sha1rsa;
2523     ret = CertComparePublicKeyInfo(0, &info1, &info2);
2524     ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2525     info2.Algorithm.pszObjId = oid_x957_dsa;
2526     ret = CertComparePublicKeyInfo(0, &info1, &info2);
2527     ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2528     info1.PublicKey.cbData = sizeof(bits1);
2529     info1.PublicKey.pbData = bits1;
2530     info1.PublicKey.cUnusedBits = 0;
2531     info2.PublicKey.cbData = sizeof(bits1);
2532     info2.PublicKey.pbData = bits1;
2533     info2.PublicKey.cUnusedBits = 0;
2534     ret = CertComparePublicKeyInfo(0, &info1, &info2);
2535     ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
2536     info2.Algorithm.pszObjId = oid_rsa_rsa;
2537     info1.PublicKey.cbData = sizeof(bits4);
2538     info1.PublicKey.pbData = bits4;
2539     info1.PublicKey.cUnusedBits = 0;
2540     info2.PublicKey.cbData = sizeof(bits5);
2541     info2.PublicKey.pbData = bits5;
2542     info2.PublicKey.cUnusedBits = 0;
2543     ret = CertComparePublicKeyInfo(0, &info1, &info2);
2544     ok(!ret, "CertComparePublicKeyInfo: as raw binary: keys should be unequal\n");
2545     ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2546     ok(ret ||
2547      broken(!ret), /* win9x */
2548      "CertComparePublicKeyInfo: as ASN.1 encoded: keys should be equal\n");
2549     info1.PublicKey.cUnusedBits = 1;
2550     info2.PublicKey.cUnusedBits = 5;
2551     ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2552     ok(ret ||
2553      broken(!ret), /* win9x */
2554      "CertComparePublicKeyInfo: ASN.1 encoding should ignore cUnusedBits\n");
2555     info1.PublicKey.cUnusedBits = 0;
2556     info2.PublicKey.cUnusedBits = 0;
2557     info1.PublicKey.cbData--; /* kill one byte, make ASN.1 encoded data invalid */
2558     ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2559     ok(!ret, "CertComparePublicKeyInfo: comparing bad ASN.1 encoded key should fail\n");
2560     /* Even though they compare in their used bits, these do not compare */
2561     info1.PublicKey.cbData = sizeof(bits2);
2562     info1.PublicKey.pbData = bits2;
2563     info1.PublicKey.cUnusedBits = 0;
2564     info2.PublicKey.cbData = sizeof(bits3);
2565     info2.PublicKey.pbData = bits3;
2566     info2.PublicKey.cUnusedBits = 1;
2567     ret = CertComparePublicKeyInfo(0, &info1, &info2);
2568     /* Simple (non-comparing) case */
2569     ok(!ret, "Expected keys not to compare\n");
2570     info2.PublicKey.cbData = sizeof(bits1);
2571     info2.PublicKey.pbData = bits1;
2572     info2.PublicKey.cUnusedBits = 0;
2573     ret = CertComparePublicKeyInfo(0, &info1, &info2);
2574     ok(!ret, "Expected keys not to compare\n");
2575     /* ASN.1 encoded non-comparing case */
2576     info1.PublicKey.cbData = sizeof(bits5);
2577     info1.PublicKey.pbData = bits5;
2578     info1.PublicKey.cUnusedBits = 0;
2579     info2.PublicKey.cbData = sizeof(bits6);
2580     info2.PublicKey.pbData = bits6;
2581     info2.PublicKey.cUnusedBits = 0;
2582     ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
2583     ok(!ret, "CertComparePublicKeyInfo: different keys should be unequal\n");
2584 }
2585
2586 static void testHashPublicKeyInfo(void)
2587 {
2588     BOOL ret;
2589     CERT_PUBLIC_KEY_INFO info = { { 0 } };
2590     DWORD len;
2591
2592     /* Crash
2593     ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, NULL);
2594     ret = CryptHashPublicKeyInfo(0, 0, 0, 0, &info, NULL, NULL);
2595      */
2596     ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, &len);
2597     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2598      "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2599     /* Crashes on some win9x boxes */
2600     if (0)
2601     {
2602         ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, NULL, NULL, &len);
2603         ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2604          "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2605     }
2606     ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, NULL, &len);
2607     ok(ret ||
2608      broken(!ret), /* win9x */
2609      "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2610     if (ret)
2611     {
2612         ok(len == 16, "Expected hash size 16, got %d\n", len);
2613         if (len == 16)
2614         {
2615             static const BYTE emptyHash[] = { 0xb8,0x51,0x3a,0x31,0x0e,0x9f,0x40,
2616              0x36,0x9c,0x92,0x45,0x1b,0x9d,0xc8,0xf9,0xf6 };
2617             BYTE buf[16];
2618
2619             ret = CryptHashPublicKeyInfo(0, 0, 0, X509_ASN_ENCODING, &info, buf,
2620              &len);
2621             ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
2622             ok(!memcmp(buf, emptyHash, len), "Unexpected hash\n");
2623         }
2624     }
2625 }
2626
2627 static const BYTE md5SignedEmptyCertHash[] = { 0xfb,0x0f,0x66,0x82,0x66,0xd9,
2628  0xe5,0xf8,0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
2629
2630 static void testHashToBeSigned(void)
2631 {
2632     BOOL ret;
2633     DWORD size;
2634     BYTE hash[16];
2635
2636     /* Crash */
2637     if (0)
2638     {
2639         ret = CryptHashToBeSigned(0, 0, NULL, 0, NULL, NULL);
2640     }
2641     SetLastError(0xdeadbeef);
2642     ret = CryptHashToBeSigned(0, 0, NULL, 0, NULL, &size);
2643     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2644      "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
2645     SetLastError(0xdeadbeef);
2646     ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, NULL, 0, NULL, &size);
2647     ok(!ret &&
2648      (GetLastError() == CRYPT_E_ASN1_EOD ||
2649       GetLastError() == OSS_BAD_ARG), /* win9x */
2650      "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2651     /* Can't sign anything:  has to be asn.1 encoded, at least */
2652     SetLastError(0xdeadbeef);
2653     ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, int1, sizeof(int1),
2654      NULL, &size);
2655     ok(!ret &&
2656      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
2657       GetLastError() == OSS_MORE_INPUT), /* win9x */
2658      "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
2659     /* Can't be empty, either */
2660     SetLastError(0xdeadbeef);
2661     ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, emptyCert,
2662      sizeof(emptyCert), NULL, &size);
2663     ok(!ret &&
2664      (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2665       GetLastError() == OSS_DATA_ERROR), /* win9x */
2666      "expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2667     /* Signing a cert works */
2668     ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert,
2669      sizeof(md5SignedEmptyCert), NULL, &size);
2670     ok(ret ||
2671      broken(!ret), /* win9x */
2672      "CryptHashToBeSigned failed: %08x\n", GetLastError());
2673     if (ret)
2674     {
2675         ok(size == sizeof(md5SignedEmptyCertHash), "unexpected size %d\n", size);
2676     }
2677
2678     ret = CryptHashToBeSigned(0, X509_ASN_ENCODING, md5SignedEmptyCert,
2679      sizeof(md5SignedEmptyCert), hash, &size);
2680     ok(!memcmp(hash, md5SignedEmptyCertHash, size), "unexpected value\n");
2681 }
2682
2683 static void testCompareCert(void)
2684 {
2685     CERT_INFO info1 = { 0 }, info2 = { 0 };
2686     BOOL ret;
2687
2688     /* Crashes
2689     ret = CertCompareCertificate(X509_ASN_ENCODING, NULL, NULL);
2690      */
2691
2692     /* Certs with the same issuer and serial number are equal, even if they
2693      * differ in other respects (like subject).
2694      */
2695     info1.SerialNumber.pbData = serialNum;
2696     info1.SerialNumber.cbData = sizeof(serialNum);
2697     info1.Issuer.pbData = subjectName;
2698     info1.Issuer.cbData = sizeof(subjectName);
2699     info1.Subject.pbData = subjectName2;
2700     info1.Subject.cbData = sizeof(subjectName2);
2701     info2.SerialNumber.pbData = serialNum;
2702     info2.SerialNumber.cbData = sizeof(serialNum);
2703     info2.Issuer.pbData = subjectName;
2704     info2.Issuer.cbData = sizeof(subjectName);
2705     info2.Subject.pbData = subjectName;
2706     info2.Subject.cbData = sizeof(subjectName);
2707     ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2708     ok(ret, "Expected certs to be equal\n");
2709
2710     info2.Issuer.pbData = subjectName2;
2711     info2.Issuer.cbData = sizeof(subjectName2);
2712     ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
2713     ok(!ret, "Expected certs not to be equal\n");
2714 }
2715
2716 static void testVerifySubjectCert(void)
2717 {
2718     BOOL ret;
2719     DWORD flags;
2720     PCCERT_CONTEXT context1, context2;
2721
2722     /* Crashes
2723     ret = CertVerifySubjectCertificateContext(NULL, NULL, NULL);
2724      */
2725     flags = 0;
2726     ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2727     ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2728      GetLastError());
2729     flags = CERT_STORE_NO_CRL_FLAG;
2730     ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
2731     ok(!ret && GetLastError() == E_INVALIDARG,
2732      "Expected E_INVALIDARG, got %08x\n", GetLastError());
2733
2734     flags = 0;
2735     context1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
2736      sizeof(bigCert));
2737     ret = CertVerifySubjectCertificateContext(NULL, context1, &flags);
2738     ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2739      GetLastError());
2740     ret = CertVerifySubjectCertificateContext(context1, NULL, &flags);
2741     ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2742      GetLastError());
2743     ret = CertVerifySubjectCertificateContext(context1, context1, &flags);
2744     ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2745      GetLastError());
2746
2747     context2 = CertCreateCertificateContext(X509_ASN_ENCODING,
2748      bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject));
2749     SetLastError(0xdeadbeef);
2750     ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2751     ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2752      GetLastError());
2753     flags = CERT_STORE_REVOCATION_FLAG;
2754     ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2755     ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2756      GetLastError());
2757     ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
2758      "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
2759      flags);
2760     flags = CERT_STORE_SIGNATURE_FLAG;
2761     ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
2762     ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
2763      GetLastError());
2764     ok(flags == CERT_STORE_SIGNATURE_FLAG,
2765      "Expected CERT_STORE_SIGNATURE_FLAG, got %08x\n", flags);
2766     CertFreeCertificateContext(context2);
2767
2768     CertFreeCertificateContext(context1);
2769 }
2770
2771 static void testVerifyRevocation(void)
2772 {
2773     BOOL ret;
2774     CERT_REVOCATION_STATUS status = { 0 };
2775     PCCERT_CONTEXT cert = CertCreateCertificateContext(X509_ASN_ENCODING,
2776      bigCert, sizeof(bigCert));
2777
2778     /* Crash
2779     ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL);
2780      */
2781     SetLastError(0xdeadbeef);
2782     ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2783     ok(!ret && GetLastError() == E_INVALIDARG,
2784      "Expected E_INVALIDARG, got %08x\n", GetLastError());
2785     status.cbSize = sizeof(status);
2786     ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
2787     ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2788     ret = CertVerifyRevocation(0, 2, 0, NULL, 0, NULL, &status);
2789     ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2790     ret = CertVerifyRevocation(2, 0, 0, NULL, 0, NULL, &status);
2791     ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
2792     SetLastError(0xdeadbeef);
2793     ret = CertVerifyRevocation(0, 0, 1, (void **)&cert, 0, NULL, &status);
2794     ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2795      "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2796     SetLastError(0xdeadbeef);
2797     ret = CertVerifyRevocation(0, 2, 1, (void **)&cert, 0, NULL, &status);
2798     ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL,
2799      "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
2800
2801     CertFreeCertificateContext(cert);
2802 }
2803
2804 static BYTE privKey[] = {
2805  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
2806  0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
2807  0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
2808  0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
2809  0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
2810  0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
2811  0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
2812  0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
2813  0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
2814  0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
2815  0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
2816  0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
2817  0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
2818  0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
2819  0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
2820  0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
2821  0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
2822  0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
2823  0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
2824  0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
2825  0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
2826  0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
2827  0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
2828  0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
2829
2830 static const BYTE exportedPublicKeyBlob[] = {
2831 0x06,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x31,0x00,0x02,0x00,0x00,
2832 0x01,0x00,0x01,0x00,0x79,0x10,0x1c,0xd0,0x6b,0x10,0x18,0x30,0x94,0x61,0xdc,0x0e,
2833 0xcb,0x96,0x4e,0x21,0x3f,0x79,0xcd,0xa9,0x17,0x62,0xbc,0xbb,0x61,0x4c,0xe0,0x75,
2834 0x38,0x6c,0xf3,0xde,0x60,0x86,0x03,0x97,0x65,0xeb,0x1e,0x6b,0xdb,0x53,0x85,0xad,
2835 0x68,0x21,0xf1,0x5d,0xe7,0x1f,0xe6,0x53,0xb4,0xbb,0x59,0x3e,0x14,0x27,0xb1,0x83,
2836 0xa7,0x3a,0x54,0xe2 };
2837
2838 static const BYTE asnEncodedPublicKey[] = {
2839 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,
2840 0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
2841 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,
2842 0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
2843 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
2844
2845 static void testAcquireCertPrivateKey(void)
2846 {
2847     BOOL ret;
2848     PCCERT_CONTEXT cert;
2849     HCRYPTPROV csp;
2850     DWORD size, keySpec;
2851     BOOL callerFree;
2852     CRYPT_KEY_PROV_INFO keyProvInfo;
2853     HCRYPTKEY key;
2854     WCHAR ms_def_prov_w[MAX_PATH];
2855
2856     if (!pCryptAcquireCertificatePrivateKey)
2857     {
2858         skip("CryptAcquireCertificatePrivateKey() is not available\n");
2859         return;
2860     }
2861
2862     lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
2863
2864     keyProvInfo.pwszContainerName = cspNameW;
2865     keyProvInfo.pwszProvName = ms_def_prov_w;
2866     keyProvInfo.dwProvType = PROV_RSA_FULL;
2867     keyProvInfo.dwFlags = 0;
2868     keyProvInfo.cProvParam = 0;
2869     keyProvInfo.rgProvParam = NULL;
2870     keyProvInfo.dwKeySpec = AT_SIGNATURE;
2871
2872     pCryptAcquireContextA(NULL, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2873      CRYPT_DELETEKEYSET);
2874
2875     cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
2876      sizeof(selfSignedCert));
2877
2878     /* Crash
2879     ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL, NULL);
2880     ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, NULL,
2881      &callerFree);
2882     ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, NULL, &keySpec,
2883      NULL);
2884     ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, NULL, NULL);
2885     ret = pCryptAcquireCertificatePrivateKey(NULL, 0, NULL, &csp, &keySpec,
2886      &callerFree);
2887     ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, NULL, NULL, NULL);
2888      */
2889
2890     /* Missing private key */
2891     ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, NULL, NULL);
2892     ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2893      "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2894     ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2895      &callerFree);
2896     ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2897      "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2898     CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2899      &keyProvInfo);
2900     ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
2901      &callerFree);
2902     ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
2903      "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
2904
2905     pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2906      CRYPT_NEWKEYSET);
2907     ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
2908     ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
2909     if (ret)
2910     {
2911         HCRYPTPROV certCSP;
2912         DWORD size;
2913         CERT_KEY_CONTEXT keyContext;
2914
2915         /* Don't cache provider */
2916         ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2917          &keySpec, &callerFree);
2918         ok(ret ||
2919          broken(!ret), /* win95 */
2920          "CryptAcquireCertificatePrivateKey failed: %08x\n",
2921          GetLastError());
2922         if (ret)
2923         {
2924             ok(callerFree, "Expected callerFree to be TRUE\n");
2925             CryptReleaseContext(certCSP, 0);
2926         }
2927
2928         ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &certCSP,
2929          NULL, NULL);
2930         ok(ret ||
2931          broken(!ret), /* win95 */
2932          "CryptAcquireCertificatePrivateKey failed: %08x\n",
2933          GetLastError());
2934         CryptReleaseContext(certCSP, 0);
2935
2936         /* Use the key prov info's caching (there shouldn't be any) */
2937         ret = pCryptAcquireCertificatePrivateKey(cert,
2938          CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2939          &callerFree);
2940         ok(ret ||
2941          broken(!ret), /* win95 */
2942          "CryptAcquireCertificatePrivateKey failed: %08x\n",
2943          GetLastError());
2944         if (ret)
2945         {
2946             ok(callerFree, "Expected callerFree to be TRUE\n");
2947             CryptReleaseContext(certCSP, 0);
2948         }
2949
2950         /* Cache it (and check that it's cached) */
2951         ret = pCryptAcquireCertificatePrivateKey(cert,
2952          CRYPT_ACQUIRE_CACHE_FLAG, NULL, &certCSP, &keySpec, &callerFree);
2953         ok(ret ||
2954          broken(!ret), /* win95 */
2955          "CryptAcquireCertificatePrivateKey failed: %08x\n",
2956          GetLastError());
2957         ok(!callerFree, "Expected callerFree to be FALSE\n");
2958         size = sizeof(keyContext);
2959         ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2960          &keyContext, &size);
2961         ok(ret ||
2962          broken(!ret), /* win95 */
2963          "CertGetCertificateContextProperty failed: %08x\n",
2964          GetLastError());
2965
2966         /* Remove the cached provider */
2967         CryptReleaseContext(keyContext.hCryptProv, 0);
2968         CertSetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID, 0,
2969          NULL);
2970         /* Allow caching via the key prov info */
2971         keyProvInfo.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
2972         CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0,
2973          &keyProvInfo);
2974         /* Now use the key prov info's caching */
2975         ret = pCryptAcquireCertificatePrivateKey(cert,
2976          CRYPT_ACQUIRE_USE_PROV_INFO_FLAG, NULL, &certCSP, &keySpec,
2977          &callerFree);
2978         ok(ret ||
2979          broken(!ret), /* win95 */
2980          "CryptAcquireCertificatePrivateKey failed: %08x\n",
2981          GetLastError());
2982         ok(!callerFree, "Expected callerFree to be FALSE\n");
2983         size = sizeof(keyContext);
2984         ret = CertGetCertificateContextProperty(cert, CERT_KEY_CONTEXT_PROP_ID,
2985          &keyContext, &size);
2986         ok(ret ||
2987          broken(!ret), /* win95 */
2988          "CertGetCertificateContextProperty failed: %08x\n",
2989          GetLastError());
2990         CryptReleaseContext(certCSP, 0);
2991
2992         CryptDestroyKey(key);
2993     }
2994
2995     /* Some sanity-checking on public key exporting */
2996     ret = CryptImportPublicKeyInfo(csp, X509_ASN_ENCODING,
2997      &cert->pCertInfo->SubjectPublicKeyInfo, &key);
2998     ok(ret, "CryptImportPublicKeyInfo failed: %08x\n", GetLastError());
2999     if (ret)
3000     {
3001         ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, NULL, &size);
3002         ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
3003         if (ret)
3004         {
3005             LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, size), encodedKey;
3006
3007             ret = CryptExportKey(key, 0, PUBLICKEYBLOB, 0, buf, &size);
3008             ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
3009             ok(size == sizeof(exportedPublicKeyBlob), "Unexpected size %d\n",
3010              size);
3011             ok(!memcmp(buf, exportedPublicKeyBlob, size), "Unexpected value\n");
3012             ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB,
3013              buf, CRYPT_ENCODE_ALLOC_FLAG, NULL, &encodedKey, &size);
3014             ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3015             if (ret)
3016             {
3017                 ok(size == sizeof(asnEncodedPublicKey), "Unexpected size %d\n",
3018                  size);
3019                 ok(!memcmp(encodedKey, asnEncodedPublicKey, size),
3020                  "Unexpected value\n");
3021                 LocalFree(encodedKey);
3022             }
3023             HeapFree(GetProcessHeap(), 0, buf);
3024         }
3025         CryptDestroyKey(key);
3026     }
3027     ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
3028      NULL, 0, NULL, NULL, &size);
3029     ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
3030     if (ret)
3031     {
3032         PCERT_PUBLIC_KEY_INFO info = HeapAlloc(GetProcessHeap(), 0, size);
3033
3034         ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
3035          NULL, 0, NULL, info, &size);
3036         ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
3037         if (ret)
3038         {
3039             ok(info->PublicKey.cbData == sizeof(asnEncodedPublicKey),
3040              "Unexpected size %d\n", info->PublicKey.cbData);
3041             ok(!memcmp(info->PublicKey.pbData, asnEncodedPublicKey,
3042              info->PublicKey.cbData), "Unexpected value\n");
3043         }
3044         HeapFree(GetProcessHeap(), 0, info);
3045     }
3046
3047     CryptReleaseContext(csp, 0);
3048     pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
3049      CRYPT_DELETEKEYSET);
3050
3051     CertFreeCertificateContext(cert);
3052 }
3053
3054 static void testGetPublicKeyLength(void)
3055 {
3056     static char oid_rsa_rsa[] = szOID_RSA_RSA;
3057     static char oid_rsa_dh[] = szOID_RSA_DH;
3058     static char bogusOID[] = "1.2.3";
3059     DWORD ret;
3060     CERT_PUBLIC_KEY_INFO info = { { 0 } };
3061     BYTE bogusKey[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
3062     BYTE key[] = { 0x30,0x0f,0x02,0x08,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
3063      0x02,0x03,0x01,0x00,0x01 };
3064
3065     /* Crashes
3066     ret = CertGetPublicKeyLength(0, NULL);
3067      */
3068     /* With an empty public key info */
3069     SetLastError(0xdeadbeef);
3070     ret = CertGetPublicKeyLength(0, &info);
3071     ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3072      "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3073      ret, GetLastError());
3074     SetLastError(0xdeadbeef);
3075     ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3076     ok(ret == 0 &&
3077      (GetLastError() == CRYPT_E_ASN1_EOD ||
3078       GetLastError() == OSS_BAD_ARG), /* win9x */
3079      "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
3080      ret, GetLastError());
3081     /* With a nearly-empty public key info */
3082     info.Algorithm.pszObjId = oid_rsa_rsa;
3083     SetLastError(0xdeadbeef);
3084     ret = CertGetPublicKeyLength(0, &info);
3085     ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3086      "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3087      ret, GetLastError());
3088     SetLastError(0xdeadbeef);
3089     ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3090     ok(ret == 0 &&
3091      (GetLastError() == CRYPT_E_ASN1_EOD ||
3092       GetLastError() == OSS_BAD_ARG), /* win9x */
3093      "Expected length 0 and CRYPT_E_ASN1_EOD, got length %d, %08x\n",
3094      ret, GetLastError());
3095     /* With a bogus key */
3096     info.PublicKey.cbData = sizeof(bogusKey);
3097     info.PublicKey.pbData = bogusKey;
3098     SetLastError(0xdeadbeef);
3099     ret = CertGetPublicKeyLength(0, &info);
3100     ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3101      "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3102      ret, GetLastError());
3103     SetLastError(0xdeadbeef);
3104     ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3105     ok(ret == 0 &&
3106      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3107       GetLastError() == OSS_PDU_MISMATCH), /* win9x */
3108      "Expected length 0 and CRYPT_E_ASN1_BADTAGTAG, got length %d, %08x\n",
3109      ret, GetLastError());
3110     /* With a believable RSA key but a bogus OID */
3111     info.Algorithm.pszObjId = bogusOID;
3112     info.PublicKey.cbData = sizeof(key);
3113     info.PublicKey.pbData = key;
3114     SetLastError(0xdeadbeef);
3115     ret = CertGetPublicKeyLength(0, &info);
3116     ok(ret == 0 && GetLastError() == ERROR_FILE_NOT_FOUND,
3117      "Expected length 0 and ERROR_FILE_NOT_FOUND, got length %d, %08x\n",
3118      ret, GetLastError());
3119     SetLastError(0xdeadbeef);
3120     ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3121     ok(ret == 56, "Expected length 56, got %d\n", ret);
3122     /* An RSA key with the DH OID */
3123     info.Algorithm.pszObjId = oid_rsa_dh;
3124     SetLastError(0xdeadbeef);
3125     ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3126     ok(ret == 0 &&
3127      (GetLastError() == CRYPT_E_ASN1_BADTAG ||
3128       GetLastError() == E_INVALIDARG), /* win9x */
3129      "Expected length 0 and CRYPT_E_ASN1_BADTAG, got length %d, %08x\n",
3130      ret, GetLastError());
3131     /* With the RSA OID */
3132     info.Algorithm.pszObjId = oid_rsa_rsa;
3133     SetLastError(0xdeadbeef);
3134     ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info);
3135     ok(ret == 56, "Expected length 56, got %d\n", ret);
3136     /* With the RSA OID and a message encoding */
3137     info.Algorithm.pszObjId = oid_rsa_rsa;
3138     SetLastError(0xdeadbeef);
3139     ret = CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &info);
3140     ok(ret == 56, "Expected length 56, got %d\n", ret);
3141 }
3142
3143 START_TEST(cert)
3144 {
3145     init_function_pointers();
3146
3147     testAddCert();
3148     testCertProperties();
3149     testDupCert();
3150     testFindCert();
3151     testGetSubjectCert();
3152     testGetIssuerCert();
3153
3154     testCryptHashCert();
3155     testCertSigs();
3156     testSignAndEncodeCert();
3157     testCreateSelfSignCert();
3158     testKeyUsage();
3159     testGetValidUsages();
3160     testCompareCertName();
3161     testCompareIntegerBlob();
3162     testComparePublicKeyInfo();
3163     testHashPublicKeyInfo();
3164     testHashToBeSigned();
3165     testCompareCert();
3166     testVerifySubjectCert();
3167     testVerifyRevocation();
3168     testAcquireCertPrivateKey();
3169     testGetPublicKeyLength();
3170 }