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