wined3d: Add the bulk of the GLSL string generation functions.
[wine] / dlls / crypt32 / tests / cert.c
1 /*
2  * crypt32 cert functions tests
3  *
4  * Copyright 2005-2006 Juan Lang
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <assert.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <windef.h>
25 #include <winbase.h>
26 #include <winreg.h>
27 #include <winerror.h>
28 #include <wincrypt.h>
29
30 #include "wine/test.h"
31
32 static BOOL (WINAPI * pCryptVerifyCertificateSignatureEx)
33                         (HCRYPTPROV, DWORD, DWORD, void *, DWORD, void *, DWORD, void *);
34
35 #define CRYPT_GET_PROC(func)                                       \
36     p ## func = (void *)GetProcAddress(hCrypt32, #func);           \
37     if(!p ## func)                                                 \
38         trace("GetProcAddress(hCrypt32, \"%s\") failed\n", #func); \
39
40 static void init_function_pointers(void)
41 {
42     HMODULE hCrypt32;
43
44     pCryptVerifyCertificateSignatureEx = NULL;
45
46     hCrypt32 = GetModuleHandleA("crypt32.dll");
47     assert(hCrypt32);
48
49     CRYPT_GET_PROC(CryptVerifyCertificateSignatureEx);
50 }
51
52 static void testCryptHashCert(void)
53 {
54     static const BYTE emptyHash[] = { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b,
55      0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07,
56      0x09 };
57     static const BYTE knownHash[] = { 0xae, 0x9d, 0xbf, 0x6d, 0xf5, 0x46, 0xee,
58      0x8b, 0xc5, 0x7a, 0x13, 0xba, 0xc2, 0xb1, 0x04, 0xf2, 0xbf, 0x52, 0xa8,
59      0xa2 };
60     static const BYTE toHash[] = "abcdefghijklmnopqrstuvwxyz0123456789.,;!?:";
61     BOOL ret;
62     BYTE hash[20];
63     DWORD hashLen = sizeof(hash);
64
65     /* NULL buffer and nonzero length crashes
66     ret = CryptHashCertificate(0, 0, 0, NULL, size, hash, &hashLen);
67        empty hash length also crashes
68     ret = CryptHashCertificate(0, 0, 0, buf, size, hash, NULL);
69      */
70     /* Test empty hash */
71     ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), NULL,
72      &hashLen);
73     ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError());
74     ok(hashLen == sizeof(hash),
75      "Got unexpected size of hash %ld, expected %d\n", hashLen, sizeof(hash));
76     /* Test with empty buffer */
77     ret = CryptHashCertificate(0, 0, 0, NULL, 0, hash, &hashLen);
78     ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError());
79     ok(!memcmp(hash, emptyHash, sizeof(emptyHash)),
80      "Unexpected hash of nothing\n");
81     /* Test a known value */
82     ret = CryptHashCertificate(0, 0, 0, toHash, sizeof(toHash), hash,
83      &hashLen);
84     ok(ret, "CryptHashCertificate failed: %08lx\n", GetLastError());
85     ok(!memcmp(hash, knownHash, sizeof(knownHash)), "Unexpected hash\n");
86 }
87
88 static const WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
89  'm','p',0 };
90
91 static void verifySig(HCRYPTPROV csp, const BYTE *toSign, size_t toSignLen,
92  const BYTE *sig, size_t sigLen)
93 {
94     HCRYPTHASH hash;
95     BOOL ret = CryptCreateHash(csp, CALG_SHA1, 0, 0, &hash);
96
97     ok(ret, "CryptCreateHash failed: %08lx\n", GetLastError());
98     if (ret)
99     {
100         BYTE mySig[64];
101         DWORD mySigSize = sizeof(mySig);
102
103         ret = CryptHashData(hash, toSign, toSignLen, 0);
104         ok(ret, "CryptHashData failed: %08lx\n", GetLastError());
105         /* use the A variant so the test can run on Win9x */
106         ret = CryptSignHashA(hash, AT_SIGNATURE, NULL, 0, mySig, &mySigSize);
107         ok(ret, "CryptSignHash failed: %08lx\n", GetLastError());
108         if (ret)
109         {
110             ok(mySigSize == sigLen, "Expected sig length %d, got %ld\n",
111              sigLen, mySigSize);
112             ok(!memcmp(mySig, sig, sigLen), "Unexpected signature\n");
113         }
114         CryptDestroyHash(hash);
115     }
116 }
117
118 /* Tests signing the certificate described by toBeSigned with the CSP passed in,
119  * using the algorithm with OID sigOID.  The CSP is assumed to be empty, and a
120  * keyset named AT_SIGNATURE will be added to it.  The signing key will be
121  * stored in *key, and the signature will be stored in sig.  sigLen should be
122  * at least 64 bytes.
123  */
124 static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
125  LPCSTR sigOID, HCRYPTKEY *key, BYTE *sig, DWORD *sigLen)
126 {
127     BOOL ret;
128     DWORD size = 0;
129     CRYPT_ALGORITHM_IDENTIFIER algoID = { NULL, { 0, NULL } };
130
131     /* These all crash
132     ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
133     ret = CryptSignCertificate(0, 0, 0, NULL, 0, NULL, NULL, NULL, &size);
134     ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
135      NULL, NULL, NULL, &size);
136      */
137     ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
138      &algoID, NULL, NULL, &size);
139     ok(!ret && GetLastError() == NTE_BAD_ALGID, 
140      "Expected NTE_BAD_ALGID, got %08lx\n", GetLastError());
141     algoID.pszObjId = (LPSTR)sigOID;
142     ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData,
143      &algoID, NULL, NULL, &size);
144     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
145      "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
146     ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData,
147      toBeSigned->cbData, &algoID, NULL, NULL, &size);
148     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
149      "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
150
151     /* No keys exist in the new CSP yet.. */
152     ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
153      toBeSigned->cbData, &algoID, NULL, NULL, &size);
154     ok(!ret && (GetLastError() == NTE_BAD_KEYSET || GetLastError() ==
155      NTE_NO_KEY), "Expected NTE_BAD_KEYSET or NTE_NO_KEY, got %08lx\n",
156      GetLastError());
157     ret = CryptGenKey(csp, AT_SIGNATURE, 0, key);
158     ok(ret, "CryptGenKey failed: %08lx\n", GetLastError());
159     if (ret)
160     {
161         ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
162          toBeSigned->cbData, &algoID, NULL, NULL, &size);
163         ok(ret, "CryptSignCertificate failed: %08lx\n", GetLastError());
164         ok(size <= *sigLen, "Expected size <= %ld, got %ld\n", *sigLen, size);
165         if (ret)
166         {
167             ret = CryptSignCertificate(csp, AT_SIGNATURE, 0, toBeSigned->pbData,
168              toBeSigned->cbData, &algoID, NULL, sig, &size);
169             ok(ret, "CryptSignCertificate failed: %08lx\n", GetLastError());
170             if (ret)
171             {
172                 *sigLen = size;
173                 verifySig(csp, toBeSigned->pbData, toBeSigned->cbData, sig,
174                  size);
175             }
176         }
177     }
178 }
179
180 static void testVerifyCertSig(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned,
181  LPCSTR sigOID, const BYTE *sig, DWORD sigLen)
182 {
183     CERT_SIGNED_CONTENT_INFO info;
184     LPBYTE cert = NULL;
185     DWORD size = 0;
186     BOOL ret;
187
188     if(pCryptVerifyCertificateSignatureEx) {
189         ret = pCryptVerifyCertificateSignatureEx(0, 0, 0, NULL, 0, NULL, 0, NULL);
190         ok(!ret && GetLastError() == E_INVALIDARG,
191          "Expected E_INVALIDARG, got %08lx\n", GetLastError());
192         ret = pCryptVerifyCertificateSignatureEx(csp, 0, 0, NULL, 0, NULL, 0, NULL);
193         ok(!ret && GetLastError() == E_INVALIDARG,
194          "Expected E_INVALIDARG, got %08lx\n", GetLastError());
195         ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING, 0, NULL, 0,
196          NULL, 0, NULL);
197         ok(!ret && GetLastError() == E_INVALIDARG,
198          "Expected E_INVALIDARG, got %08lx\n", GetLastError());
199         /* This crashes
200         ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
201          CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, NULL, 0, NULL, 0, NULL);
202          */
203     }
204     info.ToBeSigned.cbData = toBeSigned->cbData;
205     info.ToBeSigned.pbData = toBeSigned->pbData;
206     info.SignatureAlgorithm.pszObjId = (LPSTR)sigOID;
207     info.SignatureAlgorithm.Parameters.cbData = 0;
208     info.Signature.cbData = sigLen;
209     info.Signature.pbData = (BYTE *)sig;
210     info.Signature.cUnusedBits = 0;
211     ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_CERT, &info,
212      CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&cert, &size);
213     ok(ret, "CryptEncodeObjectEx failed: %08lx\n", GetLastError());
214     if (cert)
215     {
216         CRYPT_DATA_BLOB certBlob = { 0, NULL };
217         PCERT_PUBLIC_KEY_INFO pubKeyInfo = NULL;
218
219         if(pCryptVerifyCertificateSignatureEx) {
220             ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
221              CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
222             ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
223              "Expected CRYPT_E_ASN1_EOD, got %08lx\n", GetLastError());
224             certBlob.cbData = 1;
225             certBlob.pbData = (void *)0xdeadbeef;
226             ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
227              CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
228             ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
229              "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", GetLastError());
230             certBlob.cbData = size;
231             certBlob.pbData = cert;
232             ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
233              CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob, 0, NULL, 0, NULL);
234             ok(!ret && GetLastError() == E_INVALIDARG,
235              "Expected E_INVALIDARG, got %08lx\n", GetLastError());
236             ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
237              CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
238              CRYPT_VERIFY_CERT_SIGN_ISSUER_NULL, NULL, 0, NULL);
239             ok(!ret && GetLastError() == E_INVALIDARG,
240              "Expected E_INVALIDARG, got %08lx\n", GetLastError());
241             /* This crashes
242             ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
243              CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
244              CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, NULL, 0, NULL);
245              */
246         }
247         CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
248          (LPSTR)sigOID, 0, NULL, NULL, &size);
249         pubKeyInfo = HeapAlloc(GetProcessHeap(), 0, size);
250         if (pubKeyInfo)
251         {
252             ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
253              X509_ASN_ENCODING, (LPSTR)sigOID, 0, NULL, pubKeyInfo, &size);
254             ok(ret, "CryptExportKey failed: %08lx\n", GetLastError());
255             if (ret && pCryptVerifyCertificateSignatureEx)
256             {
257                 ret = pCryptVerifyCertificateSignatureEx(csp, X509_ASN_ENCODING,
258                  CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB, &certBlob,
259                  CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pubKeyInfo, 0, NULL);
260                 ok(ret, "CryptVerifyCertificateSignatureEx failed: %08lx\n",
261                  GetLastError());
262             }
263             HeapFree(GetProcessHeap(), 0, pubKeyInfo);
264         }
265         LocalFree(cert);
266     }
267 }
268
269 static const BYTE emptyCert[] = { 0x30, 0x00 };
270
271 static void testCertSigs(void)
272 {
273     HCRYPTPROV csp;
274     CRYPT_DATA_BLOB toBeSigned = { sizeof(emptyCert), (LPBYTE)emptyCert };
275     BOOL ret;
276     HCRYPTKEY key;
277     BYTE sig[64];
278     DWORD sigSize = sizeof(sig);
279
280     /* Just in case a previous run failed, delete this thing */
281     CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
282      CRYPT_DELETEKEYSET);
283     ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
284      CRYPT_NEWKEYSET);
285     ok(ret, "CryptAcquireContext failed: %08lx\n", GetLastError());
286
287     testSignCert(csp, &toBeSigned, szOID_RSA_SHA1RSA, &key, sig, &sigSize);
288     testVerifyCertSig(csp, &toBeSigned, szOID_RSA_SHA1RSA, sig, sigSize);
289
290     CryptDestroyKey(key);
291     CryptReleaseContext(csp, 0);
292     ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
293      CRYPT_DELETEKEYSET);
294 }
295
296 static const BYTE subjectName[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
297  0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
298  0x6e, 0x67, 0x00 };
299
300 static void testCreateSelfSignCert(void)
301 {
302     PCCERT_CONTEXT context;
303     CERT_NAME_BLOB name = { sizeof(subjectName), (LPBYTE)subjectName };
304     HCRYPTPROV csp;
305     BOOL ret;
306     HCRYPTKEY key;
307
308     /* This crashes:
309     context = CertCreateSelfSignCertificate(0, NULL, 0, NULL, NULL, NULL, NULL,
310      NULL);
311      * Calling this with no first parameter creates a new key container, which
312      * lasts beyond the test, so I don't test that.  Nb: the generated key
313      * name is a GUID.
314     context = CertCreateSelfSignCertificate(0, &name, 0, NULL, NULL, NULL, NULL,
315      NULL);
316      */
317
318     /* Acquire a CSP */
319     CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
320      CRYPT_DELETEKEYSET);
321     ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
322      CRYPT_NEWKEYSET);
323     ok(ret, "CryptAcquireContext failed: %08lx\n", GetLastError());
324
325     context = CertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
326      NULL, NULL);
327     ok(!context && GetLastError() == NTE_NO_KEY,
328      "Expected NTE_NO_KEY, got %08lx\n", GetLastError());
329     ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
330     ok(ret, "CryptGenKey failed: %08lx\n", GetLastError());
331     if (ret)
332     {
333         context = CertCreateSelfSignCertificate(csp, &name, 0, NULL, NULL, NULL,
334          NULL, NULL);
335         ok(context != NULL, "CertCreateSelfSignCertificate failed: %08lx\n",
336          GetLastError());
337         if (context)
338         {
339             DWORD size = 0;
340             PCRYPT_KEY_PROV_INFO info;
341
342             /* The context must have a key provider info property */
343             ret = CertGetCertificateContextProperty(context,
344              CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
345             ok(ret && size, "Expected non-zero key provider info\n");
346             if (size)
347             {
348                 info = HeapAlloc(GetProcessHeap(), 0, size);
349                 if (info)
350                 {
351                     ret = CertGetCertificateContextProperty(context,
352                      CERT_KEY_PROV_INFO_PROP_ID, info, &size);
353                     ok(ret, "CertGetCertificateContextProperty failed: %08lx\n",
354                      GetLastError());
355                     if (ret)
356                     {
357                         /* Sanity-check the key provider */
358                         ok(!lstrcmpW(info->pwszContainerName, cspNameW),
359                          "Unexpected key container\n");
360                         ok(!lstrcmpW(info->pwszProvName, MS_DEF_PROV_W),
361                          "Unexpected provider\n");
362                         ok(info->dwKeySpec == AT_SIGNATURE,
363                          "Expected AT_SIGNATURE, got %ld\n", info->dwKeySpec);
364                     }
365                     HeapFree(GetProcessHeap(), 0, info);
366                 }
367             }
368
369             CertFreeCertificateContext(context);
370         }
371
372         CryptDestroyKey(key);
373     }
374
375     CryptReleaseContext(csp, 0);
376     ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
377      CRYPT_DELETEKEYSET);
378 }
379
380 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
381  0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
382  0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
383  0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
384  0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
385  0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
386  0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
387  0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
388  0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
389  0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
390
391 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
392  szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
393
394 static const BYTE certWithUsage[] = { 0x30, 0x81, 0x93, 0x02, 0x01, 0x01, 0x30,
395  0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
396  0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00,
397  0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
398  0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
399  0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31,
400  0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61,
401  0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00,
402  0x03, 0x01, 0x00, 0xa3, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x1d,
403  0x25, 0x01, 0x01, 0xff, 0x04, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01,
404  0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
405  0x03, 0x02, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
406
407 static void testKeyUsage(void)
408 {
409     BOOL ret;
410     PCCERT_CONTEXT context;
411     DWORD size;
412
413     /* Test base cases */
414     ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, NULL);
415     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
416      "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
417     size = 1;
418     ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
419     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
420      "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
421     size = 0;
422     ret = CertGetEnhancedKeyUsage(NULL, 0, NULL, &size);
423     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
424      "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
425     /* These crash
426     ret = CertSetEnhancedKeyUsage(NULL, NULL);
427     usage.cUsageIdentifier = 0;
428     ret = CertSetEnhancedKeyUsage(NULL, &usage);
429      */
430     /* Test with a cert with no enhanced key usage extension */
431     context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
432      sizeof(bigCert));
433     ok(context != NULL, "CertCreateCertificateContext failed: %08lx\n",
434      GetLastError());
435     if (context)
436     {
437         static const char oid[] = "1.2.3.4";
438         BYTE buf[sizeof(CERT_ENHKEY_USAGE) + 2 * (sizeof(LPSTR) + sizeof(oid))];
439         PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
440
441         ret = CertGetEnhancedKeyUsage(context, 0, NULL, NULL);
442         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
443          "Expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
444         size = 1;
445         ret = CertGetEnhancedKeyUsage(context, 0, NULL, &size);
446         if (ret)
447         {
448             /* Windows 2000, ME, or later: even though it succeeded, we expect
449              * CRYPT_E_NOT_FOUND, which indicates there is no enhanced key
450              * usage set for this cert (which implies it's valid for all uses.)
451              */
452             ok(GetLastError() == CRYPT_E_NOT_FOUND,
453              "Expected CRYPT_E_NOT_FOUND, got %08lx\n", GetLastError());
454             ok(size == sizeof(CERT_ENHKEY_USAGE), "Expected size %d, got %ld\n",
455              sizeof(CERT_ENHKEY_USAGE), size);
456             ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
457             ok(ret, "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
458             ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %ld\n",
459              pUsage->cUsageIdentifier);
460         }
461         else
462         {
463             /* Windows NT, 95, or 98: it fails, and the last error is
464              * CRYPT_E_NOT_FOUND.
465              */
466             ok(GetLastError() == CRYPT_E_NOT_FOUND,
467              "Expected CRYPT_E_NOT_FOUND, got %08lx\n", GetLastError());
468         }
469         /* I can add a usage identifier when no key usage has been set */
470         ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
471         ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08lx\n",
472          GetLastError());
473         size = sizeof(buf);
474         ret = CertGetEnhancedKeyUsage(context,
475          CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
476         ok(ret && GetLastError() == 0,
477          "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
478         ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %ld\n",
479          pUsage->cUsageIdentifier);
480         if (pUsage->cUsageIdentifier)
481             ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
482              "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
483         /* Now set an empty key usage */
484         pUsage->cUsageIdentifier = 0;
485         ret = CertSetEnhancedKeyUsage(context, pUsage);
486         ok(ret, "CertSetEnhancedKeyUsage failed: %08lx\n", GetLastError());
487         /* Shouldn't find it in the cert */
488         size = sizeof(buf);
489         ret = CertGetEnhancedKeyUsage(context,
490          CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
491         ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
492          "Expected CRYPT_E_NOT_FOUND, got %08lx\n", GetLastError());
493         /* Should find it as an extended property */
494         ret = CertGetEnhancedKeyUsage(context,
495          CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
496         ok(ret && GetLastError() == 0,
497          "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
498         ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %ld\n",
499          pUsage->cUsageIdentifier);
500         /* Should find it as either */
501         ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
502         ok(ret && GetLastError() == 0,
503          "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
504         ok(pUsage->cUsageIdentifier == 0, "Expected 0 usages, got %ld\n",
505          pUsage->cUsageIdentifier);
506         /* Add a usage identifier */
507         ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
508         ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08lx\n",
509          GetLastError());
510         size = sizeof(buf);
511         ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
512         ok(ret && GetLastError() == 0,
513          "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
514         ok(pUsage->cUsageIdentifier == 1, "Expected 1 identifier, got %ld\n",
515          pUsage->cUsageIdentifier);
516         if (pUsage->cUsageIdentifier)
517             ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
518              "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
519         /* Yep, I can re-add the same usage identifier */
520         ret = CertAddEnhancedKeyUsageIdentifier(context, oid);
521         ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08lx\n",
522          GetLastError());
523         size = sizeof(buf);
524         ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
525         ok(ret && GetLastError() == 0,
526          "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
527         ok(pUsage->cUsageIdentifier == 2, "Expected 2 identifiers, got %ld\n",
528          pUsage->cUsageIdentifier);
529         if (pUsage->cUsageIdentifier)
530             ok(!strcmp(pUsage->rgpszUsageIdentifier[0], oid),
531              "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[0]);
532         if (pUsage->cUsageIdentifier >= 2)
533             ok(!strcmp(pUsage->rgpszUsageIdentifier[1], oid),
534              "Expected %s, got %s\n", oid, pUsage->rgpszUsageIdentifier[1]);
535         /* Now set a NULL extended property--this deletes the property. */
536         ret = CertSetEnhancedKeyUsage(context, NULL);
537         ok(ret, "CertSetEnhancedKeyUsage failed: %08lx\n", GetLastError());
538         SetLastError(0xbaadcafe);
539         size = sizeof(buf);
540         ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
541         ok(GetLastError() == CRYPT_E_NOT_FOUND,
542          "Expected CRYPT_E_NOT_FOUND, got %08lx\n", GetLastError());
543
544         CertFreeCertificateContext(context);
545     }
546     /* Now test with a cert with an enhanced key usage extension */
547     context = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage,
548      sizeof(certWithUsage));
549     ok(context != NULL, "CertCreateCertificateContext failed: %08lx\n",
550      GetLastError());
551     if (context)
552     {
553         LPBYTE buf = NULL;
554         DWORD bufSize = 0, i;
555
556         /* The size may depend on what flags are used to query it, so I
557          * realloc the buffer for each test.
558          */
559         ret = CertGetEnhancedKeyUsage(context,
560          CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
561         ok(ret, "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
562         buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
563         if (buf)
564         {
565             PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
566
567             /* Should find it in the cert */
568             size = bufSize;
569             ret = CertGetEnhancedKeyUsage(context,
570              CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
571             ok(ret && GetLastError() == 0,
572              "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
573             ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %ld\n",
574              pUsage->cUsageIdentifier);
575             for (i = 0; i < pUsage->cUsageIdentifier; i++)
576                 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
577                  "Expected %s, got %s\n", keyUsages[i],
578                  pUsage->rgpszUsageIdentifier[i]);
579             HeapFree(GetProcessHeap(), 0, buf);
580         }
581         ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
582         ok(ret, "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
583         buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
584         if (buf)
585         {
586             PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
587
588             /* Should find it as either */
589             size = bufSize;
590             ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
591             /* In Windows, GetLastError returns CRYPT_E_NOT_FOUND not found
592              * here, even though the return is successful and the usage id
593              * count is positive.  I don't enforce that here.
594              */
595             ok(ret,
596              "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
597             ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %ld\n",
598              pUsage->cUsageIdentifier);
599             for (i = 0; i < pUsage->cUsageIdentifier; i++)
600                 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
601                  "Expected %s, got %s\n", keyUsages[i],
602                  pUsage->rgpszUsageIdentifier[i]);
603             HeapFree(GetProcessHeap(), 0, buf);
604         }
605         /* Shouldn't find it as an extended property */
606         ret = CertGetEnhancedKeyUsage(context,
607          CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &size);
608         ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
609          "Expected CRYPT_E_NOT_FOUND, got %08lx\n", GetLastError());
610         /* Adding a usage identifier overrides the cert's usage!? */
611         ret = CertAddEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
612         ok(ret, "CertAddEnhancedKeyUsageIdentifier failed: %08lx\n",
613          GetLastError());
614         ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
615         ok(ret, "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
616         buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
617         if (buf)
618         {
619             PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
620
621             /* Should find it as either */
622             size = bufSize;
623             ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
624             ok(ret,
625              "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
626             ok(pUsage->cUsageIdentifier == 1, "Expected 1 usage, got %ld\n",
627              pUsage->cUsageIdentifier);
628             ok(!strcmp(pUsage->rgpszUsageIdentifier[0], szOID_RSA_RSA),
629              "Expected %s, got %s\n", szOID_RSA_RSA,
630              pUsage->rgpszUsageIdentifier[0]);
631             HeapFree(GetProcessHeap(), 0, buf);
632         }
633         /* But querying the cert directly returns its usage */
634         ret = CertGetEnhancedKeyUsage(context,
635          CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &bufSize);
636         ok(ret, "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
637         buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
638         if (buf)
639         {
640             PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
641
642             size = bufSize;
643             ret = CertGetEnhancedKeyUsage(context,
644              CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &size);
645             ok(ret,
646              "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
647             ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %ld\n",
648              pUsage->cUsageIdentifier);
649             for (i = 0; i < pUsage->cUsageIdentifier; i++)
650                 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
651                  "Expected %s, got %s\n", keyUsages[i],
652                  pUsage->rgpszUsageIdentifier[i]);
653             HeapFree(GetProcessHeap(), 0, buf);
654         }
655         /* And removing the only usage identifier in the extended property
656          * results in the cert's key usage being found.
657          */
658         ret = CertRemoveEnhancedKeyUsageIdentifier(context, szOID_RSA_RSA);
659         ok(ret, "CertRemoveEnhancedKeyUsage failed: %08lx\n", GetLastError());
660         ret = CertGetEnhancedKeyUsage(context, 0, NULL, &bufSize);
661         ok(ret, "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
662         buf = HeapAlloc(GetProcessHeap(), 0, bufSize);
663         if (buf)
664         {
665             PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE)buf;
666
667             /* Should find it as either */
668             size = bufSize;
669             ret = CertGetEnhancedKeyUsage(context, 0, pUsage, &size);
670             ok(ret,
671              "CertGetEnhancedKeyUsage failed: %08lx\n", GetLastError());
672             ok(pUsage->cUsageIdentifier == 3, "Expected 3 usages, got %ld\n",
673              pUsage->cUsageIdentifier);
674             for (i = 0; i < pUsage->cUsageIdentifier; i++)
675                 ok(!strcmp(pUsage->rgpszUsageIdentifier[i], keyUsages[i]),
676                  "Expected %s, got %s\n", keyUsages[i],
677                  pUsage->rgpszUsageIdentifier[i]);
678             HeapFree(GetProcessHeap(), 0, buf);
679         }
680
681         CertFreeCertificateContext(context);
682     }
683 }
684
685 static void testCompareCertName(void)
686 {
687     static const BYTE bogus[] = { 1, 2, 3, 4 };
688     static const BYTE bogusPrime[] = { 0, 1, 2, 3, 4 };
689     static const BYTE emptyPrime[] = { 0x30, 0x00, 0x01 };
690     BOOL ret;
691     CERT_NAME_BLOB blob1, blob2;
692
693     /* crashes
694     ret = CertCompareCertificateName(0, NULL, NULL);
695      */
696     /* An empty name checks against itself.. */
697     blob1.pbData = (LPBYTE)emptyCert;
698     blob1.cbData = sizeof(emptyCert);
699     ret = CertCompareCertificateName(0, &blob1, &blob1);
700     ok(ret, "CertCompareCertificateName failed: %08lx\n", GetLastError());
701     /* It doesn't have to be a valid encoded name.. */
702     blob1.pbData = (LPBYTE)bogus;
703     blob1.cbData = sizeof(bogus);
704     ret = CertCompareCertificateName(0, &blob1, &blob1);
705     ok(ret, "CertCompareCertificateName failed: %08lx\n", GetLastError());
706     /* Leading zeroes matter.. */
707     blob2.pbData = (LPBYTE)bogusPrime;
708     blob2.cbData = sizeof(bogusPrime);
709     ret = CertCompareCertificateName(0, &blob1, &blob2);
710     ok(!ret, "Expected failure\n");
711     /* As do trailing extra bytes. */
712     blob2.pbData = (LPBYTE)emptyPrime;
713     blob2.cbData = sizeof(emptyPrime);
714     ret = CertCompareCertificateName(0, &blob1, &blob2);
715     ok(!ret, "Expected failure\n");
716 }
717
718 static const BYTE int1[] = { 0x88, 0xff, 0xff, 0xff };
719 static const BYTE int2[] = { 0x88, 0xff };
720 static const BYTE int3[] = { 0x23, 0xff };
721 static const BYTE int4[] = { 0x7f, 0x00 };
722 static const BYTE int5[] = { 0x7f };
723 static const BYTE int6[] = { 0x80, 0x00, 0x00, 0x00 };
724 static const BYTE int7[] = { 0x80, 0x00 };
725
726 struct IntBlobTest
727 {
728     CRYPT_INTEGER_BLOB blob1;
729     CRYPT_INTEGER_BLOB blob2;
730     BOOL areEqual;
731 } intBlobs[] = {
732  { { sizeof(int1), (LPBYTE)int1 }, { sizeof(int2), (LPBYTE)int2 }, TRUE },
733  { { sizeof(int3), (LPBYTE)int3 }, { sizeof(int3), (LPBYTE)int3 }, TRUE },
734  { { sizeof(int4), (LPBYTE)int4 }, { sizeof(int5), (LPBYTE)int5 }, TRUE },
735  { { sizeof(int6), (LPBYTE)int6 }, { sizeof(int7), (LPBYTE)int7 }, TRUE },
736  { { sizeof(int1), (LPBYTE)int1 }, { sizeof(int7), (LPBYTE)int7 }, FALSE },
737 };
738
739 static void testCompareIntegerBlob(void)
740 {
741     DWORD i;
742     BOOL ret;
743
744     for (i = 0; i < sizeof(intBlobs) / sizeof(intBlobs[0]); i++)
745     {
746         ret = CertCompareIntegerBlob(&intBlobs[i].blob1, &intBlobs[i].blob2);
747         ok(ret == intBlobs[i].areEqual,
748          "%ld: expected blobs %s compare\n", i, intBlobs[i].areEqual ?
749          "to" : "not to");
750     }
751 }
752
753 static void testComparePublicKeyInfo(void)
754 {
755     BOOL ret;
756     CERT_PUBLIC_KEY_INFO info1 = { { 0 } }, info2 = { { 0 } };
757     static CHAR oid_rsa_rsa[]     = szOID_RSA_RSA;
758     static CHAR oid_rsa_sha1rsa[] = szOID_RSA_SHA1RSA;
759     static CHAR oid_x957_dsa[]    = szOID_X957_DSA;
760     static const BYTE bits1[] = { 1, 0 };
761     static const BYTE bits2[] = { 0 };
762     static const BYTE bits3[] = { 1 };
763
764     /* crashes
765     ret = CertComparePublicKeyInfo(0, NULL, NULL);
766      */
767     /* Empty public keys compare */
768     ret = CertComparePublicKeyInfo(0, &info1, &info2);
769     ok(ret, "CertComparePublicKeyInfo failed: %08lx\n", GetLastError());
770     /* Different OIDs appear to compare */
771     info1.Algorithm.pszObjId = oid_rsa_rsa;
772     info2.Algorithm.pszObjId = oid_rsa_sha1rsa;
773     ret = CertComparePublicKeyInfo(0, &info1, &info2);
774     ok(ret, "CertComparePublicKeyInfo failed: %08lx\n", GetLastError());
775     info2.Algorithm.pszObjId = oid_x957_dsa;
776     ret = CertComparePublicKeyInfo(0, &info1, &info2);
777     ok(ret, "CertComparePublicKeyInfo failed: %08lx\n", GetLastError());
778     info1.PublicKey.cbData = sizeof(bits1);
779     info1.PublicKey.pbData = (LPBYTE)bits1;
780     info1.PublicKey.cUnusedBits = 0;
781     info2.PublicKey.cbData = sizeof(bits1);
782     info2.PublicKey.pbData = (LPBYTE)bits1;
783     info2.PublicKey.cUnusedBits = 0;
784     ret = CertComparePublicKeyInfo(0, &info1, &info2);
785     ok(ret, "CertComparePublicKeyInfo failed: %08lx\n", GetLastError());
786     /* Even though they compare in their used bits, these do not compare */
787     info1.PublicKey.cbData = sizeof(bits2);
788     info1.PublicKey.pbData = (LPBYTE)bits2;
789     info1.PublicKey.cUnusedBits = 0;
790     info2.PublicKey.cbData = sizeof(bits3);
791     info2.PublicKey.pbData = (LPBYTE)bits3;
792     info2.PublicKey.cUnusedBits = 1;
793     ret = CertComparePublicKeyInfo(0, &info1, &info2);
794     /* Simple (non-comparing) case */
795     ok(!ret, "Expected keys not to compare\n");
796     info2.PublicKey.cbData = sizeof(bits1);
797     info2.PublicKey.pbData = (LPBYTE)bits1;
798     info2.PublicKey.cUnusedBits = 0;
799     ret = CertComparePublicKeyInfo(0, &info1, &info2);
800     ok(!ret, "Expected keys not to compare\n");
801 }
802
803 static const BYTE subjectName2[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
804  0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c, 0x65, 0x78, 0x20, 0x4c, 0x61,
805  0x6e, 0x67, 0x00 };
806
807 static const BYTE serialNum[] = { 1 };
808
809 void testCompareCert(void)
810 {
811     CERT_INFO info1 = { 0 }, info2 = { 0 };
812     BOOL ret;
813
814     /* Crashes
815     ret = CertCompareCertificate(X509_ASN_ENCODING, NULL, NULL);
816      */
817
818     /* Certs with the same issuer and serial number are equal, even if they
819      * differ in other respects (like subject).
820      */
821     info1.SerialNumber.pbData = (LPBYTE)serialNum;
822     info1.SerialNumber.cbData = sizeof(serialNum);
823     info1.Issuer.pbData = (LPBYTE)subjectName;
824     info1.Issuer.cbData = sizeof(subjectName);
825     info1.Subject.pbData = (LPBYTE)subjectName2;
826     info1.Subject.cbData = sizeof(subjectName2);
827     info2.SerialNumber.pbData = (LPBYTE)serialNum;
828     info2.SerialNumber.cbData = sizeof(serialNum);
829     info2.Issuer.pbData = (LPBYTE)subjectName;
830     info2.Issuer.cbData = sizeof(subjectName);
831     info2.Subject.pbData = (LPBYTE)subjectName;
832     info2.Subject.cbData = sizeof(subjectName);
833     ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
834     ok(ret, "Expected certs to be equal\n");
835
836     info2.Issuer.pbData = (LPBYTE)subjectName2;
837     info2.Issuer.cbData = sizeof(subjectName2);
838     ret = CertCompareCertificate(X509_ASN_ENCODING, &info1, &info2);
839     ok(!ret, "Expected certs not to be equal\n");
840 }
841
842 static const BYTE bigCertWithDifferentSubject[] = { 0x30, 0x7a, 0x02, 0x01, 0x02,
843  0x30, 0x02, 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
844  0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67,
845  0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31,
846  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
847  0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15,
848  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x41, 0x6c,
849  0x65, 0x78, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06,
850  0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55,
851  0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02,
852  0x01, 0x01 };
853
854 static void testVerifySubjectCert(void)
855 {
856     BOOL ret;
857     DWORD flags;
858     PCCERT_CONTEXT context1, context2;
859
860     /* Crashes
861     ret = CertVerifySubjectCertificateContext(NULL, NULL, NULL);
862      */
863     flags = 0;
864     ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
865     ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
866      GetLastError());
867     flags = CERT_STORE_NO_CRL_FLAG;
868     ret = CertVerifySubjectCertificateContext(NULL, NULL, &flags);
869     ok(!ret && GetLastError() == E_INVALIDARG,
870      "Expected E_INVALIDARG, got %08lx\n", GetLastError());
871
872     flags = 0;
873     context1 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
874      sizeof(bigCert));
875     ret = CertVerifySubjectCertificateContext(NULL, context1, &flags);
876     ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
877      GetLastError());
878     ret = CertVerifySubjectCertificateContext(context1, NULL, &flags);
879     ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
880      GetLastError());
881     ret = CertVerifySubjectCertificateContext(context1, context1, &flags);
882     ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
883      GetLastError());
884
885     context2 = CertCreateCertificateContext(X509_ASN_ENCODING,
886      bigCertWithDifferentSubject, sizeof(bigCertWithDifferentSubject));
887     SetLastError(0xdeadbeef);
888     ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
889     ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
890      GetLastError());
891     flags = CERT_STORE_REVOCATION_FLAG;
892     ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
893     ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
894      GetLastError());
895     ok(flags == (CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG),
896      "Expected CERT_STORE_REVOCATION_FLAG | CERT_STORE_NO_CRL_FLAG, got %08lx\n",
897      flags);
898     flags = CERT_STORE_SIGNATURE_FLAG;
899     ret = CertVerifySubjectCertificateContext(context1, context2, &flags);
900     ok(ret, "CertVerifySubjectCertificateContext failed; %08lx\n",
901      GetLastError());
902     ok(flags == CERT_STORE_SIGNATURE_FLAG,
903      "Expected CERT_STORE_SIGNATURE_FLAG, got %08lx\n", flags);
904     CertFreeCertificateContext(context2);
905
906     CertFreeCertificateContext(context1);
907 }
908
909 START_TEST(cert)
910 {
911     init_function_pointers();
912     testCryptHashCert();
913     testCertSigs();
914     testCreateSelfSignCert();
915     testKeyUsage();
916     testCompareCertName();
917     testCompareIntegerBlob();
918     testComparePublicKeyInfo();
919     testCompareCert();
920     testVerifySubjectCert();
921 }