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