ReactOS  0.4.14-dev-614-gbfd8a84
cert.c
Go to the documentation of this file.
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 <stdio.h>
22 #include <stdarg.h>
23 
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 
33 static BOOL (WINAPI *pCertGetValidUsages)(DWORD,PCCERT_CONTEXT*,int*,LPSTR*,DWORD*);
34 static BOOL (WINAPI *pCryptAcquireCertificatePrivateKey)(PCCERT_CONTEXT,DWORD,void*,HCRYPTPROV_OR_NCRYPT_KEY_HANDLE*,DWORD*,BOOL*);
35 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*);
36 static BOOL (WINAPI * pCryptVerifyCertificateSignatureEx)
37  (HCRYPTPROV, DWORD, DWORD, void *, DWORD, void *, DWORD, void *);
38 
39 static BOOL (WINAPI * pCryptAcquireContextA)
41 
42 static void init_function_pointers(void)
43 {
44  HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll");
45  HMODULE hAdvapi32 = GetModuleHandleA("advapi32.dll");
46 
47 #define GET_PROC(dll, func) \
48  p ## func = (void *)GetProcAddress(dll, #func); \
49  if(!p ## func) \
50  trace("GetProcAddress(%s) failed\n", #func);
51 
53  GET_PROC(hCrypt32, CertGetValidUsages)
55  GET_PROC(hCrypt32, CryptEncodeObjectEx)
57 
58  GET_PROC(hAdvapi32, CryptAcquireContextA)
59 
60 #undef GET_PROC
61 }
62 
63 static BYTE subjectName[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
64  0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
65  0x6e, 0x67, 0x00 };
66 static BYTE serialNum[] = { 1 };
67 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
68  0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
69  0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
70  0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
71  0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
72  0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
73  0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
74  0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
75  0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
76  0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
77 static BYTE bigCertHash[] = { 0x6e, 0x30, 0x90, 0x71, 0x5f, 0xd9, 0x23,
78  0x56, 0xeb, 0xae, 0x25, 0x40, 0xe6, 0x22, 0xda, 0x19, 0x26, 0x02, 0xa6, 0x08 };
79 
80 static const BYTE bigCertWithDifferentSubject[] = { 0x30, 0x7a, 0x02, 0x01, 0x02,
81  0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
82  0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67,
83  0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31,
84  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
85  0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15,
86  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c,
87  0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06,
88  0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
89  0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
90  0x01, 0x01 };
91 static const BYTE bigCertWithDifferentIssuer[] = { 0x30, 0x7a, 0x02, 0x01,
92  0x01, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
93  0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
94  0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
95  0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
96  0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
97  0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
98  0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
99  0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
100  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
101  0x02, 0x01, 0x01 };
102 
103 static BYTE subjectName2[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
104  0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61,
105  0x6e, 0x67, 0x00 };
106 static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
107  0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
108  0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
109  0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
110  0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
111  0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
112  0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20,
113  0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
114  0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
115  0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
116 static const BYTE bigCert2WithDifferentSerial[] = { 0x30, 0x7a, 0x02, 0x01,
117  0x02, 0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
118  0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e,
119  0x67, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
120  0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30,
121  0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
122  0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41,
123  0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02,
124  0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03,
125  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
126  0x02, 0x01, 0x01 };
127 static BYTE bigCert2Hash[] = { 0x4a, 0x7f, 0x32, 0x1f, 0xcf, 0x3b, 0xc0,
128  0x87, 0x48, 0x2b, 0xa1, 0x86, 0x54, 0x18, 0xe4, 0x3a, 0x0e, 0x53, 0x7e, 0x2b };
129 
130 static const BYTE certWithUsage[] = { 0x30, 0x81, 0x93, 0x02, 0x01, 0x01, 0x30,
131  0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
132  0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00,
133  0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
134  0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
135  0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31,
136  0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61,
137  0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00,
138  0x03, 0x01, 0x00, 0xa3, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x1d,
139  0x25, 0x01, 0x01, 0xff, 0x04, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01,
140  0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
141  0x03, 0x02, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
142 
143 static void testAddCert(void)
144 {
145  HCERTSTORE store;
148  PCCERT_CONTEXT copyContext;
149  BOOL ret;
150 
153  ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
154  if (!store)
155  return;
156 
157  /* Weird--bad add disposition leads to an access violation in Windows.
158  * Both tests crash on some win9x boxes.
159  */
160  if (0)
161  {
163  sizeof(bigCert), 0, NULL);
166  "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n",
167  GetLastError());
169  bigCert, sizeof(bigCert), 0, NULL);
172  "Expected STATUS_ACCESS_VIOLATION or E_INVALIDARG, got %08x\n",
173  GetLastError());
174  }
175 
176  /* Weird--can add a cert to the NULL store (does this have special
177  * meaning?)
178  */
179  context = NULL;
182  ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win98 */),
183  "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
184  if (context)
186  if (!ret && GetLastError() == OSS_DATA_ERROR)
187  {
188  skip("bigCert can't be decoded, skipping tests\n");
189  return;
190  }
191 
194  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
195  GetLastError());
198  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
199  GetLastError());
200  /* This has the same name as bigCert, so finding isn't done by name */
203  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
204  GetLastError());
205  ok(context != NULL, "Expected a context\n");
206  if (context)
207  {
209 
210  /* Duplicate (AddRef) the context so we can still use it after
211  * deleting it from the store.
212  */
215  /* Set the same hash as bigCert2, and try to readd it */
217  0, &hash);
218  ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
219  GetLastError());
222  /* The failure is a bit odd (CRYPT_E_ASN1_BADTAG), so just check
223  * that it fails.
224  */
225  ok(!ret, "Expected failure\n");
227  }
229  sizeof(bigCert2));
230  ok(context != NULL, "Expected a context\n");
231  if (context)
232  {
233  /* Try to readd bigCert2 to the store */
237  "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
239  }
240 
241  /* Adding a cert with the same issuer name and serial number (but
242  * different subject) as an existing cert succeeds.
243  */
244  context = NULL;
248  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
249  GetLastError());
250  if (context)
252 
253  /* Adding a cert with the same subject name and serial number (but
254  * different issuer) as an existing cert succeeds.
255  */
256  context = NULL;
260  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
261  GetLastError());
262  if (context)
264 
265  /* Adding a cert with the same issuer name and serial number (but
266  * different otherwise) as an existing cert succeeds.
267  */
268  context = NULL;
272  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
273  GetLastError());
274  if (context)
276 
279  ok(collection != NULL, "CertOpenStore failed: %08x\n", GetLastError());
280  if (collection)
281  {
282  /* Add store to the collection, but disable updates */
283  CertAddStoreToCollection(collection, store, 0, 0);
284 
286  sizeof(bigCert2));
287  ok(context != NULL, "Expected a context\n");
288  if (context)
289  {
290  /* Try to readd bigCert2 to the collection */
294  "Expected CRYPT_E_EXISTS, got %08x\n", GetLastError());
295  /* Replacing an existing certificate context is allowed, even
296  * though updates to the collection aren't..
297  */
300  ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
301  GetLastError());
302  /* use the existing certificate and ask for a copy of the context*/
303  copyContext = NULL;
305  CERT_STORE_ADD_USE_EXISTING, &copyContext);
306  ok(ret, "CertAddCertificateContextToStore failed: %08x\n",
307  GetLastError());
308  ok(copyContext != NULL, "Expected on output a non NULL copyContext\n");
309  if (copyContext)
310  CertFreeCertificateContext(copyContext);
311  /* but adding a new certificate isn't allowed. */
315  "Expected E_ACCESSDENIED, got %08x\n", GetLastError());
317  }
318 
320  }
321 
322  CertCloseStore(store, 0);
323 }
324 
325 static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
326  PCCERT_CONTEXT context, DWORD propID)
327 {
328  BYTE hash[20] = { 0 }, hashProperty[20];
329  BOOL ret;
330  DWORD size;
331  DWORD dwSizeWithNull;
332 
333  memset(hash, 0, sizeof(hash));
334  memset(hashProperty, 0, sizeof(hashProperty));
335  size = sizeof(hash);
336  ret = CryptHashCertificate(0, algID, 0, data, dataLen, hash, &size);
337  ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
339  &dwSizeWithNull);
340  ok(ret, "algID %08x, propID %d: CertGetCertificateContextProperty failed: %08x\n",
341  algID, propID, GetLastError());
342  ret = CertGetCertificateContextProperty(context, propID, hashProperty,
343  &size);
344  ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
345  GetLastError());
346  ok(!memcmp(hash, hashProperty, size), "Unexpected hash for property %d\n",
347  propID);
348  ok(size == dwSizeWithNull, "Unexpected length of hash for property: received %d instead of %d\n",
349  dwSizeWithNull,size);
350 }
351 
352 static const CHAR cspNameA[] = "WineCryptTemp";
353 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e','m','p',0 };
354 static const BYTE v1CertWithPubKey[] = {
355 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
356 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
357 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
358 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
359 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
360 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
361 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
362 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
363 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
364 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
365 0x01,0x01 };
366 static const BYTE v1CertWithSubjectKeyId[] = {
367 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
368 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
369 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
370 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
371 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
372 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
373 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
374 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
375 0x4c,0x61,0x6e,0x67,0x00 };
376 static const BYTE subjectKeyId[] = {
377 0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
378 static const BYTE selfSignedCert[] = {
379  0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
380  0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
381  0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
382  0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
383  0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
384  0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
385  0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
386  0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
387  0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
388  0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
389  0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
390  0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
391  0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
392  0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
393  0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
394  0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
395  0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
396  0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
397  0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
398  0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
399  0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
400  0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
401  0xa8, 0x76, 0x57, 0x92, 0x36 };
402 static const BYTE selfSignedSignatureHash[] = { 0x07,0x5a,0x3e,0xfd,0x0d,0xf6,
403  0x88,0xeb,0x00,0x64,0xbd,0xc9,0xd6,0xea,0x0a,0x7c,0xcc,0x24,0xdb,0x5d };
404 
405 static void testCertProperties(void)
406 {
408  bigCert, sizeof(bigCert));
409  DWORD propID, numProps, access, size;
410  BOOL ret;
411  BYTE hash[20] = { 0 }, hashProperty[20];
413  CERT_KEY_CONTEXT keyContext;
414 
415  ok(context != NULL || broken(GetLastError() == OSS_DATA_ERROR /* win98 */),
416  "CertCreateCertificateContext failed: %08x\n", GetLastError());
417  if (!context)
418  return;
419 
420  /* This crashes
421  propID = CertEnumCertificateContextProperties(NULL, 0);
422  */
423 
424  propID = 0;
425  numProps = 0;
426  do {
428  if (propID)
429  numProps++;
430  } while (propID != 0);
431  ok(numProps == 0, "Expected 0 properties, got %d\n", numProps);
432 
433  /* Tests with a NULL cert context. Prop ID 0 fails.. */
435  ok(!ret && GetLastError() == E_INVALIDARG,
436  "Expected E_INVALIDARG, got %08x\n", GetLastError());
437  /* while this just crashes.
438  ret = CertSetCertificateContextProperty(NULL,
439  CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL);
440  */
441 
443  ok(!ret && GetLastError() == E_INVALIDARG,
444  "Expected E_INVALIDARG, got %08x\n", GetLastError());
445  /* Can't set the cert property directly, this crashes.
446  ret = CertSetCertificateContextProperty(context,
447  CERT_CERT_PROP_ID, 0, bigCert2);
448  */
449 
450  /* These all crash.
451  ret = CertGetCertificateContextProperty(context,
452  CERT_ACCESS_STATE_PROP_ID, 0, NULL);
453  ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
454  NULL, NULL);
455  ret = CertGetCertificateContextProperty(context, CERT_HASH_PROP_ID,
456  hashProperty, NULL);
457  */
458  /* A missing prop */
459  size = 0;
463  "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
464  /* And, an implicit property */
465  size = sizeof(access);
468  ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
469  GetLastError());
471  "Didn't expect a persisted cert\n");
472  /* Trying to set this "read only" property crashes.
473  access |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
474  ret = CertSetCertificateContextProperty(context,
475  CERT_ACCESS_STATE_PROP_ID, 0, &access);
476  */
477 
478  /* Can I set the hash to an invalid hash? */
479  blob.pbData = hash;
480  blob.cbData = sizeof(hash);
482  &blob);
483  ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
484  GetLastError());
485  size = sizeof(hashProperty);
487  hashProperty, &size);
488  ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
489  GetLastError());
490  ok(!memcmp(hashProperty, hash, sizeof(hash)), "Unexpected hash\n");
491  /* Delete the (bogus) hash, and get the real one */
493  NULL);
494  ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
495  GetLastError());
498 
499  /* Now that the hash property is set, we should get one property when
500  * enumerating.
501  */
502  propID = 0;
503  numProps = 0;
504  do {
506  if (propID)
507  numProps++;
508  } while (propID != 0);
509  ok(numProps == 1, "Expected 1 properties, got %d\n", numProps);
510 
511  /* Check a few other implicit properties */
514 
515  /* Getting the signature hash fails with this bogus certificate */
516  size = 0;
519  ok(!ret &&
522  GetLastError() == OSS_DATA_ERROR), /* win9x */
523  "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
524 
525  /* Test key contexts and handles and such */
526  size = 0;
528  NULL, &size);
530  "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
531  size = sizeof(CERT_KEY_CONTEXT);
533  NULL, &size);
535  "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
537  &keyContext, &size);
539  "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
540  /* Key context with an invalid size */
541  keyContext.cbSize = 0;
543  0, &keyContext);
544  ok(!ret && GetLastError() == E_INVALIDARG,
545  "Expected E_INVALIDARG, got %08x\n", GetLastError());
546  size = sizeof(keyContext);
548  &keyContext, &size);
550  "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
551  keyContext.cbSize = sizeof(keyContext);
552  keyContext.hCryptProv = 0;
553  keyContext.dwKeySpec = AT_SIGNATURE;
555  0, &keyContext);
556  ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
557  /* Now that that's set, the key prov handle property is also gettable.
558  */
559  size = sizeof(keyContext.hCryptProv);
562  ok(ret, "Expected to get the CERT_KEY_PROV_HANDLE_PROP_ID, got %08x\n",
563  GetLastError());
564  /* Remove the key prov handle property.. */
567  ok(ret, "CertSetCertificateContextProperty failed: %08x\n",
568  GetLastError());
569  /* and the key context's CSP is set to NULL. */
570  size = sizeof(keyContext);
572  CERT_KEY_CONTEXT_PROP_ID, &keyContext, &size);
573  ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
574  GetLastError());
575  ok(keyContext.hCryptProv == 0, "Expected no hCryptProv\n");
576 
577  /* According to MSDN the subject key id can be stored as a property,
578  * as a subject key extension, or as the SHA1 hash of the public key,
579  * but this cert has none of them:
580  */
584  "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
586  /* This cert does have a public key, but its subject key identifier still
587  * isn't available: */
593  "Expected ERROR_INVALID_DATA, got %08x\n", GetLastError());
595  /* This cert with a subject key extension can have its key identifier
596  * property retrieved:
597  */
602  ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
603  if (ret)
604  {
606 
607  if (buf)
608  {
611  ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
612  GetLastError());
613  ok(!memcmp(buf, subjectKeyId, size), "Unexpected subject key id\n");
614  HeapFree(GetProcessHeap(), 0, buf);
615  }
616  }
618 
620  selfSignedCert, sizeof(selfSignedCert));
621  /* Getting the signature hash of a valid (self-signed) cert succeeds */
622  size = 0;
625  ok(ret, "CertGetCertificateContextProperty failed: %08x\n", GetLastError());
626  ok(size == sizeof(selfSignedSignatureHash), "unexpected size %d\n", size);
628  CERT_SIGNATURE_HASH_PROP_ID, hashProperty, &size);
629  if (ret)
630  ok(!memcmp(hashProperty, selfSignedSignatureHash, size),
631  "unexpected value\n");
633 }
634 
635 static void testCreateCert(void)
636 {
637  PCCERT_CONTEXT cert, enumCert;
638  DWORD count, size;
639  BOOL ret;
640 
641  SetLastError(0xdeadbeef);
643  ok(!cert && GetLastError() == E_INVALIDARG,
644  "expected E_INVALIDARG, got %08x\n", GetLastError());
645  SetLastError(0xdeadbeef);
647  sizeof(selfSignedCert));
648  ok(!cert && GetLastError() == E_INVALIDARG,
649  "expected E_INVALIDARG, got %08x\n", GetLastError());
650  SetLastError(0xdeadbeef);
652  ok(!cert &&
654  broken(GetLastError() == OSS_MORE_INPUT /* NT4 */)),
655  "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
656 
658  selfSignedCert, sizeof(selfSignedCert));
659  ok(cert != NULL, "creating cert failed: %08x\n", GetLastError());
660  /* Even in-memory certs are expected to have a store associated with them */
661  ok(cert->hCertStore != NULL, "expected created cert to have a store\n");
662  /* The cert doesn't have the archived property set (which would imply it
663  * doesn't show up in enumerations.)
664  */
665  size = 0;
667  NULL, &size);
669  "expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
670  /* Strangely, enumerating the certs in the store finds none. */
671  enumCert = NULL;
672  count = 0;
673  while ((enumCert = CertEnumCertificatesInStore(cert->hCertStore, enumCert)))
674  count++;
675  ok(!count, "expected 0, got %d\n", count);
677 }
678 
679 static void testDupCert(void)
680 {
681  PCCERT_CONTEXT context, dupContext, storeContext, storeContext2, context2;
682  HCERTSTORE store, store2;
683  BOOL ret;
684 
687  ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
688  if (!store)
689  return;
690 
693  ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win98 */),
694  "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
695  if (!ret && GetLastError() == OSS_DATA_ERROR)
696  {
697  skip("bigCert can't be decoded, skipping tests\n");
698  return;
699  }
700  ok(context != NULL, "Expected a valid cert context\n");
701  if (context)
702  {
703  ok(context->cbCertEncoded == sizeof(bigCert),
704  "Wrong cert size %d\n", context->cbCertEncoded);
705  ok(!memcmp(context->pbCertEncoded, bigCert, sizeof(bigCert)),
706  "Unexpected encoded cert in context\n");
707  ok(context->hCertStore == store, "Unexpected store\n");
708 
710  ok(dupContext != NULL, "Expected valid duplicate\n");
711  /* Not only is it a duplicate, it's identical: the address is the
712  * same.
713  */
714  ok(dupContext == context, "Expected identical context addresses\n");
715  CertFreeCertificateContext(dupContext);
717  }
718  CertCloseStore(store, 0);
719 
721  ok(context != NULL, "CertCreateCertificateContext failed\n");
722 
724  ok(dupContext == context, "context != dupContext\n");
725 
726  ret = CertFreeCertificateContext(dupContext);
727  ok(ret, "CertFreeCertificateContext failed\n");
728 
730  ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
731 
733  ok(ret, "CertAddCertificateContextToStore failed\n");
734  ok(storeContext != NULL && storeContext != context, "unexpected storeContext\n");
735  ok(storeContext->hCertStore == store, "unexpected hCertStore\n");
736 
737  ok(storeContext->pbCertEncoded != context->pbCertEncoded, "unexpected pbCertEncoded\n");
738  ok(storeContext->cbCertEncoded == context->cbCertEncoded, "unexpected cbCertEncoded\n");
739  ok(storeContext->pCertInfo != context->pCertInfo, "unexpected pCertInfo\n");
740 
742  ok(store2 != NULL, "CertOpenStore failed: %d\n", GetLastError());
743 
744  ret = CertAddCertificateContextToStore(store2, storeContext, CERT_STORE_ADD_NEW, &storeContext2);
745  ok(ret, "CertAddCertificateContextToStore failed\n");
746  ok(storeContext2 != NULL && storeContext2 != storeContext, "unexpected storeContext\n");
747  ok(storeContext2->hCertStore == store2, "unexpected hCertStore\n");
748 
749  ok(storeContext2->pbCertEncoded != storeContext->pbCertEncoded, "unexpected pbCertEncoded\n");
750  ok(storeContext2->cbCertEncoded == storeContext->cbCertEncoded, "unexpected cbCertEncoded\n");
751  ok(storeContext2->pCertInfo != storeContext->pCertInfo, "unexpected pCertInfo\n");
752 
753  CertFreeCertificateContext(storeContext2);
754  CertFreeCertificateContext(storeContext);
755 
757  ok(context2 != NULL, "CertCreateCertificateContext failed\n");
758 
759  ok(context2->hCertStore == context->hCertStore, "Unexpected hCertStore\n");
760 
761  CertFreeCertificateContext(context2);
763  ok(ret, "CertFreeCertificateContext failed\n");
764 
765  CertCloseStore(store, 0);
766  CertCloseStore(store2, 0);
767 
768  SetLastError(0xdeadbeef);
770  ok(context == NULL, "Expected context to be NULL\n");
771 
773  ok(ret, "CertFreeCertificateContext failed\n");
774 }
775 
776 static void testLinkCert(void)
777 {
778  const CERT_CONTEXT *context, *link;
779  HCERTSTORE store;
780  BOOL ret;
781 
783  ok(context != NULL, "CertCreateCertificateContext failed\n");
784 
786  ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
787 
789  ok(ret, "CertAddCertificateContextToStore failed\n");
790  ok(link != NULL && link != context, "unexpected storeContext\n");
791  ok(link->hCertStore == store, "unexpected hCertStore\n");
792 
793  ok(link->pbCertEncoded == context->pbCertEncoded, "unexpected pbCertEncoded\n");
794  ok(link->cbCertEncoded == context->cbCertEncoded, "unexpected cbCertEncoded\n");
795  ok(link->pCertInfo == context->pCertInfo, "unexpected pCertInfo\n");
796 
799  CertCloseStore(store, 0);
800 }
801 
802 static BYTE subjectName3[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
803  0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x52, 0x6f, 0x62, 0x20, 0x20, 0x4c, 0x61,
804  0x6e, 0x67, 0x00 };
805 static const BYTE iTunesCert0[] = {
806 0x30,0x82,0x03,0xc4,0x30,0x82,0x03,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
807 0x47,0xbf,0x19,0x95,0xdf,0x8d,0x52,0x46,0x43,0xf7,0xdb,0x6d,0x48,0x0d,0x31,
808 0xa4,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
809 0x00,0x30,0x81,0x8b,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
810 0x5a,0x41,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0c,0x57,0x65,
811 0x73,0x74,0x65,0x72,0x6e,0x20,0x43,0x61,0x70,0x65,0x31,0x14,0x30,0x12,0x06,
812 0x03,0x55,0x04,0x07,0x13,0x0b,0x44,0x75,0x72,0x62,0x61,0x6e,0x76,0x69,0x6c,
813 0x6c,0x65,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x0a,0x13,0x06,0x54,0x68,
814 0x61,0x77,0x74,0x65,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14,
815 0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,
816 0x61,0x74,0x69,0x6f,0x6e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13,
817 0x16,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
818 0x6d,0x70,0x69,0x6e,0x67,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x33,0x31,
819 0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x33,0x31,
820 0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x53,0x31,0x0b,0x30,
821 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,
822 0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
823 0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,
824 0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,0x6d,0x65,0x20,
825 0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,0x76,0x69,0x63,
826 0x65,0x73,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,
827 0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,
828 0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa9,0xca,0xb2,0xa4,0xcc,0xcd,0x20,
829 0xaf,0x0a,0x7d,0x89,0xac,0x87,0x75,0xf0,0xb4,0x4e,0xf1,0xdf,0xc1,0x0f,0xbf,
830 0x67,0x61,0xbd,0xa3,0x64,0x1c,0xda,0xbb,0xf9,0xca,0x33,0xab,0x84,0x30,0x89,
831 0x58,0x7e,0x8c,0xdb,0x6b,0xdd,0x36,0x9e,0x0f,0xbf,0xd1,0xec,0x78,0xf2,0x77,
832 0xa6,0x7e,0x6f,0x3c,0xbf,0x93,0xaf,0x0d,0xba,0x68,0xf4,0x6c,0x94,0xca,0xbd,
833 0x52,0x2d,0xab,0x48,0x3d,0xf5,0xb6,0xd5,0x5d,0x5f,0x1b,0x02,0x9f,0xfa,0x2f,
834 0x6b,0x1e,0xa4,0xf7,0xa3,0x9a,0xa6,0x1a,0xc8,0x02,0xe1,0x7f,0x4c,0x52,0xe3,
835 0x0e,0x60,0xec,0x40,0x1c,0x7e,0xb9,0x0d,0xde,0x3f,0xc7,0xb4,0xdf,0x87,0xbd,
836 0x5f,0x7a,0x6a,0x31,0x2e,0x03,0x99,0x81,0x13,0xa8,0x47,0x20,0xce,0x31,0x73,
837 0x0d,0x57,0x2d,0xcd,0x78,0x34,0x33,0x95,0x12,0x99,0x12,0xb9,0xde,0x68,0x2f,
838 0xaa,0xe6,0xe3,0xc2,0x8a,0x8c,0x2a,0xc3,0x8b,0x21,0x87,0x66,0xbd,0x83,0x58,
839 0x57,0x6f,0x75,0xbf,0x3c,0xaa,0x26,0x87,0x5d,0xca,0x10,0x15,0x3c,0x9f,0x84,
840 0xea,0x54,0xc1,0x0a,0x6e,0xc4,0xfe,0xc5,0x4a,0xdd,0xb9,0x07,0x11,0x97,0x22,
841 0x7c,0xdb,0x3e,0x27,0xd1,0x1e,0x78,0xec,0x9f,0x31,0xc9,0xf1,0xe6,0x22,0x19,
842 0xdb,0xc4,0xb3,0x47,0x43,0x9a,0x1a,0x5f,0xa0,0x1e,0x90,0xe4,0x5e,0xf5,0xee,
843 0x7c,0xf1,0x7d,0xab,0x62,0x01,0x8f,0xf5,0x4d,0x0b,0xde,0xd0,0x22,0x56,0xa8,
844 0x95,0xcd,0xae,0x88,0x76,0xae,0xee,0xba,0x0d,0xf3,0xe4,0x4d,0xd9,0xa0,0xfb,
845 0x68,0xa0,0xae,0x14,0x3b,0xb3,0x87,0xc1,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,
846 0x81,0xdb,0x30,0x81,0xd8,0x30,0x34,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
847 0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
848 0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,
849 0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,
850 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
851 0xff,0x02,0x01,0x00,0x30,0x41,0x06,0x03,0x55,0x1d,0x1f,0x04,0x3a,0x30,0x38,
852 0x30,0x36,0xa0,0x34,0xa0,0x32,0x86,0x30,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
853 0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,
854 0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
855 0x6d,0x70,0x69,0x6e,0x67,0x43,0x41,0x2e,0x63,0x72,0x6c,0x30,0x13,0x06,0x03,
856 0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,
857 0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,
858 0x02,0x01,0x06,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,0x04,0x1d,0x30,0x1b,0xa4,
859 0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0c,0x54,
860 0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,0x33,0x30,0x0d,0x06,0x09,
861 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,
862 0x4a,0x6b,0xf9,0xea,0x58,0xc2,0x44,0x1c,0x31,0x89,0x79,0x99,0x2b,0x96,0xbf,
863 0x82,0xac,0x01,0xd6,0x1c,0x4c,0xcd,0xb0,0x8a,0x58,0x6e,0xdf,0x08,0x29,0xa3,
864 0x5e,0xc8,0xca,0x93,0x13,0xe7,0x04,0x52,0x0d,0xef,0x47,0x27,0x2f,0x00,0x38,
865 0xb0,0xe4,0xc9,0x93,0x4e,0x9a,0xd4,0x22,0x62,0x15,0xf7,0x3f,0x37,0x21,0x4f,
866 0x70,0x31,0x80,0xf1,0x8b,0x38,0x87,0xb3,0xe8,0xe8,0x97,0x00,0xfe,0xcf,0x55,
867 0x96,0x4e,0x24,0xd2,0xa9,0x27,0x4e,0x7a,0xae,0xb7,0x61,0x41,0xf3,0x2a,0xce,
868 0xe7,0xc9,0xd9,0x5e,0xdd,0xbb,0x2b,0x85,0x3e,0xb5,0x9d,0xb5,0xd9,0xe1,0x57,
869 0xff,0xbe,0xb4,0xc5,0x7e,0xf5,0xcf,0x0c,0x9e,0xf0,0x97,0xfe,0x2b,0xd3,0x3b,
870 0x52,0x1b,0x1b,0x38,0x27,0xf7,0x3f,0x4a };
871 static const BYTE iTunesCert1[] = {
872 0x30,0x82,0x03,0xff,0x30,0x82,0x02,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
873 0x0d,0xe9,0x2b,0xf0,0xd4,0xd8,0x29,0x88,0x18,0x32,0x05,0x09,0x5e,0x9a,0x76,
874 0x88,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
875 0x00,0x30,0x53,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
876 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
877 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,
878 0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
879 0x20,0x54,0x69,0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,
880 0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,
881 0x30,0x33,0x31,0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
882 0x30,0x38,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x57,
883 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,
884 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,
885 0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2f,0x30,0x2d,0x06,0x03,0x55,
886 0x04,0x03,0x13,0x26,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,
887 0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,
888 0x76,0x69,0x63,0x65,0x73,0x20,0x53,0x69,0x67,0x6e,0x65,0x72,0x30,0x82,0x01,
889 0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,
890 0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,
891 0xb2,0x50,0x28,0x48,0xdd,0xd3,0x68,0x7a,0x84,0x18,0x44,0x66,0x75,0x5d,0x7e,
892 0xc4,0xb8,0x9f,0x63,0x26,0xff,0x3d,0x43,0x9c,0x7c,0x11,0x38,0x10,0x25,0x55,
893 0x73,0xd9,0x75,0x27,0x69,0xfd,0x4e,0xb9,0x20,0x5c,0xd3,0x0a,0xf9,0xa0,0x1b,
894 0x2a,0xed,0x55,0x56,0x21,0x61,0xd8,0x1e,0xdb,0xe4,0xbc,0x33,0x6b,0xc7,0xef,
895 0xdd,0xa3,0x37,0x65,0x8e,0x1b,0x93,0x0c,0xb6,0x53,0x1e,0x5c,0x7c,0x66,0x35,
896 0x5f,0x05,0x8a,0x45,0xfe,0x76,0x4e,0xdf,0x53,0x80,0xa2,0x81,0x20,0x9d,0xae,
897 0x88,0x5c,0xa2,0x08,0xf7,0xe5,0x30,0xf9,0xee,0x22,0x37,0x4c,0x42,0x0a,0xce,
898 0xdf,0xc6,0x1f,0xc4,0xd6,0x55,0xe9,0x81,0x3f,0xb5,0x52,0xa3,0x2c,0xaa,0x01,
899 0x7a,0xf2,0xa2,0xaa,0x8d,0x35,0xfe,0x9f,0xe6,0x5d,0x6a,0x05,0x9f,0x3d,0x6b,
900 0xe3,0xbf,0x96,0xc0,0xfe,0xcc,0x60,0xf9,0x40,0xe7,0x07,0xa0,0x44,0xeb,0x81,
901 0x51,0x6e,0xa5,0x2a,0xf2,0xb6,0x8a,0x10,0x28,0xed,0x8f,0xdc,0x06,0xa0,0x86,
902 0x50,0x9a,0x7b,0x4a,0x08,0x0d,0x30,0x1d,0xca,0x10,0x9e,0x6b,0xf7,0xe9,0x58,
903 0xae,0x04,0xa9,0x40,0x99,0xb2,0x28,0xe8,0x8f,0x16,0xac,0x3c,0xe3,0x53,0x6f,
904 0x4b,0xd3,0x35,0x9d,0xb5,0x6f,0x64,0x1d,0xb3,0x96,0x2c,0xbb,0x3d,0xe7,0x79,
905 0xeb,0x6d,0x7a,0xf9,0x16,0xe6,0x26,0xad,0xaf,0xef,0x99,0x53,0xb7,0x40,0x2c,
906 0x95,0xb8,0x79,0xaa,0xfe,0xd4,0x52,0xab,0x29,0x74,0x7e,0x42,0xec,0x39,0x1e,
907 0xa2,0x6a,0x16,0xe6,0x59,0xbb,0x24,0x68,0xd8,0x00,0x80,0x43,0x10,0x87,0x80,
908 0x6b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xca,0x30,0x81,0xc7,0x30,0x34,0x06,
909 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,
910 0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,
911 0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
912 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
913 0xff,0x04,0x02,0x30,0x00,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30,
914 0x2a,0x30,0x28,0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,
915 0x2f,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,
916 0x6f,0x6d,0x2f,0x74,0x73,0x73,0x2d,0x63,0x61,0x2e,0x63,0x72,0x6c,0x30,0x16,
917 0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,
918 0x06,0x01,0x05,0x05,0x07,0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
919 0x01,0xff,0x04,0x04,0x03,0x02,0x06,0xc0,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,
920 0x04,0x1d,0x30,0x1b,0xa4,0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,
921 0x04,0x03,0x13,0x0c,0x54,0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,
922 0x34,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
923 0x00,0x03,0x82,0x01,0x01,0x00,0x87,0x78,0x70,0xda,0x4e,0x52,0x01,0x20,0x5b,
924 0xe0,0x79,0xc9,0x82,0x30,0xc4,0xfd,0xb9,0x19,0x96,0xbd,0x91,0x00,0xc3,0xbd,
925 0xcd,0xcd,0xc6,0xf4,0x0e,0xd8,0xff,0xf9,0x4d,0xc0,0x33,0x62,0x30,0x11,0xc5,
926 0xf5,0x74,0x1b,0xd4,0x92,0xde,0x5f,0x9c,0x20,0x13,0xb1,0x7c,0x45,0xbe,0x50,
927 0xcd,0x83,0xe7,0x80,0x17,0x83,0xa7,0x27,0x93,0x67,0x13,0x46,0xfb,0xca,0xb8,
928 0x98,0x41,0x03,0xcc,0x9b,0x51,0x5b,0x05,0x8b,0x7f,0xa8,0x6f,0xf3,0x1b,0x50,
929 0x1b,0x24,0x2e,0xf2,0x69,0x8d,0x6c,0x22,0xf7,0xbb,0xca,0x16,0x95,0xed,0x0c,
930 0x74,0xc0,0x68,0x77,0xd9,0xeb,0x99,0x62,0x87,0xc1,0x73,0x90,0xf8,0x89,0x74,
931 0x7a,0x23,0xab,0xa3,0x98,0x7b,0x97,0xb1,0xf7,0x8f,0x29,0x71,0x4d,0x2e,0x75,
932 0x1b,0x48,0x41,0xda,0xf0,0xb5,0x0d,0x20,0x54,0xd6,0x77,0xa0,0x97,0x82,0x63,
933 0x69,0xfd,0x09,0xcf,0x8a,0xf0,0x75,0xbb,0x09,0x9b,0xd9,0xf9,0x11,0x55,0x26,
934 0x9a,0x61,0x32,0xbe,0x7a,0x02,0xb0,0x7b,0x86,0xbe,0xa2,0xc3,0x8b,0x22,0x2c,
935 0x78,0xd1,0x35,0x76,0xbc,0x92,0x73,0x5c,0xf9,0xb9,0xe6,0x4c,0x15,0x0a,0x23,
936 0xcc,0xe4,0xd2,0xd4,0x34,0x2e,0x49,0x40,0x15,0x3c,0x0f,0x60,0x7a,0x24,0xc6,
937 0xa5,0x66,0xef,0x96,0xcf,0x70,0xeb,0x3e,0xe7,0xf4,0x0d,0x7e,0xdc,0xd1,0x7c,
938 0xa3,0x76,0x71,0x69,0xc1,0x9c,0x4f,0x47,0x30,0x35,0x21,0xb1,0xa2,0xaf,0x1a,
939 0x62,0x3c,0x2b,0xd9,0x8e,0xaa,0x2a,0x07,0x7b,0xd8,0x18,0xb3,0x5c,0x7b,0xe2,
940 0x9d,0xa5,0x6f,0xfe,0x3c,0x89,0xad };
941 static const BYTE iTunesCert2[] = {
942 0x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
943 0x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75,
944 0xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
945 0x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
946 0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,
947 0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,
948 0x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,
949 0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,
950 0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,
951 0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x34,0x30,
952 0x37,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30,
953 0x37,0x31,0x35,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,
954 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,
955 0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
956 0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b,
957 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,
958 0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,
959 0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,
960 0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,
961 0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,
962 0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,
963 0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,
964 0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,0x53,0x69,
965 0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,0x20,0x43,0x41,0x30,0x82,
966 0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,
967 0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,
968 0x00,0xbe,0xbc,0xee,0xbc,0x7e,0xef,0x83,0xeb,0xe0,0x37,0x4f,0xfb,0x03,0x10,
969 0x38,0xbe,0x08,0xd2,0x8c,0x7d,0x9d,0xfa,0x92,0x7f,0x19,0x0c,0xc2,0x6b,0xee,
970 0x42,0x52,0x8c,0xde,0xd3,0x1c,0x48,0x13,0x25,0xea,0xc1,0x63,0x7a,0xf9,0x51,
971 0x65,0xee,0xd3,0xaa,0x3b,0xf5,0xf0,0x94,0x9c,0x2b,0xfb,0xf2,0x66,0xd4,0x24,
972 0xda,0xf7,0xf5,0x9f,0x6e,0x19,0x39,0x36,0xbc,0xd0,0xa3,0x76,0x08,0x1e,0x22,
973 0x27,0x24,0x6c,0x38,0x91,0x27,0xe2,0x84,0x49,0xae,0x1b,0x8a,0xa1,0xfd,0x25,
974 0x82,0x2c,0x10,0x30,0xe8,0x71,0xab,0x28,0xe8,0x77,0x4a,0x51,0xf1,0xec,0xcd,
975 0xf8,0xf0,0x54,0xd4,0x6f,0xc0,0xe3,0x6d,0x0a,0x8f,0xd9,0xd8,0x64,0x8d,0x63,
976 0xb2,0x2d,0x4e,0x27,0xf6,0x85,0x0e,0xfe,0x6d,0xe3,0x29,0x99,0xe2,0x85,0x47,
977 0x7c,0x2d,0x86,0x7f,0xe8,0x57,0x8f,0xad,0x67,0xc2,0x33,0x32,0x91,0x13,0x20,
978 0xfc,0xa9,0x23,0x14,0x9a,0x6d,0xc2,0x84,0x4b,0x76,0x68,0x04,0xd5,0x71,0x2c,
979 0x5d,0x21,0xfa,0x88,0x0d,0x26,0xfd,0x1f,0x2d,0x91,0x2b,0xe7,0x01,0x55,0x4d,
980 0xf2,0x6d,0x35,0x28,0x82,0xdf,0xd9,0x6b,0x5c,0xb6,0xd6,0xd9,0xaa,0x81,0xfd,
981 0x5f,0xcd,0x83,0xba,0x63,0x9d,0xd0,0x22,0xfc,0xa9,0x3b,0x42,0x69,0xb2,0x8e,
982 0x3a,0xb5,0xbc,0xb4,0x9e,0x0f,0x5e,0xc4,0xea,0x2c,0x82,0x8b,0x28,0xfd,0x53,
983 0x08,0x96,0xdd,0xb5,0x01,0x20,0xd1,0xf9,0xa5,0x18,0xe7,0xc0,0xee,0x51,0x70,
984 0x37,0xe1,0xb6,0x05,0x48,0x52,0x48,0x6f,0x38,0xea,0xc3,0xe8,0x6c,0x7b,0x44,
985 0x84,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xa0,0x30,0x82,0x01,0x9c,
986 0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,
987 0x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,
988 0x3b,0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,
989 0x03,0x30,0x2a,0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,
990 0x16,0x1c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,
991 0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,
992 0x30,0x31,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24,
993 0xa0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,
994 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63,
995 0x61,0x33,0x2e,0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16,
996 0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x08,0x2b,
997 0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,
998 0x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48,
999 0x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x01,0x30,0x29,0x06,
1000 0x03,0x55,0x1d,0x11,0x04,0x22,0x30,0x20,0xa4,0x1e,0x30,0x1c,0x31,0x1a,0x30,
1001 0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x43,0x6c,0x61,0x73,0x73,0x33,0x43,
1002 0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x34,0x33,0x30,0x1d,0x06,0x03,0x55,
1003 0x1d,0x0e,0x04,0x16,0x04,0x14,0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,
1004 0x36,0x7c,0x68,0xcf,0x5b,0x78,0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x81,0x80,0x06,
1005 0x03,0x55,0x1d,0x23,0x04,0x79,0x30,0x77,0xa1,0x63,0xa4,0x61,0x30,0x5f,0x31,
1006 0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,
1007 0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
1008 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,
1009 0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6c,
1010 0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,
1011 0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,
1012 0x72,0x69,0x74,0x79,0x82,0x10,0x70,0xba,0xe4,0x1d,0x10,0xd9,0x29,0x34,0xb6,
1013 0x38,0xca,0x7b,0x03,0xcc,0xba,0xbf,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
1014 0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xae,0x3a,0x17,0xb8,
1015 0x4a,0x7b,0x55,0xfa,0x64,0x55,0xec,0x40,0xa4,0xed,0x49,0x41,0x90,0x99,0x9c,
1016 0x89,0xbc,0xaf,0x2e,0x1d,0xca,0x78,0x23,0xf9,0x1c,0x19,0x0f,0x7f,0xeb,0x68,
1017 0xbc,0x32,0xd9,0x88,0x38,0xde,0xdc,0x3f,0xd3,0x89,0xb4,0x3f,0xb1,0x82,0x96,
1018 0xf1,0xa4,0x5a,0xba,0xed,0x2e,0x26,0xd3,0xde,0x7c,0x01,0x6e,0x00,0x0a,0x00,
1019 0xa4,0x06,0x92,0x11,0x48,0x09,0x40,0xf9,0x1c,0x18,0x79,0x67,0x23,0x24,0xe0,
1020 0xbb,0xd5,0xe1,0x50,0xae,0x1b,0xf5,0x0e,0xdd,0xe0,0x2e,0x81,0xcd,0x80,0xa3,
1021 0x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88,
1022 0x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f,
1023 0x5e,0xf6,0x7a,0xb5 };
1024 static const BYTE iTunesCert3[] = {
1025 0x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1026 0x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6,
1027 0x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
1028 0x00,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
1029 0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,
1030 0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,
1031 0x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,
1032 0x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,
1033 0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x54,0x65,0x72,0x6d,
1034 0x73,0x20,0x6f,0x66,0x20,0x75,0x73,0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,
1035 0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,
1036 0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,0x29,0x30,
1037 0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,0x13,0x25,0x56,0x65,0x72,
1038 0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,
1039 0x6f,0x64,0x65,0x20,0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,
1040 0x34,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x31,0x37,0x30,
1041 0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x38,0x30,0x31,0x32,0x32,0x32,
1042 0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,
1043 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
1044 0x08,0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x12,
1045 0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x43,0x75,0x70,0x65,0x72,0x74,
1046 0x69,0x6e,0x6f,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0a,0x14,0x14,0x41,
1047 0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x2c,0x20,
1048 0x49,0x6e,0x63,0x2e,0x31,0x3e,0x30,0x3c,0x06,0x03,0x55,0x04,0x0b,0x13,0x35,
1049 0x44,0x69,0x67,0x69,0x74,0x61,0x6c,0x20,0x49,0x44,0x20,0x43,0x6c,0x61,0x73,
1050 0x73,0x20,0x33,0x20,0x2d,0x20,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f,0x66,0x74,
1051 0x20,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x56,0x61,0x6c,0x69,0x64,
1052 0x61,0x74,0x69,0x6f,0x6e,0x20,0x76,0x32,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,
1053 0x04,0x03,0x14,0x14,0x41,0x70,0x70,0x6c,0x65,0x20,0x43,0x6f,0x6d,0x70,0x75,
1054 0x74,0x65,0x72,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x30,0x81,0x9f,0x30,0x0d,0x06,
1055 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,
1056 0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xd3,0xab,0x3b,0x7f,0xec,0x48,0x84,
1057 0xce,0xa8,0x1a,0x12,0xf3,0x3c,0x87,0xcb,0x24,0x58,0x96,0x02,0x87,0x66,0x49,
1058 0xeb,0x89,0xee,0x79,0x44,0x70,0x8d,0xe7,0xd4,0x1f,0x30,0x92,0xc0,0x9c,0x35,
1059 0x78,0xc0,0xaf,0x1c,0xb6,0x28,0xd3,0xe0,0xe0,0x9d,0xd3,0x49,0x76,0x73,0x57,
1060 0x19,0x4d,0x8d,0x70,0x85,0x64,0x4d,0x1d,0xc6,0x02,0x3e,0xe5,0x2c,0x66,0x07,
1061 0xd2,0x27,0x4b,0xd6,0xc8,0x3c,0x93,0xb6,0x15,0x0c,0xde,0x5b,0xd7,0x93,0xdd,
1062 0xbe,0x85,0x62,0x34,0x17,0x8a,0x05,0x60,0xf0,0x8a,0x1c,0x5a,0x40,0x21,0x8d,
1063 0x51,0x6c,0xb0,0x62,0xd8,0xb5,0xd4,0xf9,0xb1,0xd0,0x58,0x7a,0x7a,0x82,0x55,
1064 0xb3,0xf9,0x53,0x71,0xde,0xd2,0xc9,0x37,0x8c,0xf6,0x5a,0x1f,0x2d,0xcd,0x7c,
1065 0x67,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30,
1066 0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06,0x03,0x55,
1067 0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x40,0x06,0x03,
1068 0x55,0x1d,0x1f,0x04,0x39,0x30,0x37,0x30,0x35,0xa0,0x33,0xa0,0x31,0x86,0x2f,
1069 0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,
1070 0x34,0x2d,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,
1071 0x63,0x6f,0x6d,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2e,0x63,
1072 0x72,0x6c,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b,0x30,0x39,
1073 0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,0x17,0x03,0x30,0x2a,
1074 0x30,0x28,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x1c,0x68,
1075 0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,
1076 0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x30,0x13,0x06,
1077 0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,
1078 0x07,0x03,0x03,0x30,0x75,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,
1079 0x04,0x69,0x30,0x67,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,
1080 0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,
1081 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x3f,0x06,
1082 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x33,0x68,0x74,0x74,0x70,
1083 0x3a,0x2f,0x2f,0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,
1084 0x61,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,
1085 0x43,0x53,0x43,0x33,0x2d,0x32,0x30,0x30,0x34,0x2d,0x61,0x69,0x61,0x2e,0x63,
1086 0x65,0x72,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
1087 0x08,0xf5,0x51,0xe8,0xfb,0xfe,0x3d,0x3d,0x64,0x36,0x7c,0x68,0xcf,0x5b,0x78,
1088 0xa8,0xdf,0xb9,0xc5,0x37,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,
1089 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x04,0x10,0x30,0x16,0x06,0x0a,0x2b,0x06,
1090 0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x1b,0x04,0x08,0x30,0x06,0x01,0x01,0x00,
1091 0x01,0x01,0xff,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
1092 0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6a,0xa6,0x06,0xd0,0x33,0x18,0x64,
1093 0xe2,0x69,0x82,0xee,0x6e,0x36,0x9e,0x9d,0x9a,0x0e,0x18,0xa8,0xac,0x9d,0x10,
1094 0xed,0x01,0x3c,0xb9,0x61,0x04,0x62,0xf3,0x85,0x8f,0xcc,0x4f,0x2c,0x66,0x35,
1095 0x54,0x25,0x45,0x8d,0x95,0x1c,0xd2,0x33,0xbe,0x2e,0xdd,0x7f,0x74,0xaf,0x03,
1096 0x7b,0x86,0x63,0xb0,0xc9,0xe6,0xbd,0xc7,0x8e,0xde,0x03,0x18,0x98,0x82,0xc3,
1097 0xbb,0xf8,0x15,0x99,0x1a,0xa9,0xdd,0xb9,0x5d,0xb9,0xbd,0x53,0x95,0x25,0x76,
1098 0xfb,0x5c,0x53,0x90,0xea,0x01,0x0a,0xa0,0xb1,0xbf,0x09,0x1b,0x97,0x8f,0x40,
1099 0xfa,0x85,0x12,0x74,0x01,0xdb,0xf6,0xdb,0x09,0xd6,0x5f,0x4f,0xd7,0x17,0xb4,
1100 0xbf,0x9e,0x2f,0x86,0x52,0x5d,0x70,0x24,0x52,0x32,0x1e,0xa5,0x1d,0x39,0x8b,
1101 0x66,0xf6,0xba,0x9b,0x69,0x8e,0x12,0x60,0xdb,0xb6,0xcf,0xe6,0x0d,0xd6,0x1c,
1102 0x8f,0xd4,0x5b,0x4b,0x00,0xde,0x21,0x93,0xfb,0x6e,0xc7,0x3d,0xb4,0x66,0x0d,
1103 0x29,0x0c,0x4e,0xe9,0x3f,0x94,0xd6,0xd6,0xdc,0xec,0xf8,0x53,0x3b,0x62,0xd5,
1104 0x97,0x50,0x53,0x84,0x17,0xfe,0xe2,0xed,0x4c,0x23,0x0a,0x49,0xce,0x5b,0xe9,
1105 0x70,0x31,0xc1,0x04,0x02,0x02,0x6c,0xb8,0x52,0xcd,0xc7,0x4e,0x70,0xb4,0x13,
1106 0xd7,0xe0,0x92,0xba,0x44,0x1a,0x10,0x4c,0x6e,0x45,0xc6,0x86,0x04,0xc6,0x64,
1107 0xd3,0x9c,0x6e,0xc1,0x9c,0xac,0x74,0x3d,0x77,0x06,0x5e,0x28,0x28,0x5c,0xf5,
1108 0xe0,0x9c,0x19,0xd8,0xba,0x74,0x81,0x2d,0x67,0x77,0x93,0x8d,0xbf,0xd2,0x52,
1109 0x00,0xe6,0xa5,0x38,0x4e,0x2e,0x73,0x66,0x7a };
1110 static BYTE iTunesIssuer[] = {
1111 0x30,0x81,0xb4,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,
1112 0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,
1113 0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,
1114 0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,
1115 0x04,0x0b,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,
1116 0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65,0x74,0x77,0x6f,
1117 0x72,0x6b,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,
1118 0x32,0x54,0x65,0x72,0x6d,0x73,0x20,0x6f,0x66,0x20,0x75,0x73,
1119 0x65,0x20,0x61,0x74,0x20,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,
1120 0x2f,0x77,0x77,0x77,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,
1121 0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x72,0x70,0x61,0x20,0x28,0x63,
1122 0x29,0x30,0x34,0x31,0x2e,0x30,0x2c,0x06,0x03,0x55,0x04,0x03,
1123 0x13,0x25,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
1124 0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x43,0x6f,0x64,0x65,0x20,
1125 0x53,0x69,0x67,0x6e,0x69,0x6e,0x67,0x20,0x32,0x30,0x30,0x34,
1126 0x20,0x43,0x41 };
1127 static BYTE iTunesSerialNum[] = {
1128 0x8d,0xf6,0x6a,0xdf,0xd2,0x40,0xfe,0xb6,0xa6,0x61,0x9b,0x9b,
1129 0xe0,0xa0,0x1a,0x0f };
1130 
1131 static void testFindCert(void)
1132 {
1133  HCERTSTORE store;
1134  PCCERT_CONTEXT context = NULL, subject;
1135  BOOL ret;
1136  CERT_INFO certInfo = { 0 };
1138  BYTE otherSerialNumber[] = { 2 };
1139  DWORD count;
1140  static const WCHAR juan[] = { 'j','u','a','n',0 };
1141  static const WCHAR lang[] = { 'L','A','N','G',0 };
1142  static const WCHAR malcolm[] = { 'm','a','l','c','o','l','m',0 };
1143 
1144  store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1146  ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1147  if (!store)
1148  return;
1149 
1151  bigCert, sizeof(bigCert), CERT_STORE_ADD_NEW, NULL);
1152  ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win98 */),
1153  "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1154  if (!ret && GetLastError() == OSS_DATA_ERROR)
1155  {
1156  skip("bigCert can't be decoded, skipping tests\n");
1157  return;
1158  }
1161  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1162  GetLastError());
1163  /* This has the same name as bigCert */
1166  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1167  GetLastError());
1168 
1169  /* Crashes
1170  context = CertFindCertificateInStore(NULL, 0, 0, 0, NULL, NULL);
1171  */
1172 
1173  /* Check first cert's there, by issuer */
1174  certInfo.Subject.pbData = subjectName;
1175  certInfo.Subject.cbData = sizeof(subjectName);
1176  certInfo.SerialNumber.pbData = serialNum;
1177  certInfo.SerialNumber.cbData = sizeof(serialNum);
1179  CERT_FIND_ISSUER_NAME, &certInfo.Subject, NULL);
1180  ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1181  GetLastError());
1182  if (context)
1183  {
1185  CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
1186  ok(context != NULL, "Expected more than one cert\n");
1187  if (context)
1188  {
1190  0, CERT_FIND_ISSUER_NAME, &certInfo.Subject, context);
1191  ok(context == NULL, "Expected precisely two certs\n");
1192  }
1193  }
1194 
1195  /* Check second cert's there as well, by subject name */
1196  certInfo.Subject.pbData = subjectName2;
1197  certInfo.Subject.cbData = sizeof(subjectName2);
1199  CERT_FIND_SUBJECT_NAME, &certInfo.Subject, NULL);
1200  ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1201  GetLastError());
1202  if (context)
1203  {
1205  CERT_FIND_SUBJECT_NAME, &certInfo.Subject, context);
1206  ok(context == NULL, "Expected one cert only\n");
1207  }
1208 
1209  /* Strange but true: searching for the subject cert requires you to set
1210  * the issuer, not the subject
1211  */
1213  CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1214  ok(context == NULL, "Expected no certificate\n");
1215  certInfo.Subject.pbData = NULL;
1216  certInfo.Subject.cbData = 0;
1217  certInfo.Issuer.pbData = subjectName2;
1218  certInfo.Issuer.cbData = sizeof(subjectName2);
1220  CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1221  ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1222  GetLastError());
1223  if (context)
1224  {
1226  CERT_FIND_SUBJECT_CERT, &certInfo, context);
1227  ok(context == NULL, "Expected one cert only\n");
1228  }
1229  /* A non-matching serial number will not match. */
1230  certInfo.SerialNumber.pbData = otherSerialNumber;
1231  certInfo.SerialNumber.cbData = sizeof(otherSerialNumber);
1233  CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1234  ok(context == NULL, "Expected no match\n");
1235  /* No serial number will not match */
1236  certInfo.SerialNumber.cbData = 0;
1238  CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1239  ok(context == NULL, "Expected no match\n");
1240  /* A serial number still won't match if the name doesn't */
1241  certInfo.SerialNumber.pbData = serialNum;
1242  certInfo.SerialNumber.cbData = sizeof(serialNum);
1243  certInfo.Issuer.pbData = subjectName3;
1244  certInfo.Issuer.cbData = sizeof(subjectName3);
1246  CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1247  ok(context == NULL, "Expected no match\n");
1248 
1249  /* The nice thing about hashes, they're unique */
1250  blob.pbData = bigCertHash;
1251  blob.cbData = sizeof(bigCertHash);
1254  ok(context != NULL, "CertFindCertificateInStore failed: %08x\n",
1255  GetLastError());
1256  if (context)
1257  {
1259  CERT_FIND_SHA1_HASH, &certInfo.Subject, context);
1260  ok(context == NULL, "Expected one cert only\n");
1261  }
1262 
1263  /* Searching for NULL string matches any context. */
1264  count = 0;
1265  context = NULL;
1266  do {
1269  if (context)
1270  count++;
1271  } while (context);
1272  ok(count == 3, "expected 3 contexts\n");
1273  count = 0;
1274  context = NULL;
1275  do {
1277  CERT_FIND_ISSUER_STR, juan, context);
1278  if (context)
1279  count++;
1280  } while (context);
1281  ok(count == 2, "expected 2 contexts\n");
1282  count = 0;
1283  context = NULL;
1284  do {
1287  if (context)
1288  count++;
1289  } while (context);
1290  ok(count == 3, "expected 3 contexts\n");
1291  SetLastError(0xdeadbeef);
1293  CERT_FIND_ISSUER_STR, malcolm, NULL);
1294  ok(!context, "expected no certs\n");
1296  "expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1297 
1298  CertCloseStore(store, 0);
1299 
1300  /* Another subject cert search, using iTunes's certs */
1301  store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1305  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1306  GetLastError());
1309  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1310  GetLastError());
1313  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1314  GetLastError());
1316  iTunesCert3, sizeof(iTunesCert3), CERT_STORE_ADD_NEW, &subject);
1317  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1318  GetLastError());
1319 
1320  /* The certInfo's issuer does not match any subject, but the serial
1321  * number does match a cert whose issuer matches certInfo's issuer.
1322  * This yields a match.
1323  */
1324  certInfo.SerialNumber.cbData = sizeof(iTunesSerialNum);
1325  certInfo.SerialNumber.pbData = iTunesSerialNum;
1326  certInfo.Issuer.cbData = sizeof(iTunesIssuer);
1327  certInfo.Issuer.pbData = iTunesIssuer;
1329  CERT_FIND_SUBJECT_CERT, &certInfo, NULL);
1330  ok(context != NULL, "Expected a match\n");
1331  if (context)
1332  {
1333  ret = CertCompareCertificateName(context->dwCertEncodingType,
1334  &certInfo.Issuer, &context->pCertInfo->Subject);
1335  ok(!ret, "Expected subject name not to match\n");
1336  ret = CertCompareCertificateName(context->dwCertEncodingType,
1337  &certInfo.Issuer, &context->pCertInfo->Issuer);
1338  ok(ret, "Expected issuer name to match\n");
1340  &context->pCertInfo->SerialNumber);
1341  ok(ret, "Expected serial number to match\n");
1343  CERT_FIND_SUBJECT_CERT, &certInfo, context);
1344  ok(context == NULL, "Expected one cert only\n");
1345  }
1346 
1348  CERT_FIND_ISSUER_OF, subject, NULL);
1349  ok(context != NULL, "Expected an issuer\n");
1350  if (context)
1351  {
1354 
1355  ok(!none, "Expected no parent of issuer\n");
1357  }
1358  CertFreeCertificateContext(subject);
1359  CertCloseStore(store, 0);
1360 }
1361 
1362 static void testGetSubjectCert(void)
1363 {
1364  HCERTSTORE store;
1365  PCCERT_CONTEXT context1, context2;
1366  CERT_INFO info = { 0 };
1367  BOOL ret;
1368 
1369  store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1371  ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
1372  if (!store)
1373  return;
1374 
1377  ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* win98 */),
1378  "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1379  if (!ret && GetLastError() == OSS_DATA_ERROR)
1380  {
1381  skip("bigCert can't be decoded, skipping tests\n");
1382  return;
1383  }
1385  bigCert2, sizeof(bigCert2), CERT_STORE_ADD_NEW, &context1);
1386  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1387  GetLastError());
1388  ok(context1 != NULL, "Expected a context\n");
1391  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1392  GetLastError());
1393 
1395  NULL);
1396  ok(!context2 && GetLastError() == E_INVALIDARG,
1397  "Expected E_INVALIDARG, got %08x\n", GetLastError());
1399  &info);
1400  ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1401  "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1402  info.SerialNumber.cbData = sizeof(serialNum);
1403  info.SerialNumber.pbData = serialNum;
1405  &info);
1406  ok(!context2 && GetLastError() == CRYPT_E_NOT_FOUND,
1407  "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
1408  info.Issuer.cbData = sizeof(subjectName2);
1409  info.Issuer.pbData = subjectName2;
1411  &info);
1412  ok(context2 != NULL,
1413  "CertGetSubjectCertificateFromStore failed: %08x\n", GetLastError());
1414  /* Not only should this find a context, but it should be the same
1415  * (same address) as context1.
1416  */
1417  ok(context1 == context2, "Expected identical context addresses\n");
1418  CertFreeCertificateContext(context2);
1419 
1420  CertFreeCertificateContext(context1);
1421  CertCloseStore(store, 0);
1422 }
1423 
1424 /* This expires in 1970 or so */
1425 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
1426  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
1427  0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
1428  0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1429  0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1430  0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1431  0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
1432  0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
1433  0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
1434  0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
1435  0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
1436  0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
1437  0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
1438  0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
1439  0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
1440  0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
1441  0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
1442  0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
1443  0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
1444  0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
1445  0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
1446  0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
1447  0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
1448  0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
1449  0x49, 0xe5, 0xf9, 0x65, 0xf3 };
1450 
1451 /* This expires in 2036 or so */
1452 static const BYTE childOfExpired[] = { 0x30, 0x81, 0xcc, 0x30, 0x78, 0xa0,
1453  0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
1454  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d,
1455  0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63,
1456  0x40, 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e,
1457  0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x35, 0x30, 0x35,
1458  0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x30, 0x35,
1459  0x30, 0x35, 0x31, 0x37, 0x31, 0x32, 0x34, 0x39, 0x5a, 0x30, 0x15, 0x31, 0x13,
1460  0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e,
1461  0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03,
1462  0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
1463  0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x20, 0x3b, 0xdb, 0x4d, 0x67, 0x50,
1464  0xec, 0x73, 0x9d, 0xf9, 0x85, 0x5d, 0x18, 0xe9, 0xb4, 0x98, 0xe3, 0x31, 0xb7,
1465  0x03, 0x0b, 0xc0, 0x39, 0x93, 0x56, 0x81, 0x0a, 0xfc, 0x78, 0xa8, 0x29, 0x42,
1466  0x5f, 0x69, 0xfb, 0xbc, 0x5b, 0xf2, 0xa6, 0x2a, 0xbe, 0x91, 0x2c, 0xfc, 0x89,
1467  0x69, 0x15, 0x18, 0x58, 0xe5, 0x02, 0x75, 0xf7, 0x2a, 0xb6, 0xa9, 0xfb, 0x47,
1468  0x6a, 0x6e, 0x0a, 0x9b, 0xe9, 0xdc };
1469 /* chain10_0 -+
1470  * +-> chain7_1
1471  * chain10_1 -+
1472  * A chain with two issuers, only one of whose dates is valid.
1473  */
1474 static const BYTE chain10_0[] = {
1475 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1476 0x4a,0x30,0x3a,0x42,0xa2,0x5a,0xb3,0x93,0x4d,0x94,0x06,0xad,0x6d,0x1c,0x34,
1477 0xe6,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1478 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1479 0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1480 0x30,0x5a,0x17,0x0d,0x30,0x36,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1481 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1482 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1483 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1484 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1485 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1486 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1487 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1488 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1489 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1490 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1491 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1492 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1493 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1494 0x81,0x00,0x85,0x6e,0x35,0x2f,0x2c,0x51,0x4f,0xd6,0x2a,0xe4,0x9e,0xd0,0x4b,
1495 0xe6,0x90,0xfd,0xf7,0x20,0xad,0x76,0x3f,0x93,0xea,0x7f,0x0d,0x1f,0xb3,0x8e,
1496 0xfd,0xe0,0xe1,0xd6,0xd7,0x9c,0x7d,0x46,0x6b,0x15,0x5c,0xe6,0xc9,0x62,0x3b,
1497 0x70,0x4a,0x4b,0xb2,0x82,0xe3,0x55,0x0c,0xc4,0x90,0x44,0x06,0x6c,0x86,0x1c,
1498 0x6d,0x47,0x12,0xda,0x33,0x95,0x5d,0x98,0x43,0xcb,0x7c,0xfa,0x2b,0xee,0xc4,
1499 0x2d,0xc8,0x95,0x33,0x89,0x08,0x3f,0x9f,0x87,0xea,0x20,0x04,0xaf,0x58,0x4b,
1500 0x9d,0xc0,0x7c,0x0a,0x1b,0x05,0x31,0x3b,0xbb,0x13,0x58,0x2e,0x3f,0x61,0x6b,
1501 0x10,0xb4,0xeb,0xb9,0x1a,0x30,0xfd,0xea,0xca,0x29,0x99,0x5f,0x42,0x2b,0x00,
1502 0xb0,0x08,0xc3,0xf0,0xb6,0xd6,0x6b,0xf9,0x35,0x95 };
1503 static const BYTE chain10_1[] = {
1504 0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
1505 0xbf,0x99,0x4f,0x14,0x03,0x77,0x44,0xb8,0x49,0x02,0x70,0xa1,0xb8,0x9c,0xa7,
1506 0x24,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
1507 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
1508 0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
1509 0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
1510 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
1511 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
1512 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
1513 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
1514 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
1515 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
1516 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
1517 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
1518 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
1519 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
1520 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
1521 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
1522 0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,
1523 0x81,0x00,0xa8,0xec,0x8c,0x34,0xe7,0x2c,0xdf,0x75,0x87,0xc4,0xf7,0xda,0x71,
1524 0x72,0x29,0xb2,0x48,0xa8,0x2a,0xec,0x7b,0x7d,0x19,0xb9,0x5f,0x1d,0xd9,0x91,
1525 0x2b,0xc4,0x28,0x7e,0xd6,0xb5,0x91,0x69,0xa5,0x8a,0x1a,0x1f,0x97,0x98,0x46,
1526 0x9d,0xdf,0x12,0xf6,0x45,0x62,0xad,0x60,0xb6,0xba,0xb0,0xfd,0xf5,0x9f,0xc6,
1527 0x98,0x05,0x4f,0x4d,0x48,0xdc,0xee,0x69,0xbe,0xb8,0xc4,0xc4,0xd7,0x1b,0xb1,
1528 0x1f,0x64,0xd6,0x45,0xa7,0xdb,0xb3,0x87,0x63,0x0f,0x54,0xe1,0x3a,0x6b,0x57,
1529 0x36,0xd7,0x68,0x65,0xcf,0xda,0x57,0x8d,0xcd,0x84,0x75,0x47,0x26,0x2c,0xef,
1530 0x1e,0x8f,0xc7,0x3b,0xee,0x5d,0x03,0xa6,0xdf,0x3a,0x20,0xb2,0xcc,0xc9,0x09,
1531 0x2c,0xfe,0x2b,0x79,0xb0,0xca,0x2c,0x9a,0x81,0x6b };
1532 static const BYTE chain7_1[] = {
1533 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
1534 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,
1535 0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,
1536 0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,
1537 0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,
1538 0x35,0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,
1539 0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,
1540 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,
1541 0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,
1542 0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,
1543 0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,
1544 0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,
1545 0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,
1546 0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,
1547 0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,
1548 0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,
1549 0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,
1550 0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
1551 0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9f,0x69,0xfd,0x26,0xd5,0x4b,
1552 0xe0,0xab,0x12,0x21,0xb9,0xfc,0xf7,0xe0,0x0c,0x09,0x94,0xad,0x27,0xd7,0x9d,
1553 0xa3,0xcc,0x46,0x2a,0x25,0x9a,0x24,0xa7,0x31,0x58,0x78,0xf5,0xfc,0x30,0xe1,
1554 0x6d,0xfd,0x59,0xab,0xbe,0x69,0xa0,0xea,0xe3,0x7d,0x7a,0x7b,0xe5,0x85,0xeb,
1555 0x86,0x6a,0x84,0x3c,0x96,0x01,0x1a,0x70,0xa7,0xb8,0xcb,0xf2,0x11,0xe7,0x52,
1556 0x9c,0x58,0x2d,0xac,0x63,0xce,0x72,0x4b,0xad,0x62,0xa8,0x1d,0x75,0x96,0xe2,
1557 0x27,0xf5,0x6f,0xba,0x91,0xf8,0xf1,0xb0,0xbf,0x90,0x24,0x6d,0xba,0x5d,0xd7,
1558 0x39,0x63,0x3b,0x7c,0x04,0x5d,0x89,0x9d,0x1c,0xf2,0xf7,0xcc,0xdf,0x6e,0x8a,
1559 0x43,0xa9,0xdd,0x86,0x05,0xa2,0xf3,0x22,0x2d,0x1e,0x70,0xa1,0x59,0xd7,0xa5,
1560 0x94,0x7d };
1561 
1562 static void testGetIssuerCert(void)
1563 {
1564  BOOL ret;
1566  DWORD flags = 0xffffffff, size;
1567  CERT_NAME_BLOB certsubject;
1568  BYTE *certencoded;
1569  WCHAR rootW[] = {'R', 'O', 'O', 'T', '\0'},
1570  certname[] = {'C', 'N', '=', 'd', 'u', 'm', 'm', 'y', ',', ' ', 'T', '=', 'T', 'e', 's', 't', '\0'};
1573 
1574  ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1575 
1578  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1579  GetLastError());
1580 
1583  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n",
1584  GetLastError());
1585 
1586  /* These crash:
1587  parent = CertGetIssuerCertificateFromStore(NULL, NULL, NULL, NULL);
1588  parent = CertGetIssuerCertificateFromStore(store, NULL, NULL, NULL);
1589  */
1592  "Expected E_INVALIDARG, got %08x\n", GetLastError());
1595  "Expected E_INVALIDARG, got %08x\n", GetLastError());
1598  "Expected E_INVALIDARG, got %08x\n", GetLastError());
1599  /* Confusing: the caller cannot set either of the
1600  * CERT_STORE_NO_*_FLAGs, as these are not checks,
1601  * they're results:
1602  */
1606  "Expected E_INVALIDARG, got %08x\n", GetLastError());
1607  /* Perform no checks */
1608  flags = 0;
1610  ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1611  GetLastError());
1612  if (parent)
1614  /* Check revocation and signature only */
1617  ok(parent != NULL, "CertGetIssuerCertificateFromStore failed: %08x\n",
1618  GetLastError());
1619  /* Confusing: CERT_STORE_REVOCATION_FLAG succeeds when there is no CRL by
1620  * setting CERT_STORE_NO_CRL_FLAG.
1621  */
1623  "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
1624  flags);
1625  if (parent)
1627  /* Checking time validity is not productive, because while most Windows
1628  * versions return 0 (time valid) because the child is not expired,
1629  * Windows 2003 SP1 returns that it is expired. Thus the range of
1630  * possibilities is covered, and a test verifies nothing.
1631  */
1632 
1634  CertCloseStore(store, 0);
1635 
1636  flags = 0;
1637  store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1639  /* With only the child certificate, no issuer will be found */
1642  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1644  ok(parent == NULL, "Expected no issuer\n");
1645  ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError());
1646  /* Adding an issuer allows one (and only one) issuer to be found */
1649  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1651  ok(parent == cert1, "Expected cert1 to be the issuer\n");
1653  ok(parent == NULL, "Expected only one issuer\n");
1654  ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError());
1655  /* Adding a second issuer allows two issuers to be found - and the second
1656  * issuer is found before the first, implying certs are added to the head
1657  * of a list.
1658  */
1661  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1663  ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1665  ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1667  ok(parent == NULL, "Expected no more than two issuers\n");
1668  ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError());
1672  CertCloseStore(store, 0);
1673 
1674  /* Repeat the test, reversing the order in which issuers are added,
1675  * to show it's order-dependent.
1676  */
1677  store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
1679  /* With only the child certificate, no issuer will be found */
1682  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1684  ok(parent == NULL, "Expected no issuer\n");
1685  ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError());
1686  /* Adding an issuer allows one (and only one) issuer to be found */
1689  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1691  ok(parent == cert1, "Expected cert1 to be the issuer\n");
1693  ok(parent == NULL, "Expected only one issuer\n");
1694  ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError());
1695  /* Adding a second issuer allows two issuers to be found - and the second
1696  * issuer is found before the first, implying certs are added to the head
1697  * of a list.
1698  */
1701  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1703  ok(parent == cert2, "Expected cert2 to be the first issuer\n");
1705  ok(parent == cert1, "Expected cert1 to be the second issuer\n");
1707  ok(parent == NULL, "Expected no more than two issuers\n");
1708  ok(GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08X\n", GetLastError());
1709 
1710  /* Self-sign a certificate, add to the store and test getting the issuer */
1711  size = 0;
1713  "CertStrToName should have worked\n");
1714  certencoded = HeapAlloc(GetProcessHeap(), 0, size);
1715  ok(CertStrToNameW(X509_ASN_ENCODING, certname, CERT_X500_NAME_STR, NULL, certencoded, &size, NULL),
1716  "CertStrToName should have worked\n");
1717  certsubject.pbData = certencoded;
1718  certsubject.cbData = size;
1719  cert3 = CertCreateSelfSignCertificate(0, &certsubject, 0, NULL, NULL, NULL, NULL, NULL);
1720  ok(cert3 != NULL, "CertCreateSelfSignCertificate should have worked\n");
1722  ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError());
1724  cert3 = CertEnumCertificatesInStore(store, NULL);
1725  ok(cert3 != NULL, "CertEnumCertificatesInStore should have worked\n");
1726  SetLastError(0xdeadbeef);
1727  flags = 0;
1729  ok(!parent, "Expected NULL\n");
1731  "Expected CRYPT_E_SELF_SIGNED, got %08X\n", GetLastError());
1735  CertCloseStore(store, 0);
1736  HeapFree(GetProcessHeap(), 0, certencoded);
1737 
1738  /* Test root storage self-signed certificate */
1740  ok(store != NULL, "CertOpenStore failed: %08x\n", GetLastError());
1741  flags = 0;
1743  ok(cert1 != NULL, "CertEnumCertificatesInStore should have worked\n");
1744  SetLastError(0xdeadbeef);
1746  ok(!parent, "Expected NULL\n");
1748  "Expected CRYPT_E_SELF_SIGNED, got %08X\n", GetLastError());
1749  CertCloseStore(store, 0);
1750 }
1751 
1752 static void testCryptHashCert(void)
1753 {
1754  static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b,
1755  0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07,
1756  0x09 };
1757  static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee,
1758  0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8,
1759  0xa2 };
1760  static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:";
1761  BOOL ret;
1762  BYTE hash[20];
1763  DWORD hashLen = sizeof(hash);
1764 
1765  /* NULL buffer and nonzero length crashes
1766  ret = CryptHashCertificate(0, 0, 0, NULL, size, hash, &hashLen);
1767  empty hash length also crashes
1768  ret = CryptHashCertificate(0, 0, 0, buf, size, hash, NULL);
1769  */
1770  /* Test empty hash */
1771  ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), NULL,
1772  &hashLen);
1773  ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1774  ok(hashLen == sizeof(hash), "Got unexpected size of hash %d\n", hashLen);
1775  /* Test with empty buffer */
1776  ret = CryptHashCertificate(0, 0, 0, NULL, 0, hash, &hashLen);
1777  ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1778  ok(!memcmp(hash, emptyHash, sizeof(emptyHash)),
1779  "Unexpected hash of nothing\n");
1780  /* Test a known value */
1781  ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), hash,
1782  &hashLen);
1783  ok(ret, "CryptHashCertificate failed: %08x\n", GetLastError());
1784  ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
1785 }
1786 
1787 static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen,
1788  const BYTE *sig, unsigned int sigLen)
1789 {
1790  HCRYPTHASH hash;
1791  BOOL ret = CryptCreateHash(csp, CALG_SHA1, 0, 0, &hash);
1792 
1793  ok(ret, "CryptCreateHash failed: %08x\n", GetLastError());
1794  if (ret)
1795  {
1796  BYTE mySig[64];
1797  DWORD mySigSize = sizeof(mySig);
1798 
1799  ret = CryptHashData(hash, toSign, toSignLen, 0);
1800  ok(ret, "CryptHashData failed: %08x\n", GetLastError());
1801  /* use the A variant so the test can run on Win9x */
1802  ret = CryptSignHashA(hash, AT_SIGNATURE, NULL, 0, mySig, &mySigSize);
1803  ok(ret, "CryptSignHash failed: %08x\n", GetLastError());
1804  if (ret)
1805  {
1806  ok(mySigSize == sigLen, "Expected sig length %d, got %d\n",
1807  sigLen, mySigSize);
1808  ok(!memcmp(mySig, sig, sigLen), "Unexpected signature\n");
1809  }
1811  }
1812 }
1813 
1814 /* Tests signing the certificate described by toBeSigned with the CSP passed in,
1815  * using the algorithm with OID sigOID. The CSP is assumed to be empty, and a
1816  * keyset named AT_SIGNATURE will be added to it. The signature will be stored
1817  * in sig. sigLen should be at least 64 bytes.
1818  */
1819 static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1820  LPCSTR sigOID, BYTE *sig, DWORD *sigLen)
1821 {
1822  BOOL ret;
1823  DWORD size = 0;
1824  CRYPT_ALGORITHM_IDENTIFIER algoID = { NULL, { 0, NULL } };
1825  HCRYPTKEY key;
1826 
1827  /* These all crash
1828  ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1829  ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, &size);
1830  ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1831  NULL, NULL, NULL, &size);
1832  */
1833  ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1834  &algoID, NULL, NULL, &size);
1835  ok(!ret && GetLastError() == NTE_BAD_ALGID,
1836  "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
1837  algoID.pszObjId = (LPSTR)sigOID;
1838  ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
1839  &algoID, NULL, NULL, &size);
1840  ok(!ret &&
1842  "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1843  GetLastError());
1844  ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData,
1845  toBeSigned->cbData, &algoID, NULL, NULL, &size);
1846  ok(!ret &&
1848  "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
1849  GetLastError());
1850 
1851  /* No keys exist in the new CSP yet.. */
1852  ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1853  toBeSigned->cbData, &algoID, NULL, NULL, &size);
1854  ok(!ret && (GetLastError() == NTE_BAD_KEYSET || GetLastError() ==
1855  NTE_NO_KEY), "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %08x\n",
1856  GetLastError());
1857  ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
1858  ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
1859  if (ret)
1860  {
1861  ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1862  toBeSigned->cbData, &algoID, NULL, NULL, &size);
1863  ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1864  ok(size <= *sigLen, "Expected size <= %d, got %d\n", *sigLen, size);
1865  if (ret)
1866  {
1867  ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
1868  toBeSigned->cbData, &algoID, NULL, sig, &size);
1869  ok(ret, "CryptSignCertificate failed: %08x\n", GetLastError());
1870  if (ret)
1871  {
1872  *sigLen = size;
1873  verifySig(csp, toBeSigned->pbData, toBeSigned->cbData, sig,
1874  size);
1875  }
1876  }
1878  }
1879 }
1880 
1881 static void testVerifyCertSig(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1882  LPCSTR sigOID, const BYTE *sig, DWORD sigLen)
1883 {
1885  LPBYTE cert = NULL;
1886  DWORD size = 0;
1887  BOOL ret;
1888 
1889  if (!pCryptEncodeObjectEx)
1890  {
1891  win_skip("no CryptEncodeObjectEx support\n");
1892  return;
1893  }
1896  "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1899  "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
1901  NULL);
1902  ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
1903  GetLastError() == OSS_BAD_ARG),
1904  "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
1905  info.ToBeSigned.cbData = toBeSigned->cbData;
1906  info.ToBeSigned.pbData = toBeSigned->pbData;
1907  info.SignatureAlgorithm.pszObjId = (LPSTR)sigOID;
1908  info.SignatureAlgorithm.Parameters.cbData = 0;
1909  info.Signature.cbData = sigLen;
1910  info.Signature.pbData = (BYTE *)sig;
1911  info.Signature.cUnusedBits = 0;
1912  ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT, &info,
1914  ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1915  if (cert)
1916  {
1917  PCERT_PUBLIC_KEY_INFO pubKeyInfo = NULL;
1918  DWORD pubKeySize;
1919 
1920  if (0)
1921  {
1922  /* Crashes prior to Vista */
1924  cert, size, NULL);
1925  }
1927  (LPSTR)sigOID, 0, NULL, NULL, &pubKeySize);
1928  pubKeyInfo = HeapAlloc(GetProcessHeap(), 0, pubKeySize);
1929  if (pubKeyInfo)
1930  {
1932  X509_ASN_ENCODING, (LPSTR)sigOID, 0, NULL, pubKeyInfo,
1933  &pubKeySize);
1934  ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
1935  if (ret)
1936  {
1938  cert, size, pubKeyInfo);
1939  ok(ret, "CryptVerifyCertificateSignature failed: %08x\n",
1940  GetLastError());
1941  }
1942  HeapFree(GetProcessHeap(), 0, pubKeyInfo);
1943  }
1944  LocalFree(cert);
1945  }
1946 }
1947 
1948 static void testVerifyCertSigEx(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
1949  LPCSTR sigOID, const BYTE *sig, DWORD sigLen)
1950 {
1952  LPBYTE cert = NULL;
1953  DWORD size = 0;
1954  BOOL ret;
1955 
1956  if (!pCryptVerifyCertificateSignatureEx)
1957  {
1958  win_skip("no CryptVerifyCertificateSignatureEx support\n");
1959  return;
1960  }
1961  if (!pCryptEncodeObjectEx)
1962  {
1963  win_skip("no CryptEncodeObjectEx support\n");
1964  return;
1965  }
1966  ret = pCryptVerifyCertificateSignatureEx(0, 0, 0, NULL, 0, NULL, 0, NULL);
1967  ok(!ret && GetLastError() == E_INVALIDARG,
1968  "Expected E_INVALIDARG, got %08x\n", GetLastError());
1969  ret = pCryptVerifyCertificateSignatureEx(csp, 0, 0, NULL, 0, NULL, 0, NULL);
1970  ok(!ret && GetLastError() == E_INVALIDARG,
1971  "Expected E_INVALIDARG, got %08x\n", GetLastError());
1972  ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 0, NULL, 0,
1973  NULL, 0, NULL);
1974  ok(!ret && GetLastError() == E_INVALIDARG,
1975  "Expected E_INVALIDARG, got %08x\n", GetLastError());
1976  /* This crashes
1977  ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1978  CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, NULL, 0, NULL, 0, NULL);
1979  */
1980  info.ToBeSigned.cbData = toBeSigned->cbData;
1981  info.ToBeSigned.pbData = toBeSigned->pbData;
1982  info.SignatureAlgorithm.pszObjId = (LPSTR)sigOID;
1983  info.SignatureAlgorithm.Parameters.cbData = 0;
1984  info.Signature.cbData = sigLen;
1985  info.Signature.pbData = (BYTE *)sig;
1986  info.Signature.cUnusedBits = 0;
1987  ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT, &info,
1989  ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1990  if (cert)
1991  {
1992  CRYPT_DATA_BLOB certBlob = { 0, NULL };
1993  PCERT_PUBLIC_KEY_INFO pubKeyInfo = NULL;
1994 
1995  ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
1996  CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
1998  "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
1999  certBlob.cbData = 1;
2000  certBlob.pbData = (void *)0xdeadbeef;
2001  ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
2002  CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
2004  GetLastError() == CRYPT_E_ASN1_EOD /* Win9x */ ||
2005  GetLastError() == CRYPT_E_ASN1_BADTAG /* Win98 */),
2006  "Expected STATUS_ACCESS_VIOLATION, CRYPT_E_ASN1_EOD, OR CRYPT_E_ASN1_BADTAG, got %08x\n",
2007  GetLastError());
2008 
2009  certBlob.cbData = size;
2010  certBlob.pbData = cert;
2011  ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
2012  CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
2013  ok(!ret && GetLastError() == E_INVALIDARG,
2014  "Expected E_INVALIDARG, got %08x\n", GetLastError());
2015  ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
2018  ok(!ret && GetLastError() == E_INVALIDARG,
2019  "Expected E_INVALIDARG, got %08x\n", GetLastError());
2020  /* This crashes
2021  ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
2022  CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
2023  CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, NULL, 0, NULL);
2024  */
2026  (LPSTR)sigOID, 0, NULL, NULL, &size);
2027  pubKeyInfo = HeapAlloc(GetProcessHeap(), 0, size);
2028  if (pubKeyInfo)
2029  {
2031  X509_ASN_ENCODING, (LPSTR)sigOID, 0, NULL, pubKeyInfo, &size);
2032  ok(ret, "CryptExportKey failed: %08x\n", GetLastError());
2033  if (ret)
2034  {
2035  ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
2037  CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pubKeyInfo, 0, NULL);
2038  ok(ret, "CryptVerifyCertificateSignatureEx failed: %08x\n",
2039  GetLastError());
2040  }
2041  HeapFree(GetProcessHeap(), 0, pubKeyInfo);
2042  }
2043  LocalFree(cert);
2044  }
2045 }
2046 
2047 static BYTE emptyCert[] = { 0x30, 0x00 };
2048 
2049 static void testCertSigs(void)
2050 {
2051  HCRYPTPROV csp;
2052  CRYPT_DATA_BLOB toBeSigned = { sizeof(emptyCert), emptyCert };
2053  BOOL ret;
2054  BYTE sig[64];
2055  DWORD sigSize = sizeof(sig);
2056 
2057  /* Just in case a previous run failed, delete this thing */
2058  pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2060  ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2061  CRYPT_NEWKEYSET);
2062  ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
2063 
2064  testSignCert(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, &sigSize);
2065  testVerifyCertSig(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize);
2066  testVerifyCertSigEx(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize);
2067 
2068  CryptReleaseContext(csp, 0);
2069  ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2071  ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
2072 }
2073 
2074 static const BYTE md5SignedEmptyCert[] = {
2075 0x30,0x56,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
2076 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
2077 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
2078 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
2079 0x0d,0x02,0x05,0x05,0x00,0x03,0x11,0x00,0xfb,0x0f,0x66,0x82,0x66,0xd9,0xe5,0xf8,
2080 0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
2081 static const BYTE md5SignedEmptyCertNoNull[] = {
2082 0x30,0x54,0x30,0x33,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
2083 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,
2084 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x07,
2085 0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,
2086 0x0d,0x02,0x05,0x03,0x11,0x00,0x04,0xd9,0xa5,0xe1,0x2b,0x55,0xa2,0xd8,0xf8,0xe5,
2087 0xd9,0x66,0x82,0x66,0x0f,0xfb };
2088 
2089 static void testSignAndEncodeCert(void)
2090 {
2091  static char oid_rsa_md5rsa[] = szOID_RSA_MD5RSA;
2092  static char oid_rsa_md5[] = szOID_RSA_MD5;
2093  BOOL ret;
2094  DWORD size;
2095  CRYPT_ALGORITHM_IDENTIFIER algID = { 0 };
2096  CERT_INFO info = { 0 };
2097 
2098  /* Crash
2099  ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
2100  NULL);
2101  ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, NULL, NULL, NULL,
2102  &size);
2103  */
2104  ret = CryptSignAndEncodeCertificate(0, 0, 0, NULL, NULL, &algID, NULL, NULL,
2105  &size);
2107  "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2109  &algID, NULL, NULL, &size);
2111  "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2113  &algID, NULL, NULL, &size);
2115  "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2116  /* Crashes on some win9x boxes */
2117  if (0)
2118  {
2120  X509_CERT_TO_BE_SIGNED, NULL, &algID, NULL, NULL, &size);
2122  "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2123  }
2124  /* Crashes
2125  ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING,
2126  X509_CERT_TO_BE_SIGNED, &info, NULL, NULL, NULL, &size);
2127  */
2129  X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
2130  ok(!ret &&
2131  (GetLastError() == NTE_BAD_ALGID ||
2132  GetLastError() == OSS_BAD_PTR), /* win9x */
2133  "Expected NTE_BAD_ALGID, got %08x\n", GetLastError());
2134  algID.pszObjId = oid_rsa_md5rsa;
2136  X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
2137  ok(!ret &&
2139  GetLastError() == NTE_BAD_ALGID ||
2140  GetLastError() == OSS_BAD_PTR), /* Win9x */
2141  "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n",
2142  GetLastError());
2143  algID.pszObjId = oid_rsa_md5;
2145  X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size);
2146  /* oid_rsa_md5 not present in some win2k */
2147  if (ret)
2148  {
2150 
2151  if (buf)
2152  {
2154  X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, buf, &size);
2155  ok(ret, "CryptSignAndEncodeCertificate failed: %08x\n",
2156  GetLastError());
2157  /* Tricky: because the NULL parameters may either be omitted or
2158  * included as an asn.1-encoded NULL (0x05,0x00), two different
2159  * values are allowed.
2160  */
2161  ok(size == sizeof(md5SignedEmptyCert) ||
2162  size == sizeof(md5SignedEmptyCertNoNull), "Unexpected size %d\n",
2163  size);
2164  if (size == sizeof(md5SignedEmptyCert))
2166  "Unexpected value\n");
2167  else if (size == sizeof(md5SignedEmptyCertNoNull))
2169  "Unexpected value\n");
2170  HeapFree(GetProcessHeap(), 0, buf);
2171  }
2172  }
2173 }
2174 
2175 static void testCreateSelfSignCert(void)
2176 {
2178  CERT_NAME_BLOB name = { sizeof(subjectName), subjectName };
2179  HCRYPTPROV csp;
2180  BOOL ret;
2181  HCRYPTKEY key;
2183 
2184  if (!pCertCreateSelfSignCertificate)
2185  {
2186  win_skip("CertCreateSelfSignCertificate() is not available\n");
2187  return;
2188  }
2189 
2190  /* This crashes:
2191  context = pCertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL,
2192  NULL);
2193  * Calling this with no first parameter creates a new key container, which
2194  * lasts beyond the test, so I don't test that. Nb: the generated key
2195  * name is a GUID.
2196  context = pCertCreateSelfSignCertificate(0, &name, 0, NULL, NULL, NULL, NULL,
2197  NULL);
2198  */
2199 
2200  /* Acquire a CSP */
2201  pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2203  ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2204  CRYPT_NEWKEYSET);
2205  ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
2206 
2207  context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
2208  NULL, NULL);
2209  ok(!context && GetLastError() == NTE_NO_KEY,
2210  "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2211  ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
2212  ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
2213  if (ret)
2214  {
2215  context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
2216  NULL, NULL);
2217  ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
2218  GetLastError());
2219  if (context)
2220  {
2221  DWORD size = 0;
2222 
2223  /* The context must have a key provider info property */
2226  ok(ret && size, "Expected non-zero key provider info\n");
2227  if (size)
2228  {
2230 
2231  if (pInfo)
2232  {
2234  CERT_KEY_PROV_INFO_PROP_ID, pInfo, &size);
2235  ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2236  GetLastError());
2237  if (ret)
2238  {
2239  /* Sanity-check the key provider */
2241  "Unexpected key container\n");
2243  "Unexpected provider\n");
2244  ok(pInfo->dwKeySpec == AT_SIGNATURE,
2245  "Expected AT_SIGNATURE, got %d\n", pInfo->dwKeySpec);
2246  }
2247  HeapFree(GetProcessHeap(), 0, pInfo);
2248  }
2249  }
2250 
2252  }
2253 
2255  }
2256 
2257  CryptReleaseContext(csp, 0);
2258  ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2260  ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
2261 
2262  /* Do the same test with a CSP, AT_KEYEXCHANGE and key info */
2263  pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2265  ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2266  CRYPT_NEWKEYSET);
2267  ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
2268  ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
2269  ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
2270 
2271  memset(&info,0,sizeof(info));
2272  info.dwProvType = PROV_RSA_FULL;
2273  info.dwKeySpec = AT_KEYEXCHANGE;
2274  info.pwszProvName = (LPWSTR) MS_DEF_PROV_W;
2275  info.pwszContainerName = cspNameW;
2276  /* This should fail because the CSP doesn't have the specified key. */
2277  SetLastError(0xdeadbeef);
2278  context = pCertCreateSelfSignCertificate(csp, &name, 0, &info, NULL, NULL,
2279  NULL, NULL);
2280  ok(context == NULL, "expected failure\n");
2281  if (context != NULL)
2283  else
2284  ok(GetLastError() == NTE_NO_KEY, "expected NTE_NO_KEY, got %08x\n",
2285  GetLastError());
2286  /* Again, with a CSP, AT_SIGNATURE and key info */
2287  info.dwKeySpec = AT_SIGNATURE;
2288  SetLastError(0xdeadbeef);
2289  context = pCertCreateSelfSignCertificate(csp, &name, 0, &info, NULL, NULL,
2290  NULL, NULL);
2291  ok(context != NULL,
2292  "CertCreateSelfSignCertificate failed: %08x\n", GetLastError());
2293  if (context)
2294  {
2295  DWORD size = 0;
2296 
2297  /* The context must have a key provider info property */
2300  ok(ret && size, "Expected non-zero key provider info\n");
2301  if (size)
2302  {
2304 
2305  if (pInfo)
2306  {
2308  CERT_KEY_PROV_INFO_PROP_ID, pInfo, &size);
2309  ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2310  GetLastError());
2311  if (ret)
2312  {
2313  /* Sanity-check the key provider */
2315  "Unexpected key container\n");
2317  "Unexpected provider\n");
2318  ok(pInfo->dwKeySpec == AT_SIGNATURE,
2319  "Expected AT_SIGNATURE, got %d\n", pInfo->dwKeySpec);
2320  }
2321  HeapFree(GetProcessHeap(), 0, pInfo);
2322  }
2323  }
2324 
2326  }
2328 
2329  CryptReleaseContext(csp, 0);
2330  ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2332  ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
2333 
2334  /* Do the same test with no CSP, AT_KEYEXCHANGE and key info */
2335  info.dwKeySpec = AT_KEYEXCHANGE;
2336  context = pCertCreateSelfSignCertificate(0, &name, 0, &info, NULL, NULL,
2337  NULL, NULL);
2338  ok(context != NULL, "CertCreateSelfSignCertificate failed: %08x\n",
2339  GetLastError());
2340  if (context)
2341  {
2342  DWORD size = 0;
2343 
2344  /* The context must have a key provider info property */
2347  ok(ret && size, "Expected non-zero key provider info\n");
2348  if (size)
2349  {
2351 
2352  if (pInfo)
2353  {
2355  CERT_KEY_PROV_INFO_PROP_ID, pInfo, &size);
2356  ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2357  GetLastError());
2358  if (ret)
2359  {
2360  /* Sanity-check the key provider */
2362  "Unexpected key container\n");
2364  "Unexpected provider\n");
2365  ok(pInfo->dwKeySpec == AT_KEYEXCHANGE,
2366  "Expected AT_KEYEXCHANGE, got %d\n", pInfo->dwKeySpec);
2367  }
2368  HeapFree(GetProcessHeap(), 0, pInfo);
2369  }
2370  }
2371 
2373  }
2374 
2375  pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2377 
2378  /* Acquire a CSP and generate an AT_KEYEXCHANGE key in it. */
2379  pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2381  ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2382  CRYPT_NEWKEYSET);
2383  ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
2384 
2385  context = pCertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
2386  NULL, NULL);
2387  ok(!context && GetLastError() == NTE_NO_KEY,
2388  "Expected NTE_NO_KEY, got %08x\n", GetLastError());
2389  ret = CryptGenKey(csp, AT_KEYEXCHANGE, 0, &key);
2390  ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
2392 
2393  memset(&info,0,sizeof(info));
2394  info.dwProvType = PROV_RSA_FULL;
2395  info.dwKeySpec = AT_SIGNATURE;
2396  info.pwszProvName = (LPWSTR) MS_DEF_PROV_W;
2397  info.pwszContainerName = cspNameW;
2398  /* This should fail because the CSP doesn't have the specified key. */
2399  SetLastError(0xdeadbeef);
2400  context = pCertCreateSelfSignCertificate(csp, &name, 0, &info, NULL, NULL,
2401  NULL, NULL);
2402  ok(context == NULL, "expected failure\n");
2403  if (context != NULL)
2405  else
2406  ok(GetLastError() == NTE_NO_KEY, "expected NTE_NO_KEY, got %08x\n",
2407  GetLastError());
2408  /* Again, with a CSP, AT_KEYEXCHANGE and key info. This succeeds because the
2409  * CSP has an AT_KEYEXCHANGE key in it.
2410  */
2411  info.dwKeySpec = AT_KEYEXCHANGE;
2412  SetLastError(0xdeadbeef);
2413  context = pCertCreateSelfSignCertificate(csp, &name, 0, &info, NULL, NULL,
2414  NULL, NULL);
2415  ok(context != NULL,
2416  "CertCreateSelfSignCertificate failed: %08x\n", GetLastError());
2417  if (context)
2418  {
2419  DWORD size = 0;
2420 
2421  /* The context must have a key provider info property */
2424  ok(ret && size, "Expected non-zero key provider info\n");
2425  if (size)
2426  {
2428 
2429  if (pInfo)
2430  {
2432  CERT_KEY_PROV_INFO_PROP_ID, pInfo, &size);
2433  ok(ret, "CertGetCertificateContextProperty failed: %08x\n",
2434  GetLastError());
2435  if (ret)
2436  {
2437  /* Sanity-check the key provider */
2439  "Unexpected key container\n");
2441  "Unexpected provider\n");
2442  ok(pInfo->dwKeySpec == AT_KEYEXCHANGE,
2443  "Expected AT_KEYEXCHANGE, got %d\n", pInfo->dwKeySpec);
2444  }
2445  HeapFree(GetProcessHeap(), 0, pInfo);
2446  }
2447  }
2448 
2450  }
2451 
2452  CryptReleaseContext(csp, 0);
2453  ret = pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
2455  ok(ret, "CryptAcquireContext failed: %08x\n", GetLastError());
2456 
2457 }
2458 
2459 static void testIntendedKeyUsage(void)
2460 {
2461  BOOL ret;
2462  CERT_INFO info = { 0 };
2463  static char oid_key_usage[] = szOID_KEY_USAGE;
2464  /* A couple "key usages". Really they're just encoded bits which aren't
2465  * necessarily restricted to the defined key usage values.
2466  */
2467  static BYTE usage1[] = { 0x03,0x03,0x00,0xff,0xff };
2468  static BYTE usage2[] = { 0x03,0x03,0x01,0xff,0xfe };
2469  static const BYTE expected_usage1[] = { 0xff,0xff,0x00,0x00 };
2470  static const BYTE expected_usage2[] = { 0xff,0xfe,0x00,0x00 };
2471  CERT_EXTENSION ext = { oid_key_usage, TRUE, { sizeof(usage1), usage1 } };
2472  BYTE usage_bytes[4];
2473 
2474  if (0)
2475  {
2476  /* Crash */
2478  }
2479  ret = CertGetIntendedKeyUsage(0, &info, NULL, 0);
2480  ok(!ret, "expected failure\n");
2481  ret = CertGetIntendedKeyUsage(0, &info, usage_bytes, sizeof(usage_bytes));
2482  ok(!ret, "expected failure\n");
2484  ok(!ret, "expected failure\n");
2486  sizeof(usage_bytes));
2487  ok(!ret, "expected failure\n");
2488  info.cExtension = 1;
2489  info.rgExtension = &ext;
2491  ok(!ret, "expected failure\n");
2492  /* The unused bytes are filled with 0. */
2494  sizeof(usage_bytes));
2495  ok(ret, "CertGetIntendedKeyUsage failed: %08x\n", GetLastError());
2496  ok(!memcmp(usage_bytes, expected_usage1, sizeof(expected_usage1)),
2497  "unexpected value\n");
2498  /* The usage bytes are copied in big-endian order. */
2499  ext.Value.cbData = sizeof(usage2);
2500  ext.Value.pbData = usage2;
2502  sizeof(usage_bytes));
2503  ok(ret, "CertGetIntendedKeyUsage failed: %08x\n", GetLastError());
2504  ok(!memcmp(usage_bytes, expected_usage2, sizeof(expected_usage2)),
2505  "unexpected value\n");
2506 }
2507 
2510 
2511 static void testKeyUsage(void)
2512 {
2513  BOOL ret;
2515  DWORD size;
2516 
2517  /* Test base cases */
2520  "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2521  size = 1;
2524  "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2525  size = 0;
2528  "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2529  /* These crash
2530  ret = CertSetEnhancedKeyUsage(NULL, NULL);
2531  usage.cUsageIdentifier = 0;
2532  ret = CertSetEnhancedKeyUsage(NULL, &usage);
2533  */
2534  /* Test with a cert with no enhanced key usage extension */
2536  sizeof(bigCert));
2537  ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2538  GetLastError());
2539  if (context)
2540  {
2541  static const char oid[] = "1.2.3.4";
2542  BYTE buf[sizeof(CERT_ENHKEY_USAGE) + 2 * (sizeof(LPSTR) + sizeof(oid))];
2544 
2547  "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
2548  size = 1;
2550  if (ret)
2551  {
2552  /* Windows 2000, ME, or later: even though it succeeded, we expect
2553  * CRYPT_E_NOT_FOUND, which indicates there is no enhanced key
2554  * usage set for this cert (which implies it's valid for all uses.)
2555  */
2557  "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2558  ok(size == sizeof(CERT_ENHKEY_USAGE), "Wrong size %d\n", size);
2559  ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2560  ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2561  ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2562  pUsage->cUsageIdentifier);
2563  }
2564  else
2565  {
2566  /* Windows NT, 95, or 98: it fails, and the last error is
2567  * CRYPT_E_NOT_FOUND.
2568  */
2570  "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2571  }
2572  /* I can add a usage identifier when no key usage has been set */
2574  ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2575  GetLastError());
2576  size = sizeof(buf);
2579  ok(ret && GetLastError() == 0,
2580  "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2581  ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2582  pUsage->cUsageIdentifier);
2583  if (pUsage->cUsageIdentifier)
2584  ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2585  "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2586  /* Now set an empty key usage */
2587  pUsage->cUsageIdentifier = 0;
2588  ret = CertSetEnhancedKeyUsage(context, pUsage);
2589  ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2590  /* Shouldn't find it in the cert */
2591  size = sizeof(buf);
2595  "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2596  /* Should find it as an extended property */
2599  ok(ret && GetLastError() == 0,
2600  "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2601  ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2602  pUsage->cUsageIdentifier);
2603  /* Should find it as either */
2604  ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2605  ok(ret && GetLastError() == 0,
2606  "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2607  ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %d\n",
2608  pUsage->cUsageIdentifier);
2609  /* Add a usage identifier */
2611  ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2612  GetLastError());
2613  size = sizeof(buf);
2614  ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2615  ok(ret && GetLastError() == 0,
2616  "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2617  ok(pUsage->cUsageIdentifier == 1, "Expected 1 identifier, got %d\n",
2618  pUsage->cUsageIdentifier);
2619  if (pUsage->cUsageIdentifier)
2620  ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2621  "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2622  /* Re-adding the same usage identifier succeeds, though it only adds
2623  * a duplicate usage identifier on versions prior to Vista
2624  */
2626  ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2627  GetLastError());
2628  size = sizeof(buf);
2629  ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2630  ok(ret && GetLastError() == 0,
2631  "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2632  ok(pUsage->cUsageIdentifier == 1 || pUsage->cUsageIdentifier == 2,
2633  "Expected 1 or 2 identifiers, got %d\n", pUsage->cUsageIdentifier);
2634  if (pUsage->cUsageIdentifier)
2635  ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
2636  "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
2637  if (pUsage->cUsageIdentifier >= 2)
2638  ok(!strcmp(pUsage->rgpszUsageIdentifier[1], oid),
2639  "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[1]);
2640  /* Now set a NULL extended property--this deletes the property. */
2642  ok(ret, "CertSetEnhancedKeyUsage failed: %08x\n", GetLastError());
2643  SetLastError(0xbaadcafe);
2644  size = sizeof(buf);
2645  ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2646  ok(ret || broken(!ret && GetLastError() == CRYPT_E_NOT_FOUND /* NT4 */),
2647  "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2649  "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2650 
2652  }
2653  /* Now test with a cert with an enhanced key usage extension */
2655  sizeof(certWithUsage));
2656  ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
2657  GetLastError());
2658  if (context)
2659  {
2660  LPBYTE buf = NULL;
2661  DWORD bufSize = 0, i;
2662 
2663  /* The size may depend on what flags are used to query it, so I
2664  * realloc the buffer for each test.
2665  */
2668  ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2670  if (buf)
2671  {
2673 
2674  /* Should find it in the cert */
2675  size = bufSize;
2678  ok(ret && GetLastError() == 0,
2679  "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2680  ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2681  pUsage->cUsageIdentifier);
2682  for (i = 0; i < pUsage->cUsageIdentifier; i++)
2683  ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2684  "Expected %s, got %s\n", keyUsages[i],
2685  pUsage->rgpszUsageIdentifier[i]);
2686  HeapFree(GetProcessHeap(), 0, buf);
2687  }
2689  ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2691  if (buf)
2692  {
2694 
2695  /* Should find it as either */
2696  size = bufSize;
2697  ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2698  /* In Windows, GetLastError returns CRYPT_E_NOT_FOUND not found
2699  * here, even though the return is successful and the usage id
2700  * count is positive. I don't enforce that here.
2701  */
2702  ok(ret,
2703  "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2704  ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2705  pUsage->cUsageIdentifier);
2706  for (i = 0; i < pUsage->cUsageIdentifier; i++)
2707  ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2708  "Expected %s, got %s\n", keyUsages[i],
2709  pUsage->rgpszUsageIdentifier[i]);
2710  HeapFree(GetProcessHeap(), 0, buf);
2711  }
2712  /* Shouldn't find it as an extended property */
2716  "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
2717  /* Adding a usage identifier overrides the cert's usage!? */
2719  ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08x\n",
2720  GetLastError());
2722  ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2724  if (buf)
2725  {
2727 
2728  /* Should find it as either */
2729  size = bufSize;
2730  ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2731  ok(ret,
2732  "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2733  ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %d\n",
2734  pUsage->cUsageIdentifier);
2736  "Expected %s, got %s\n", szOID_RSA_RSA,
2737  pUsage->rgpszUsageIdentifier[0]);
2738  HeapFree(GetProcessHeap(), 0, buf);
2739  }
2740  /* But querying the cert directly returns its usage */
2743  ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2745  if (buf)
2746  {
2748 
2749  size = bufSize;
2752  ok(ret,
2753  "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2754  ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2755  pUsage->cUsageIdentifier);
2756  for (i = 0; i < pUsage->cUsageIdentifier; i++)
2757  ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2758  "Expected %s, got %s\n", keyUsages[i],
2759  pUsage->rgpszUsageIdentifier[i]);
2760  HeapFree(GetProcessHeap(), 0, buf);
2761  }
2762  /* And removing the only usage identifier in the extended property
2763  * results in the cert's key usage being found.
2764  */
2766  ok(ret, "CertRemoveEnhancedKeyUsage failed: %08x\n", GetLastError());
2768  ok(ret, "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2770  if (buf)
2771  {
2773 
2774  /* Should find it as either */
2775  size = bufSize;
2776  ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
2777  ok(ret,
2778  "CertGetEnhancedKeyUsage failed: %08x\n", GetLastError());
2779  ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %d\n",
2780  pUsage->cUsageIdentifier);
2781  for (i = 0; i < pUsage->cUsageIdentifier; i++)
2782  ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
2783  "Expected %s, got %s\n", keyUsages[i],
2784  pUsage->rgpszUsageIdentifier[i]);
2785  HeapFree(GetProcessHeap(), 0, buf);
2786  }
2787 
2789  }
2790 }
2791 
2792 static const BYTE cert2WithUsage[] = {
2793 0x30,0x81,0x89,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2794 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2795 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2796 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2797 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2798 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2799 0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x25,0x30,0x23,
2800 0x30,0x21,0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x17,0x30,0x15,0x06,
2801 0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x2a,0x86,0x48,0x86,
2802 0xf7,0x0d,0x01,0x01,0x01 };
2803 
2804 static void testGetValidUsages(void)
2805 {
2806  static const LPCSTR expectedOIDs[] = {
2807  "1.3.6.1.5.5.7.3.3",
2808  "1.3.6.1.5.5.7.3.2",
2809  "1.2.840.113549.1.1.1",
2810  };
2811  static const LPCSTR expectedOIDs2[] = {
2812  "1.3.6.1.5.5.7.3.2",
2813  "1.2.840.113549.1.1.1",
2814  };
2815  BOOL ret;
2816  int numOIDs;
2817  DWORD size;
2818  LPSTR *oids = NULL;
2819  PCCERT_CONTEXT contexts[3];
2820 
2821  if (!pCertGetValidUsages)
2822  {
2823  win_skip("CertGetValidUsages() is not available\n");
2824  return;
2825  }
2826 
2827  /* Crash
2828  ret = pCertGetValidUsages(0, NULL, NULL, NULL, NULL);
2829  ret = pCertGetValidUsages(0, NULL, NULL, NULL, &size);
2830  */
2831  contexts[0] = NULL;
2832  numOIDs = size = 0xdeadbeef;
2833  SetLastError(0xdeadbeef);
2834  ret = pCertGetValidUsages(1, &contexts[0], &numOIDs, NULL, &size);
2835  ok(ret, "CertGetValidUsages failed: %d\n", GetLastError());
2836  ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2837  ok(size == 0, "Expected size 0, got %d\n", size);
2839  sizeof(bigCert));
2841  sizeof(certWithUsage));
2843  cert2WithUsage, sizeof(cert2WithUsage));
2844  numOIDs = size = 0xdeadbeef;
2845  ret = pCertGetValidUsages(0, NULL, &numOIDs, NULL, &size);
2846  ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2847  ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2848  ok(size == 0, "Expected size 0, got %d\n", size);
2849  numOIDs = size = 0xdeadbeef;
2850  ret = pCertGetValidUsages(1, contexts, &numOIDs, NULL, &size);
2851  ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2852  ok(numOIDs == -1, "Expected -1, got %d\n", numOIDs);
2853  ok(size == 0, "Expected size 0, got %d\n", size);
2854  ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, NULL, &size);
2855  ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2856  ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2857  ok(size, "Expected non-zero size\n");
2858  oids = HeapAlloc(GetProcessHeap(), 0, size);
2859  if (oids)
2860  {
2861  int i;
2862  DWORD smallSize = 1;
2863 
2864  SetLastError(0xdeadbeef);
2865  ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &smallSize);
2867  "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
2868  ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2869  ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2870  for (i = 0; i < numOIDs; i++)
2871  ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2872  oids[i]);
2873  HeapFree(GetProcessHeap(), 0, oids);
2874  }
2875  numOIDs = 0xdeadbeef;
2876  /* Oddly enough, this crashes when the number of contexts is not 1:
2877  ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2878  * but setting size to 0 allows it to succeed:
2879  */
2880  size = 0;
2881  ret = pCertGetValidUsages(2, contexts, &numOIDs, NULL, &size);
2882  ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2883  ok(numOIDs == 3, "Expected 3, got %d\n", numOIDs);
2884  ok(size, "Expected non-zero size\n");
2885  oids = HeapAlloc(GetProcessHeap(), 0, size);
2886  if (oids)
2887  {
2888  int i;
2889 
2890  ret = pCertGetValidUsages(1, &contexts[1], &numOIDs, oids, &size);
2891  ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2892  for (i = 0; i < numOIDs; i++)
2893  ok(!lstrcmpA(oids[i], expectedOIDs[i]), "unexpected OID %s\n",
2894  oids[i]);
2895  HeapFree(GetProcessHeap(), 0, oids);
2896  }
2897  numOIDs = 0xdeadbeef;
2898  size = 0;
2899  ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, NULL, &size);
2900  ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2901  ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2902  ok(size, "Expected non-zero size\n");
2903  oids = HeapAlloc(GetProcessHeap(), 0, size);
2904  if (oids)
2905  {
2906  int i;
2907 
2908  ret = pCertGetValidUsages(1, &contexts[2], &numOIDs, oids, &size);
2909  ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2910  for (i = 0; i < numOIDs; i++)
2911  ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2912  oids[i]);
2913  HeapFree(GetProcessHeap(), 0, oids);
2914  }
2915  numOIDs = 0xdeadbeef;
2916  size = 0;
2917  ret = pCertGetValidUsages(3, contexts, &numOIDs, NULL, &size);
2918  ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2919  ok(numOIDs == 2, "Expected 2, got %d\n", numOIDs);
2920  ok(size, "Expected non-zero size\n");
2921  oids = HeapAlloc(GetProcessHeap(), 0, size);
2922  if (oids)
2923  {
2924  int i;
2925 
2926  ret = pCertGetValidUsages(3, contexts, &numOIDs, oids, &size);
2927  ok(ret, "CertGetValidUsages failed: %08x\n", GetLastError());
2928  for (i = 0; i < numOIDs; i++)
2929  ok(!lstrcmpA(oids[i], expectedOIDs2[i]), "unexpected OID %s\n",
2930  oids[i]);
2931  HeapFree(GetProcessHeap(), 0, oids);
2932  }
2933  CertFreeCertificateContext(contexts[0]);
2934  CertFreeCertificateContext(contexts[1]);
2935  CertFreeCertificateContext(contexts[2]);
2936 }
2937 
2938 static BYTE cn[] = {
2939 0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,
2940 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67 };
2942 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x20,0x4a,
2943 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67 };
2945 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
2946 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x20 };
2948 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
2949 0x61,0x6e,0x20,0x20,0x4c,0x61,0x6e,0x67 };
2950 static BYTE cnThenO[] = {
2951 0x30,0x2d,0x31,0x2b,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,
2952 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x30,0x17,0x06,0x03,0x55,0x04,0x0a,0x13,
2953 0x10,0x54,0x68,0x65,0x20,0x57,0x69,0x6e,0x65,0x20,0x50,0x72,0x6f,0x6a,0x65,
2954 0x63,0x74 };
2955 static BYTE oThenCN[] = {
2956 0x30,0x2d,0x31,0x2b,0x30,0x10,0x06,0x03,0x55,0x04,0x0a,0x13,0x09,0x4a,0x75,
2957 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,
2958 0x10,0x54,0x68,0x65,0x20,0x57,0x69,0x6e,0x65,0x20,0x50,0x72,0x6f,0x6a,0x65,
2959 0x63,0x74 };
2960 
2961 static void testCompareCertName(void)
2962 {
2963  static BYTE bogus[] = { 1, 2, 3, 4 };
2964  static BYTE bogusPrime[] = { 0, 1, 2, 3, 4 };
2965  static BYTE emptyPrime[] = { 0x30, 0x00, 0x01 };
2966  BOOL ret;
2967  CERT_NAME_BLOB blob1, blob2;
2968 
2969  /* crashes
2970  ret = CertCompareCertificateName(0, NULL, NULL);
2971  */
2972  /* An empty name checks against itself.. */
2973  blob1.pbData = emptyCert;
2974  blob1.cbData = sizeof(emptyCert);
2975  ret = CertCompareCertificateName(0, &blob1, &blob1);
2976  ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2977  /* It doesn't have to be a valid encoded name.. */
2978  blob1.pbData = bogus;
2979  blob1.cbData = sizeof(bogus);
2980  ret = CertCompareCertificateName(0, &blob1, &blob1);
2981  ok(ret, "CertCompareCertificateName failed: %08x\n", GetLastError());
2982  /* Leading zeroes matter.. */
2983  blob2.pbData = bogusPrime;
2984  blob2.cbData = sizeof(bogusPrime);
2985  ret = CertCompareCertificateName(0, &blob1, &blob2);
2986  ok(!ret, "Expected failure\n");
2987  /* As do trailing extra bytes. */
2988  blob2.pbData = emptyPrime;
2989  blob2.cbData = sizeof(emptyPrime);
2990  ret = CertCompareCertificateName(0, &blob1, &blob2);
2991  ok(!ret, "Expected failure\n");
2992  /* Tests to show that CertCompareCertificateName doesn't decode the name
2993  * to remove spaces, or to do an order-independent comparison.
2994  */
2995  /* Compare CN="Juan Lang" with CN=" Juan Lang" */
2996  blob1.pbData = cn;
2997  blob1.cbData = sizeof(cn);
2998  blob2.pbData = cnWithLeadingSpace;
2999  blob2.cbData = sizeof(cnWithLeadingSpace);
3000  ret = CertCompareCertificateName(0, &blob1, &blob2);
3001  ok(!ret, "Expected failure\n");
3003  ok(!ret, "Expected failure\n");
3004  /* Compare CN="Juan Lang" with CN="Juan Lang " */
3005  blob2.pbData = cnWithTrailingSpace;
3006  blob2.cbData = sizeof(cnWithTrailingSpace);
3007  ret = CertCompareCertificateName(0, &blob1, &blob2);
3008  ok(!ret, "Expected failure\n");
3010  ok(!ret, "Expected failure\n");
3011  /* Compare CN="Juan Lang" with CN="Juan Lang" */
3013  blob2.cbData = sizeof(cnWithIntermediateSpace);
3014  ret = CertCompareCertificateName(0, &blob1, &blob2);
3015  ok(!ret, "Expected failure\n");
3017  ok(!ret, "Expected failure\n");
3018  /* Compare 'CN="Juan Lang", O="The Wine Project"' with
3019  * 'O="The Wine Project", CN="Juan Lang"'
3020  */
3021  blob1.pbData = cnThenO;
3022  blob1.cbData = sizeof(cnThenO);
3023  blob2.pbData = oThenCN;
3024  blob2.cbData = sizeof(oThenCN);
3025  ret = CertCompareCertificateName(0, &blob1, &blob2);
3026  ok(!ret, "Expected failure\n");
3028  ok(!ret, "Expected failure\n");
3029 }
3030 
3032 {
3033  static char oid_1_2_3[] = "1.2.3";
3034  static char oid_common_name[] = szOID_COMMON_NAME;
3035  static char oid_organization[] = szOID_ORGANIZATION_NAME;
3036  static char juan[] = "Juan Lang";
3037  static char juan_with_leading_space[] = " Juan Lang";
3038  static char juan_with_intermediate_space[] = "Juan Lang";
3039  static char juan_with_trailing_space[] = "Juan Lang ";
3040  static char juan_lower_case[] = "juan lang";
3041  static WCHAR juanW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
3042  static char the_wine_project[] = "The Wine Project";
3043  BOOL ret;
3045  CERT_RDN_ATTR attr[2];
3046  CERT_RDN rdn = { 0, NULL };
3047 
3048  name.cbData = sizeof(cn);
3049  name.pbData = cn;
3050  if (0)
3051  {
3052  /* Crash */
3055  }
3056  SetLastError(0xdeadbeef);
3059  "expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
3061  ok(ret, "CertIsRDNAttrsInCertificateName failed: %08x\n", GetLastError());
3062  attr[0].pszObjId = oid_1_2_3;
3063  rdn.rgRDNAttr = attr;
3064  rdn.cRDNAttr = 1;
3065  SetLastError(0xdeadbeef);
3068  "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
3069  attr[0].pszObjId = oid_common_name;
3070  attr[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
3071  attr[0].Value.cbData = strlen(juan);
3072  attr[0].Value.pbData = (BYTE *)juan;
3074  ok(ret, "CertIsRDNAttrsInCertificateName failed: %08x\n", GetLastError());
3075  /* Again, spaces are not removed for name comparison. */
3076  attr[0].Value.cbData = strlen(juan_with_leading_space);
3077  attr[0].Value.pbData = (BYTE *)juan_with_leading_space;
3078  SetLastError(0xdeadbeef);
3081  "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
3082  attr[0].Value.cbData = strlen(juan_with_intermediate_space);
3083  attr[0].Value.pbData = (BYTE *)juan_with_intermediate_space;
3084  SetLastError(0xdeadbeef);
3087  "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
3088  attr[0].Value.cbData = strlen(juan_with_trailing_space);
3089  attr[0].Value.pbData = (BYTE *)juan_with_trailing_space;
3090  SetLastError(0xdeadbeef);
3093  "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
3094  /* The lower case name isn't matched unless a case insensitive match is
3095  * specified.
3096  */
3097  attr[0].Value.cbData = strlen(juan_lower_case);
3098  attr[0].Value.pbData = (BYTE *)juan_lower_case;
3099  SetLastError(0xdeadbeef);
3102  "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
3105  ok(ret ||
3106  broken(!ret && GetLastError() == CRYPT_E_NO_MATCH), /* Older crypt32 */
3107  "CertIsRDNAttrsInCertificateName failed: %08x\n", GetLastError());
3108  /* The values don't match unless they have the same RDN type */
3109  attr[0].dwValueType = CERT_RDN_UNICODE_STRING;
3110  attr[0].Value.cbData = lstrlenW(juanW) * sizeof(WCHAR);
3111  attr[0].Value.pbData = (BYTE *)juanW;
3112  SetLastError(0xdeadbeef);
3115  "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
3116  SetLastError(0xdeadbeef);
3120  "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
3121  attr[0].dwValueType = CERT_RDN_IA5_STRING;
3122  attr[0].Value.cbData = strlen(juan);
3123  attr[0].Value.pbData = (BYTE *)juan;
3124  SetLastError(0xdeadbeef);
3127  "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
3128  /* All attributes must be present */
3129  attr[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
3130  attr[0].Value.cbData = strlen(juan);
3131  attr[0].Value.pbData = (BYTE *)juan;
3132  attr[1].pszObjId = oid_organization;
3133  attr[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
3134  attr[1].Value.cbData = strlen(the_wine_project);
3135  attr[1].Value.pbData = (BYTE *)the_wine_project;
3136  rdn.cRDNAttr = 2;
3137  SetLastError(0xdeadbeef);
3140  "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
3141  /* Order also matters */
3142  name.pbData = cnThenO;
3143  name.cbData = sizeof(cnThenO);
3145  ok(ret, "CertIsRDNAttrsInCertificateName failed: %08x\n", GetLastError());
3146  name.pbData = oThenCN;
3147  name.cbData = sizeof(oThenCN);
3148  SetLastError(0xdeadbeef);
3151  "expected CRYPT_E_NO_MATCH, got %08x\n", GetLastError());
3152 }
3153 
3154 static BYTE int1[] = { 0x88, 0xff, 0xff, 0xff };
3155 static BYTE int2[] = { 0x88, 0xff };
3156 static BYTE int3[] = { 0x23, 0xff };
3157 static BYTE int4[] = { 0x7f, 0x00 };
3158 static BYTE int5[] = { 0x7f };
3159 static BYTE int6[] = { 0x80, 0x00, 0x00, 0x00 };
3160 static BYTE int7[] = { 0x80, 0x00 };
3161 
3162 static struct IntBlobTest
3163 {
3167 } intBlobs[] = {
3168  { { sizeof(int1), int1 }, { sizeof(int2), int2 }, TRUE },
3169  { { sizeof(int3), int3 }, { sizeof(int3), int3 }, TRUE },
3170  { { sizeof(int4), int4 }, { sizeof(int5), int5 }, TRUE },
3171  { { sizeof(int6), int6 }, { sizeof(int7), int7 }, TRUE },
3172  { { sizeof(int1), int1 }, { sizeof(int7), int7 }, FALSE },
3173 };
3174 
3175 static void testCompareIntegerBlob(void)
3176 {
3177  DWORD i;
3178  BOOL ret;
3179 
3180  for (i = 0; i < ARRAY_SIZE(intBlobs); i++)
3181  {
3182  ret = CertCompareIntegerBlob(&intBlobs[i].blob1, &intBlobs[i].blob2);
3183  ok(ret == intBlobs[i].areEqual,
3184  "%d: expected blobs %s compare\n", i, intBlobs[i].areEqual ?
3185  "to" : "not to");
3186  }
3187 }
3188 
3189 static void testComparePublicKeyInfo(void)
3190 {
3191  BOOL ret;
3192  CERT_PUBLIC_KEY_INFO info1 = { { 0 } }, info2 = { { 0 } };
3193  static CHAR oid_rsa_rsa[] = szOID_RSA_RSA;
3194  static CHAR oid_rsa_sha1rsa[] = szOID_RSA_SHA1RSA;
3195  static CHAR oid_x957_dsa[] = szOID_X957_DSA;
3196  static BYTE bits1[] = { 1, 0 };
3197  static BYTE bits2[] = { 0 };
3198  static BYTE bits3[] = { 1 };
3199  static BYTE bits4[] = { 0x30,8, 2,1,0x81, 2,3,1,0,1 }; /* ASN_SEQUENCE */
3200  static BYTE bits5[] = { 0x30,9, 2,2,0,0x81, 2,3,1,0,1 }; /* ASN_SEQUENCE */
3201  static BYTE bits6[] = { 0x30,9, 2,2,0,0x82, 2,3,1,0,1 }; /* ASN_SEQUENCE */
3202  static BYTE bits7[] = { 0x04,8, 2,1,0x81, 2,3,1,0,1 }; /* ASN_OCTETSTRING */
3203  static BYTE bits8[] = { 0x04,9, 2,2,0,0x81, 2,3,1,0,1 }; /* ASN_OCTETSTRING */
3204  static BYTE bits9[] = { 0x04,9, 2,2,0,0x82, 2,3,1,0,1 }; /* ASN_OCTETSTRING */
3205 
3206  /* crashes
3207  ret = CertComparePublicKeyInfo(0, NULL, NULL);
3208  */
3209  /* Empty public keys compare */
3210  ret = CertComparePublicKeyInfo(0, &info1, &info2);
3211  ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
3212  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
3213  ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
3214 
3215  /* Different OIDs appear to compare */
3216  info1.Algorithm.pszObjId = oid_rsa_rsa;
3217  info2.Algorithm.pszObjId = oid_rsa_sha1rsa;
3218  ret = CertComparePublicKeyInfo(0, &info1, &info2);
3219  ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
3220  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
3221  ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
3222 
3223  info2.Algorithm.pszObjId = oid_x957_dsa;
3224  ret = CertComparePublicKeyInfo(0, &info1, &info2);
3225  ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
3226  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
3227  ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
3228 
3229  info1.PublicKey.cbData = sizeof(bits1);
3230  info1.PublicKey.pbData = bits1;
3231  info1.PublicKey.cUnusedBits = 0;
3232  info2.PublicKey.cbData = sizeof(bits1);
3233  info2.PublicKey.pbData = bits1;
3234  info2.PublicKey.cUnusedBits = 0;
3235  ret = CertComparePublicKeyInfo(0, &info1, &info2);
3236  ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
3237  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
3238  ok(ret, "CertComparePublicKeyInfo failed: %08x\n", GetLastError());
3239 
3240  info2.Algorithm.pszObjId = oid_rsa_rsa;
3241  info1.PublicKey.cbData = sizeof(bits4);
3242  info1.PublicKey.pbData = bits4;
3243  info1.PublicKey.cUnusedBits = 0;
3244  info2.PublicKey.cbData = sizeof(bits5);
3245  info2.PublicKey.pbData = bits5;
3246  info2.PublicKey.cUnusedBits = 0;
3247  ret = CertComparePublicKeyInfo(0, &info1, &info2);
3248  ok(!ret, "CertComparePublicKeyInfo: as raw binary: keys should be unequal\n");
3249  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
3250  ok(ret, "CertComparePublicKeyInfo: as ASN.1 encoded: keys should be equal\n");
3251 
3252  info1.PublicKey.cUnusedBits = 1;
3253  info2.PublicKey.cUnusedBits = 5;
3254  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
3255  ok(ret, "CertComparePublicKeyInfo: ASN.1 encoding should ignore cUnusedBits\n");
3256  info1.PublicKey.cUnusedBits = 0;
3257  info2.PublicKey.cUnusedBits = 0;
3258  info1.PublicKey.cbData--; /* kill one byte, make ASN.1 encoded data invalid */
3259  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
3260  ok(!ret, "CertComparePublicKeyInfo: comparing bad ASN.1 encoded key should fail\n");
3261  /* Even though they compare in their used bits, these do not compare */
3262  info1.PublicKey.cbData = sizeof(bits2);
3263  info1.PublicKey.pbData = bits2;
3264  info1.PublicKey.cUnusedBits = 0;
3265  info2.PublicKey.cbData = sizeof(bits3);
3266  info2.PublicKey.pbData = bits3;
3267  info2.PublicKey.cUnusedBits = 1;
3268  ret = CertComparePublicKeyInfo(0, &info1, &info2);
3269  /* Simple (non-comparing) case */
3270  ok(!ret, "Expected keys not to compare\n");
3271  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
3272  ok(!ret, "Expected keys not to compare\n");
3273 
3274  info2.PublicKey.cbData = sizeof(bits1);
3275  info2.PublicKey.pbData = bits1;
3276  info2.PublicKey.cUnusedBits = 0;
3277  ret = CertComparePublicKeyInfo(0, &info1, &info2);
3278  ok(!ret, "Expected keys not to compare\n");
3279  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
3280  ok(!ret, "Expected keys not to compare\n");
3281 
3282  info1.PublicKey.cbData = sizeof(bits7);
3283  info1.PublicKey.pbData = bits7;
3284  info1.PublicKey.cUnusedBits = 0;
3285  info2.PublicKey.cbData = sizeof(bits8);
3286  info2.PublicKey.pbData = bits8;
3287  info2.PublicKey.cUnusedBits = 0;
3288  ret = CertComparePublicKeyInfo(0, &info1, &info2);
3289  ok(!ret, "CertComparePublicKeyInfo: as raw binary: keys should be unequal\n");
3290  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
3291  ok(!ret, "CertComparePublicKeyInfo: as ASN.1 encoded: keys should be unequal\n");
3292 
3293  ret = CertComparePublicKeyInfo(0, &info1, &info1);
3294  ok(ret, "CertComparePublicKeyInfo: as raw binary: keys should be equal\n");
3295  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info1);
3296  ok(ret, "CertComparePublicKeyInfo: as ASN.1 encoded: keys should be equal\n");
3297  info1.PublicKey.cbData--; /* kill one byte, make ASN.1 encoded data invalid */
3298  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info1);
3299  ok(ret, "CertComparePublicKeyInfo: as ASN.1 encoded: keys should be equal\n");
3300 
3301  /* ASN.1 encoded non-comparing case */
3302  info1.PublicKey.cbData = sizeof(bits5);
3303  info1.PublicKey.pbData = bits5;
3304  info1.PublicKey.cUnusedBits = 0;
3305  info2.PublicKey.cbData = sizeof(bits6);
3306  info2.PublicKey.pbData = bits6;
3307  info2.PublicKey.cUnusedBits = 0;
3308  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
3309  ok(!ret, "CertComparePublicKeyInfo: different keys should be unequal\n");
3310 
3311  /* ASN.1 encoded non-comparing case */
3312  info1.PublicKey.cbData = sizeof(bits8);
3313  info1.PublicKey.pbData = bits8;
3314  info1.PublicKey.cUnusedBits = 0;
3315  info2.PublicKey.cbData = sizeof(bits9);
3316  info2.PublicKey.pbData = bits9;
3317  info2.PublicKey.cUnusedBits = 0;
3318  ret = CertComparePublicKeyInfo(X509_ASN_ENCODING, &info1, &info2);
3319  ok(!ret, "CertComparePublicKeyInfo: different keys should be unequal\n");
3320 }
3321 
3322 static void testHashPublicKeyInfo(void)
3323 {
3324  BOOL ret;
3325  CERT_PUBLIC_KEY_INFO info = { { 0 } };
3326  DWORD len;
3327 
3328  /* Crash
3329  ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, NULL);
3330  ret = CryptHashPublicKeyInfo(0, 0, 0, 0, &info, NULL, NULL);
3331  */
3332  ret = CryptHashPublicKeyInfo(0, 0, 0, 0, NULL, NULL, &len);
3334  "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
3335  /* Crashes on some win9x boxes */
3336  if (0)
3337  {
3340  "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3341  }
3343  ok(ret ||
3344  broken(!ret), /* win9x */
3345  "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
3346  if (ret)
3347  {
3348  ok(len == 16, "Expected hash size 16, got %d\n", len);
3349  if (len == 16)
3350  {
3351  static const BYTE emptyHash[] = { 0xb8,0x51,0x3a,0x31,0x0e,0x9f,0x40,
3352  0x36,0x9c,0x92,0x45,0x1b,0x9d,0xc8,0xf9,0xf6 };
3353  BYTE buf[16];
3354 
3356  &len);
3357  ok(ret, "CryptHashPublicKeyInfo failed: %08x\n", GetLastError());
3358  ok(!memcmp(buf, emptyHash, len), "Unexpected hash\n");
3359  }
3360  }
3361 }
3362 
3363 static const BYTE md5SignedEmptyCertHash[] = { 0xfb,0x0f,0x66,0x82,0x66,0xd9,
3364  0xe5,0xf8,0xd8,0xa2,0x55,0x2b,0xe1,0xa5,0xd9,0x04 };
3365 
3366 static void testHashToBeSigned(void)
3367 {
3368  BOOL ret;
3369  DWORD size;
3370  BYTE hash[16];
3371 
3372  /* Crash */
3373  if (0)
3374  {
3375  CryptHashToBeSigned(0, 0, NULL, 0, NULL, NULL);
3376  }
3377  SetLastError(0xdeadbeef);
3378  ret = CryptHashToBeSigned(0, 0, NULL, 0, NULL, &size);
3380  "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
3381  SetLastError(0xdeadbeef);
3383  ok(!ret &&
3385  GetLastError() == OSS_BAD_ARG), /* win9x */
3386  "expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
3387  /* Can't sign anything: has to be asn.1 encoded, at least */
3388  SetLastError(0xdeadbeef);
3390  NULL, &size);
3391  ok(!ret &&
3393  GetLastError() == OSS_MORE_INPUT), /* win9x */
3394  "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
3395  /* Can't be empty, either */
3396  SetLastError(0xdeadbeef);
3398  sizeof(emptyCert), NULL, &size);
3399  ok(!ret &&
3401  GetLastError() == OSS_DATA_ERROR), /* win9x */
3402  "expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
3403  /* Signing a cert works */
3405  sizeof(md5SignedEmptyCert), NULL, &size);
3406  ok(ret ||
3407  broken(!ret), /* win9x */
3408  "CryptHashToBeSigned failed: %08x\n", GetLastError());
3409  if (ret)
3410  {
3411  ok(size == sizeof(md5SignedEmptyCertHash), "unexpected size %d\n", size);
3412  }
3413 
3415  sizeof(md5SignedEmptyCert), hash, &size);
3416  ok(ret || broken(!ret && GetLastError() == NTE_BAD_ALGID) /* NT4 */,
3417  "CryptHashToBeSigned failed: %08x\n", GetLastError());
3418 
3419  ok(!memcmp(hash, md5SignedEmptyCertHash, size), "unexpected value\n");
3420 }
3421 
3422 static void testCompareCert(void)
3423 {
3424  CERT_INFO info1 = { 0 }, info2 = { 0 };
3425  BOOL ret;
3426 
3427  /* Crashes */
3428  if (0)
3430 
3431  /* Certs with the same issuer and serial number are equal, even if they
3432  * differ in other respects (like subject).
3433  */
3434  info1.SerialNumber.pbData = serialNum;
3435  info1.SerialNumber.cbData = sizeof(serialNum);
3436  info1.Issuer.pbData = subjectName;
3437  info1.Issuer.cbData = sizeof(subjectName);
3438  info1.Subject.pbData = subjectName2;
3439  info1.Subject.cbData = sizeof(subjectName2);
3440  info2.SerialNumber.pbData = serialNum;
3441  info2.SerialNumber.cbData = sizeof(serialNum);
3442  info2.Issuer.pbData = subjectName;
3443  info2.Issuer.cbData = sizeof(subjectName);
3444  info2.Subject.pbData = subjectName;
3445  info2.Subject.cbData = sizeof(subjectName);
3446  ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
3447  ok(ret, "Expected certs to be equal\n");
3448 
3449  info2.Issuer.pbData = subjectName2;
3450  info2.Issuer.cbData = sizeof(subjectName2);
3451  ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
3452  ok(!ret, "Expected certs not to be equal\n");
3453 }
3454 
3455 static void testVerifySubjectCert(void)
3456 {
3457  BOOL ret;
3458  DWORD flags;
3459  PCCERT_CONTEXT context1, context2;
3460 
3461  /* Crashes
3462  ret = CertVerifySubjectCertificateContext(NULL, NULL, NULL);
3463  */
3464  flags = 0;
3466  ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
3467  GetLastError());
3470  ok(!ret && GetLastError() == E_INVALIDARG,
3471  "Expected E_INVALIDARG, got %08x\n", GetLastError());
3472 
3473  flags = 0;
3475  sizeof(bigCert));
3477  ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
3478  GetLastError());
3480  ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
3481  GetLastError());
3482  ret = CertVerifySubjectCertificateContext(context1, context1, &flags);
3483  ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
3484  GetLastError());
3485 
3488  SetLastError(0xdeadbeef);
3489  ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
3490  ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
3491  GetLastError());
3493  ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
3494  ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
3495  GetLastError());
3497  "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08x\n",
3498  flags);
3500  ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
3501  ok(ret, "CertVerifySubjectCertificateContext failed; %08x\n",
3502  GetLastError());
3504  "Expected CERT_STORE_SIGNATURE_FLAG, got %08x\n", flags);
3505  CertFreeCertificateContext(context2);
3506 
3507  CertFreeCertificateContext(context1);
3508 }
3509 
3511 0x30,0x82,0x01,0xdf,0x30,0x82,0x01,0x4c,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,
3512 0x5b,0xc7,0x0b,0x27,0x99,0xbb,0x2e,0x99,0x47,0x9d,0x45,0x4e,0x7c,0x1a,0xca,
3513 0xe8,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31,
3514 0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,
3515 0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3516 0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3517 0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,
3518 0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3519 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,
3520 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82,
3521 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34,
3522 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7,
3523 0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91,
3524 0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5,
3525 0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd,
3526 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c,
3527 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35,
3528 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01,
3529 0x00,0x01,0xa3,0x42,0x30,0x40,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,
3530 0xff,0x04,0x04,0x03,0x02,0x00,0x06,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,
3531 0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1d,0x06,0x03,0x55,0x1d,
3532 0x0e,0x04,0x16,0x04,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,0x28,0x89,0xa0,
3533 0x58,0xff,0x98,0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x09,0x06,0x05,0x2b,
3534 0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,0x81,0x00,0x74,0xcb,0x21,0xfd,0x2d,
3535 0x25,0xdc,0xa5,0xaa,0xa1,0x26,0xdc,0x8b,0x40,0x11,0x64,0xae,0x5c,0x71,0x3c,
3536 0x28,0xbc,0xf9,0xb3,0xcb,0xa5,0x94,0xb2,0x8d,0x4c,0x23,0x2b,0x9b,0xde,0x2c,
3537 0x4c,0x30,0x04,0xc6,0x88,0x10,0x2f,0x53,0xfd,0x6c,0x82,0xf1,0x13,0xfb,0xda,
3538 0x27,0x75,0x25,0x48,0xe4,0x72,0x09,0x2a,0xee,0xb4,0x1e,0xc9,0x55,0xf5,0xf7,
3539 0x82,0x91,0xd8,0x4b,0xe4,0x3a,0xfe,0x97,0x87,0xdf,0xfb,0x15,0x5a,0x12,0x3e,
3540 0x12,0xe6,0xad,0x40,0x0b,0xcf,0xee,0x1a,0x44,0xe0,0x83,0xb2,0x67,0x94,0xd4,
3541 0x2e,0x7c,0xf2,0x06,0x9d,0xb3,0x3b,0x7e,0x2f,0xda,0x25,0x66,0x7e,0xa7,0x1f,
3542 0x45,0xd4,0xf5,0xe3,0xdf,0x2a,0xf1,0x18,0x28,0x20,0xb5,0xf8,0xf5,0x8d,0x7a,
3543 0x2e,0x84,0xee };
3544 static const BYTE eeCert[] = {
3545 0x30,0x82,0x01,0xb9,0x30,0x82,0x01,0x22,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,
3546 0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,
3547 0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,
3548 0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30,
3549 0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30,
3550 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,
3551 0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,
3552 0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,
3553 0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,
3554 0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,
3555 0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,
3556 0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,
3557 0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,
3558 0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,
3559 0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,
3560 0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,
3561 0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,
3562 0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x23,0x30,0x21,0x30,0x1f,0x06,0x03,0x55,
3563 0x1d,0x23,0x04,0x18,0x30,0x18,0x80,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,
3564 0x28,0x89,0xa0,0x58,0xff,0x98,0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x0d,
3565 0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,
3566 0x81,0x00,0x8a,0x49,0xa9,0x86,0x5e,0xc9,0x33,0x7e,0xfd,0xab,0x64,0x1f,0x6d,
3567 0x00,0xd7,0x9b,0xec,0xd1,0x5b,0x38,0xcc,0xd6,0xf3,0xf2,0xb4,0x75,0x70,0x00,
3568 0x82,0x9d,0x37,0x58,0xe1,0xcd,0x2c,0x61,0xb3,0x28,0xe7,0x8a,0x00,0xbe,0x6e,
3569 0xca,0xe8,0x55,0xd5,0xad,0x3a,0xea,0xaf,0x13,0x20,0x1c,0x44,0xfc,0xb4,0xf9,
3570 0x29,0x2b,0xdc,0x8a,0x2d,0x1b,0x27,0x9e,0xb9,0x3b,0x4a,0x71,0x9d,0x47,0x7d,
3571 0xf7,0x92,0x6b,0x21,0x7f,0xfa,0x88,0x79,0x94,0x33,0xf6,0xdd,0x92,0x04,0x92,
3572 0xd6,0x5e,0x0a,0x74,0xf2,0x85,0xa6,0xd5,0x3c,0x28,0xc0,0x89,0x5d,0xda,0xf3,
3573 0xa6,0x01,0xc2,0xe9,0xa3,0xc1,0xb7,0x21,0x08,0xba,0x18,0x07,0x45,0xeb,0x77,
3574 0x7d,0xcd,0xc6,0xe7,0x2a,0x7b,0x46,0xd2,0x3d,0xb5 };
3575 static const BYTE rootSignedCRL[] = {
3576 0x30,0x82,0x01,0x1f,0x30,0x81,0x89,0x02,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a,
3577 0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x10,0x31,0x0e,0x30,
3578 0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x17,0x0d,
3579 0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,
3580 0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x14,
3581 0x30,0x12,0x02,0x01,0x01,0x17,0x0d,0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30,
3582 0x30,0x30,0x30,0x30,0x5a,0xa0,0x2f,0x30,0x2d,0x30,0x0a,0x06,0x03,0x55,0x1d,
3583 0x14,0x04,0x03,0x02,0x01,0x01,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,
3584 0x30,0x18,0x80,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,0x28,0x89,0xa0,0x58,
3585 0xff,0x98,0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x0d,0x06,0x09,0x2a,0x86,
3586 0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0xa3,0xcf,
3587 0x17,0x5d,0x7a,0x08,0xab,0x11,0x1a,0xbd,0x5c,0xde,0x9a,0x22,0x92,0x38,0xe6,
3588 0x96,0xcc,0xb1,0xc5,0x42,0x86,0xa6,0xae,0xad,0xa3,0x1a,0x2b,0xa0,0xb0,0x65,
3589 0xaa,0x9c,0xd7,0x2d,0x44,0x8c,0xae,0x61,0xc7,0x30,0x17,0x89,0x84,0x3b,0x4a,
3590 0x8f,0x17,0x08,0x06,0x37,0x1c,0xf7,0x2d,0x4e,0x47,0x07,0x61,0x50,0xd9,0x06,
3591 0xd1,0x46,0xed,0x0a,0xbb,0xc3,0x9b,0x36,0x0b,0xa7,0x27,0x2f,0x2b,0x55,0xce,
3592 0x2a,0xa5,0x60,0xc6,0x53,0x28,0xe8,0xee,0xad,0x0e,0x2b,0xe8,0xd7,0x5f,0xc9,
3593 0xa5,0xed,0xf9,0x77,0xb0,0x3c,0x81,0xcf,0xcc,0x49,0xb2,0x1a,0xc3,0xfd,0x34,
3594 0xd5,0xbc,0xb0,0xd5,0xa5,0x9c,0x1b,0x72,0xc3,0x0f,0xa3,0xe3,0x3c,0xf0,0xc3,
3595 0x91,0xe8,0x93,0x4f,0xd4,0x2f };
3596 
3597 static void testVerifyRevocation(void)
3598 {
3599  BOOL ret;
3601  PCCERT_CONTEXT certs[2];
3602  CERT_REVOCATION_PARA revPara = { sizeof(revPara), 0 };
3603 
3604  /* Crash
3605  ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL);
3606  */
3607  SetLastError(0xdeadbeef);
3608  ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
3609  ok(!ret && GetLastError() == E_INVALIDARG,
3610  "Expected E_INVALIDARG, got %08x\n", GetLastError());
3611  status.cbSize = sizeof(status);
3612  ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status);
3613  ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
3614  ret = CertVerifyRevocation(0, 2, 0, NULL, 0, NULL, &status);
3615  ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
3616  ret = CertVerifyRevocation(2, 0, 0, NULL, 0, NULL, &status);
3617  ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError());
3619  sizeof(bigCert));
3620  SetLastError(0xdeadbeef);
3621  ret = CertVerifyRevocation(0, 0, 1, (void **)certs, 0, NULL, &status);
3623  "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
3624  SetLastError(0xdeadbeef);
3625  ret = CertVerifyRevocation(0, 2, 1, (void **)certs, 0, NULL, &status);
3627  "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError());
3628 
3629  CertFreeCertificateContext(certs[0]);
3630 
3634  eeCert, sizeof(eeCert));
3635  /* The root cert itself can't be checked for revocation */
3636  SetLastError(0xdeadbeef);
3638  1, (void **)certs, 0, NULL, &status);
3639  if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3640  {
3641  win_skip("CERT_CONTEXT_REVOCATION_TYPE unsupported, skipping\n");
3642  return;
3643  }
3645  "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
3647  "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
3648  ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
3649  /* Neither can the end cert */
3650  SetLastError(0xdeadbeef);
3652  1, (void **)&certs[1], 0, NULL, &status);
3653  ok(!ret && (GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* Win9x */ ||
3655  "expected CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, got %08x\n",
3656  GetLastError());
3657  ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK /* Win9x */ ||
3659  "expected CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, got %08x\n",
3660  status.dwError);
3661  ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
3662  /* Both certs together can't, either (they're not CRLs) */
3663  SetLastError(0xdeadbeef);
3665  2, (void **)certs, 0, NULL, &status);
3667  GetLastError() == CRYPT_E_REVOCATION_OFFLINE /* WinME */),
3668  "expected CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, got %08x\n",
3669  GetLastError());
3670  ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK ||
3671  status.dwError == CRYPT_E_REVOCATION_OFFLINE /* WinME */,
3672  "expected CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, got %08x\n",
3673  status.dwError);
3674  ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
3675  /* Now add a CRL to the hCrlStore */
3680  SetLastError(0xdeadbeef);
3682  2, (void **)certs, 0, &revPara, &status);
3684  GetLastError() == CRYPT_E_REVOCATION_OFFLINE /* WinME */),
3685  "expected CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, got %08x\n",
3686  GetLastError());
3687  ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK ||
3688  status.dwError == CRYPT_E_REVOCATION_OFFLINE /* WinME */,
3689  "expected CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, got %08x\n",
3690  status.dwError);
3691  ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
3692  /* Specifying CERT_VERIFY_REV_CHAIN_FLAG doesn't change things either */
3693  SetLastError(0xdeadbeef);
3695  2, (void **)certs, CERT_VERIFY_REV_CHAIN_FLAG, &revPara, &status);
3697  "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
3699  "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
3700  ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
3701  /* Again, specifying the issuer cert: no change */
3702  revPara.pIssuerCert = certs[0];
3703  SetLastError(0xdeadbeef);
3705  1, (void **)&certs[1], 0, &revPara, &status);
3706  /* Win2k thinks the cert is revoked, and it is, except the CRL is out of
3707  * date, hence the revocation status should be unknown.
3708  */
3710  broken(GetLastError() == CRYPT_E_REVOKED /* Win2k */)),
3711  "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError());
3712  ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK ||
3713  broken(status.dwError == CRYPT_E_REVOKED /* Win2k */),
3714  "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError);
3715  ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex);
3716  CertCloseStore(revPara.hCrlStore, 0);
3717  CertFreeCertificateContext(certs[1]);
3718  CertFreeCertificateContext(certs[0]);
3719 }
3720 
3721 static BYTE privKey[] = {
3722  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
3723  0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
3724  0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
3725  0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
3726  0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
3727  0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
3728  0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
3729  0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
3730  0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
3731  0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
3732  0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
3733  0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
3734  0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
3735  0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
3736  0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
3737  0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
3738  0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
3739  0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
3740  0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
3741  0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
3742  0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
3743  0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
3744  0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
3745  0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
3746 
3747 static const BYTE exportedPublicKeyBlob[] = {
3748 0x06,0x02,0x00,0x00,0x00,0xa4,0x00,0x00,0x52,0x53,0x41,0x31,0x00,0x02,0x00,0x00,
3749 0x01,0x00,0x01,0x00,0x79,0x10,0x1c,0xd0,0x6b,0x10,0x18,0x30,0x94,0x61,0xdc,0x0e,
3750 0xcb,0x96,0x4e,0x21,0x3f,0x79,0xcd,0xa9,0x17,0x62,0xbc,0xbb,0x61,0x4c,0xe0,0x75,
3751 0x38,0x6c,0xf3,0xde,0x60,0x86,0x03,0x97,0x65,0xeb,0x1e,0x6b,0xdb,0x53,0x85,0xad,
3752 0x68,0x21,0xf1,0x5d,0xe7,0x1f,0xe6,0x53,0xb4,0xbb,0x59,0x3e,0x14,0x27,0xb1,0x83,
3753 0xa7,0x3a,0x54,0xe2 };
3754 
3755 static const BYTE asnEncodedPublicKey[] = {
3756 0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,
3757 0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,
3758 0x65,0x97,0x03,0x86,0x60,0xde,0xf3,0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,
3759 0x17,0xa9,0xcd,0x79,0x3f,0x21,0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,
3760 0x6b,0xd0,0x1c,0x10,0x79,0x02,0x03,0x01,0x00,0x01 };
3761 
3762 static void testAcquireCertPrivateKey(void)
3763 {
3764  BOOL ret;
3766  HCRYPTPROV csp;
3767  DWORD size, keySpec;
3768  BOOL callerFree;
3769  CRYPT_KEY_PROV_INFO keyProvInfo;
3770  HCRYPTKEY key;
3771  WCHAR ms_def_prov_w[