quartz: Fix discontinuities in wave parser.
[wine] / dlls / secur32 / tests / schannel.c
1 /*
2  * Schannel tests
3  *
4  * Copyright 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 #include <stdio.h>
21 #include <stdarg.h>
22 #include <windef.h>
23 #include <winbase.h>
24 #define SECURITY_WIN32
25 #include <security.h>
26 #include <schannel.h>
27
28 #include "wine/test.h"
29
30 static HMODULE secdll, crypt32dll;
31
32 static ACQUIRE_CREDENTIALS_HANDLE_FN_A pAcquireCredentialsHandleA;
33 static FREE_CREDENTIALS_HANDLE_FN pFreeCredentialsHandle;
34 static QUERY_CREDENTIALS_ATTRIBUTES_FN_A pQueryCredentialsAttributesA;
35
36 static PCCERT_CONTEXT (WINAPI *pCertCreateCertificateContext)(DWORD,const BYTE*,DWORD);
37 static BOOL (WINAPI *pCertFreeCertificateContext)(PCCERT_CONTEXT);
38 static BOOL (WINAPI *pCertSetCertificateContextProperty)(PCCERT_CONTEXT,DWORD,DWORD,const void*);
39
40 static BOOL (WINAPI *pCryptAcquireContextW)(HCRYPTPROV*, LPCWSTR, LPCWSTR, DWORD, DWORD);
41 static BOOL (WINAPI *pCryptDestroyKey)(HCRYPTKEY);
42 static BOOL (WINAPI *pCryptImportKey)(HCRYPTPROV,CONST BYTE*,DWORD,HCRYPTKEY,DWORD,HCRYPTKEY*);
43 static BOOL (WINAPI *pCryptReleaseContext)(HCRYPTPROV,ULONG_PTR);
44
45 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
46  0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
47  0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
48  0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
49  0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
50  0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
51  0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
52  0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
53  0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
54  0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
55 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
56  'm','p',0 };
57 static BYTE privKey[] = {
58  0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
59  0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
60  0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
61  0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
62  0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
63  0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
64  0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
65  0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
66  0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
67  0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
68  0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
69  0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
70  0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
71  0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
72  0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
73  0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
74  0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
75  0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
76  0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
77  0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
78  0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
79  0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
80  0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
81  0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
82
83 static const BYTE selfSignedCert[] = {
84  0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
85  0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
86  0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
87  0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
88  0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
89  0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
90  0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
91  0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
92  0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
93  0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
94  0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
95  0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
96  0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
97  0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
98  0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
99  0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
100  0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
101  0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
102  0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
103  0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
104  0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
105  0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
106  0xa8, 0x76, 0x57, 0x92, 0x36 };
107
108 static void InitFunctionPtrs(void)
109 {
110     HMODULE advapi32dll;
111
112     crypt32dll = LoadLibraryA("crypt32.dll");
113     secdll = LoadLibraryA("secur32.dll");
114     if(!secdll)
115         secdll = LoadLibraryA("security.dll");
116     advapi32dll = GetModuleHandleA("advapi32.dll");
117
118 #define GET_PROC(h, func)  p ## func = (void*)GetProcAddress(h, #func)
119
120     if(secdll)
121     {
122         GET_PROC(secdll, AcquireCredentialsHandleA);
123         GET_PROC(secdll, FreeCredentialsHandle);
124         GET_PROC(secdll, QueryCredentialsAttributesA);
125     }
126
127     GET_PROC(advapi32dll, CryptAcquireContextW);
128     GET_PROC(advapi32dll, CryptDestroyKey);
129     GET_PROC(advapi32dll, CryptImportKey);
130     GET_PROC(advapi32dll, CryptReleaseContext);
131
132     GET_PROC(crypt32dll, CertFreeCertificateContext);
133     GET_PROC(crypt32dll, CertSetCertificateContextProperty);
134     GET_PROC(crypt32dll, CertCreateCertificateContext);
135
136 #undef GET_PROC
137 }
138
139 static void test_strength(PCredHandle handle)
140 {
141     SecPkgCred_CipherStrengths strength = {-1,-1};
142     SECURITY_STATUS st;
143
144     st = pQueryCredentialsAttributesA(handle, SECPKG_ATTR_CIPHER_STRENGTHS, &strength);
145     ok(st == SEC_E_OK, "QueryCredentialsAttributesA failed: %u\n", GetLastError());
146     ok(strength.dwMinimumCipherStrength, "dwMinimumCipherStrength not changed\n");
147     ok(strength.dwMaximumCipherStrength, "dwMaximumCipherStrength not changed\n");
148     trace("strength %d - %d\n", strength.dwMinimumCipherStrength, strength.dwMaximumCipherStrength);
149 }
150
151 static void testAcquireSecurityContext(void)
152 {
153     SECURITY_STATUS st;
154     CredHandle cred;
155     TimeStamp exp;
156     SCHANNEL_CRED schanCred;
157     PCCERT_CONTEXT certs[2];
158     HCRYPTPROV csp;
159     static CHAR unisp_name_a[] = UNISP_NAME_A;
160     WCHAR ms_def_prov_w[MAX_PATH];
161     BOOL ret;
162     HCRYPTKEY key;
163     CRYPT_KEY_PROV_INFO keyProvInfo;
164
165     if (!pAcquireCredentialsHandleA || !pCertCreateCertificateContext ||
166         !pFreeCredentialsHandle || !pCryptAcquireContextW)
167     {
168         skip("Needed functions are not available\n");
169         return;
170     }
171
172     lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
173
174     keyProvInfo.pwszContainerName = cspNameW;
175     keyProvInfo.pwszProvName = ms_def_prov_w;
176     keyProvInfo.dwProvType = PROV_RSA_FULL;
177     keyProvInfo.dwFlags = 0;
178     keyProvInfo.cProvParam = 0;
179     keyProvInfo.rgProvParam = NULL;
180     keyProvInfo.dwKeySpec = AT_SIGNATURE;
181
182     certs[0] = pCertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
183      sizeof(bigCert));
184     certs[1] = pCertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
185      sizeof(selfSignedCert));
186
187     pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
188      CRYPT_DELETEKEYSET);
189
190     st = pAcquireCredentialsHandleA(NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL,
191      NULL);
192     ok(st == SEC_E_SECPKG_NOT_FOUND,
193      "Expected SEC_E_SECPKG_NOT_FOUND, got %08x\n", st);
194     if (0)
195     {
196         /* Crashes on Win2K */
197         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, 0, NULL, NULL, NULL,
198          NULL, NULL, NULL);
199         ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n",
200          st);
201     }
202     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_BOTH, NULL,
203      NULL, NULL, NULL, NULL, NULL);
204     ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n",
205      st);
206     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
207      NULL, NULL, NULL, NULL, NULL, NULL);
208     ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n",
209      st);
210     if (0)
211     {
212         /* Crashes */
213         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
214          NULL, NULL, NULL, NULL, NULL, NULL);
215     }
216     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
217      NULL, NULL, NULL, NULL, &cred, NULL);
218     ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
219     pFreeCredentialsHandle(&cred);
220     memset(&cred, 0, sizeof(cred));
221     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
222      NULL, NULL, NULL, NULL, &cred, &exp);
223     ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
224     ok(exp.HighPart == 0 && exp.LowPart == 0,
225      "Expected 0 expiry, got %08lx%08lx\n", exp.HighPart, exp.LowPart);
226     pFreeCredentialsHandle(&cred);
227
228     /* Bad version in SCHANNEL_CRED */
229     memset(&schanCred, 0, sizeof(schanCred));
230     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
231      NULL, &schanCred, NULL, NULL, NULL, NULL);
232     ok(st == SEC_E_INTERNAL_ERROR, "Expected SEC_E_INTERNAL_ERROR, got %08x\n",
233      st);
234     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
235      NULL, &schanCred, NULL, NULL, NULL, NULL);
236     ok(st == SEC_E_INTERNAL_ERROR, "Expected SEC_E_INTERNAL_ERROR, got %08x\n",
237      st);
238
239     /* No cert in SCHANNEL_CRED succeeds for outbound.. */
240     schanCred.dwVersion = SCHANNEL_CRED_VERSION;
241     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
242      NULL, &schanCred, NULL, NULL, &cred, NULL);
243     ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
244     pFreeCredentialsHandle(&cred);
245     /* but fails for inbound. */
246     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
247      NULL, &schanCred, NULL, NULL, NULL, NULL);
248     ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n",
249      st);
250
251     if (0)
252     {
253         /* Crashes with bad paCred pointer */
254         schanCred.cCreds = 1;
255         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
256          NULL, &schanCred, NULL, NULL, NULL, NULL);
257     }
258
259     /* Bogus cert in SCHANNEL_CRED. Windows fails with
260      * SEC_E_UNKNOWN_CREDENTIALS, but I'll accept SEC_E_NO_CREDENTIALS too.
261      */
262     schanCred.cCreds = 1;
263     schanCred.paCred = &certs[0];
264     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
265      NULL, &schanCred, NULL, NULL, NULL, NULL);
266     ok(st == SEC_E_UNKNOWN_CREDENTIALS || SEC_E_NO_CREDENTIALS,
267      "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_NO_CREDENTIALS, got %08x\n",
268      st);
269     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
270      NULL, &schanCred, NULL, NULL, NULL, NULL);
271     ok(st == SEC_E_UNKNOWN_CREDENTIALS || SEC_E_NO_CREDENTIALS,
272      "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_NO_CREDENTIALS, got %08x\n",
273      st);
274
275     /* Good cert, but missing private key. Windows fails with
276      * SEC_E_NO_CREDENTIALS, but I'll accept SEC_E_UNKNOWN_CREDENTIALS too.
277      */
278     schanCred.cCreds = 1;
279     schanCred.paCred = &certs[1];
280     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
281      NULL, &schanCred, NULL, NULL, &cred, NULL);
282     ok(st == SEC_E_UNKNOWN_CREDENTIALS || SEC_E_NO_CREDENTIALS,
283      "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_NO_CREDENTIALS, got %08x\n",
284      st);
285     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
286      NULL, &schanCred, NULL, NULL, NULL, NULL);
287     ok(st == SEC_E_UNKNOWN_CREDENTIALS || SEC_E_NO_CREDENTIALS,
288      "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_NO_CREDENTIALS, got %08x\n",
289      st);
290
291     /* Good cert, with CRYPT_KEY_PROV_INFO set before it's had a key loaded. */
292     if (pCertSetCertificateContextProperty)
293     {
294         ret = pCertSetCertificateContextProperty(certs[1],
295               CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo);
296         schanCred.dwVersion = SCH_CRED_V3;
297         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
298              NULL, &schanCred, NULL, NULL, &cred, NULL);
299         ok(st == SEC_E_UNKNOWN_CREDENTIALS,
300            "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
301         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
302              NULL, &schanCred, NULL, NULL, &cred, NULL);
303         ok(st == SEC_E_UNKNOWN_CREDENTIALS,
304            "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
305     }
306
307     ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
308      CRYPT_NEWKEYSET);
309     ok(ret, "CryptAcquireContextW failed: %08x\n", GetLastError());
310     ret = 0;
311     if (pCryptImportKey)
312     {
313         ret = pCryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
314         ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
315     }
316     if (ret)
317     {
318         PCCERT_CONTEXT tmp;
319
320         if (0)
321         {
322             /* Crashes */
323             st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
324              NULL, &schanCred, NULL, NULL, NULL, NULL);
325         }
326         /* Good cert with private key, bogus version */
327         schanCred.dwVersion = SCH_CRED_V1;
328         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
329          NULL, &schanCred, NULL, NULL, &cred, NULL);
330         ok(st == SEC_E_INTERNAL_ERROR,
331          "Expected SEC_E_INTERNAL_ERROR, got %08x\n", st);
332         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
333          NULL, &schanCred, NULL, NULL, &cred, NULL);
334         ok(st == SEC_E_INTERNAL_ERROR,
335          "Expected SEC_E_INTERNAL_ERROR, got %08x\n", st);
336         schanCred.dwVersion = SCH_CRED_V2;
337         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
338          NULL, &schanCred, NULL, NULL, &cred, NULL);
339         ok(st == SEC_E_INTERNAL_ERROR,
340          "Expected SEC_E_INTERNAL_ERROR, got %08x\n", st);
341         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
342          NULL, &schanCred, NULL, NULL, &cred, NULL);
343         ok(st == SEC_E_INTERNAL_ERROR,
344          "Expected SEC_E_INTERNAL_ERROR, got %08x\n", st);
345
346         /* Succeeds on V3 or higher */
347         schanCred.dwVersion = SCH_CRED_V3;
348         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
349          NULL, &schanCred, NULL, NULL, &cred, NULL);
350         ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
351         pFreeCredentialsHandle(&cred);
352         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
353          NULL, &schanCred, NULL, NULL, &cred, NULL);
354         ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
355         pFreeCredentialsHandle(&cred);
356         schanCred.dwVersion = SCHANNEL_CRED_VERSION;
357         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
358          NULL, &schanCred, NULL, NULL, &cred, NULL);
359         ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
360         pFreeCredentialsHandle(&cred);
361         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
362          NULL, &schanCred, NULL, NULL, &cred, NULL);
363         ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
364         test_strength(&cred);
365         pFreeCredentialsHandle(&cred);
366
367         /* How about more than one cert? */
368         schanCred.cCreds = 2;
369         schanCred.paCred = certs;
370         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
371          NULL, &schanCred, NULL, NULL, &cred, NULL);
372         ok(st == SEC_E_UNKNOWN_CREDENTIALS,
373          "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
374         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
375          NULL, &schanCred, NULL, NULL, &cred, NULL);
376         ok(st == SEC_E_UNKNOWN_CREDENTIALS,
377          "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
378         tmp = certs[0];
379         certs[0] = certs[1];
380         certs[1] = tmp;
381         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
382          NULL, &schanCred, NULL, NULL, &cred, NULL);
383         ok(st == SEC_E_UNKNOWN_CREDENTIALS,
384          "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
385         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
386          NULL, &schanCred, NULL, NULL, &cred, NULL);
387         ok(st == SEC_E_UNKNOWN_CREDENTIALS,
388          "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
389         /* FIXME: what about two valid certs? */
390
391         if (pCryptDestroyKey)
392             pCryptDestroyKey(key);
393     }
394
395     if (pCryptReleaseContext)
396         pCryptReleaseContext(csp, 0);
397     pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
398      CRYPT_DELETEKEYSET);
399
400     if (pCertFreeCertificateContext)
401     {
402         pCertFreeCertificateContext(certs[0]);
403         pCertFreeCertificateContext(certs[1]);
404     }
405 }
406
407 START_TEST(schannel)
408 {
409     InitFunctionPtrs();
410
411     testAcquireSecurityContext();
412
413     if(secdll)
414         FreeLibrary(secdll);
415     if(crypt32dll)
416         FreeLibrary(crypt32dll);
417 }