mshtml: Add tests for get_scrollLeft.
[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     if(st == SEC_E_OK)
220         pFreeCredentialsHandle(&cred);
221     memset(&cred, 0, sizeof(cred));
222     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
223      NULL, NULL, NULL, NULL, &cred, &exp);
224     ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
225     /* expriy is indeterminate in win2k3 */
226     trace("expiry: %08lx%08lx\n", exp.HighPart, exp.LowPart);
227     pFreeCredentialsHandle(&cred);
228
229     /* Bad version in SCHANNEL_CRED */
230     memset(&schanCred, 0, sizeof(schanCred));
231     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
232      NULL, &schanCred, NULL, NULL, NULL, NULL);
233     ok(st == SEC_E_INTERNAL_ERROR ||
234        st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
235        "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
236     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
237      NULL, &schanCred, NULL, NULL, NULL, NULL);
238     ok(st == SEC_E_INTERNAL_ERROR ||
239        st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
240        "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
241
242     /* No cert in SCHANNEL_CRED succeeds for outbound.. */
243     schanCred.dwVersion = SCHANNEL_CRED_VERSION;
244     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
245      NULL, &schanCred, NULL, NULL, &cred, NULL);
246     ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
247     pFreeCredentialsHandle(&cred);
248     /* but fails for inbound. */
249     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
250      NULL, &schanCred, NULL, NULL, &cred, NULL);
251     ok(st == SEC_E_NO_CREDENTIALS ||
252        st == SEC_E_OK /* Vista/win2k8 */,
253        "Expected SEC_E_NO_CREDENTIALS or SEC_E_OK, got %08x\n", st);
254
255     if (0)
256     {
257         /* Crashes with bad paCred pointer */
258         schanCred.cCreds = 1;
259         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
260          NULL, &schanCred, NULL, NULL, NULL, NULL);
261     }
262
263     /* Bogus cert in SCHANNEL_CRED. Windows fails with
264      * SEC_E_UNKNOWN_CREDENTIALS, but I'll accept SEC_E_NO_CREDENTIALS too.
265      */
266     schanCred.cCreds = 1;
267     schanCred.paCred = &certs[0];
268     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
269      NULL, &schanCred, NULL, NULL, NULL, NULL);
270     ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS,
271      "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_NO_CREDENTIALS, got %08x\n",
272      st);
273     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
274      NULL, &schanCred, NULL, NULL, NULL, NULL);
275     ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS,
276      "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_NO_CREDENTIALS, got %08x\n",
277      st);
278
279     /* Good cert, but missing private key. Windows fails with
280      * SEC_E_NO_CREDENTIALS, but I'll accept SEC_E_UNKNOWN_CREDENTIALS too.
281      */
282     schanCred.cCreds = 1;
283     schanCred.paCred = &certs[1];
284     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
285      NULL, &schanCred, NULL, NULL, &cred, NULL);
286     ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS ||
287        st == SEC_E_INTERNAL_ERROR, /* win2k */
288      "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
289      "or SEC_E_INTERNAL_ERROR, got %08x\n", st);
290     st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
291      NULL, &schanCred, NULL, NULL, NULL, NULL);
292     ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS ||
293        st == SEC_E_INTERNAL_ERROR, /* win2k */
294      "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
295      "or SEC_E_INTERNAL_ERROR, got %08x\n", st);
296
297     /* Good cert, with CRYPT_KEY_PROV_INFO set before it's had a key loaded. */
298     if (pCertSetCertificateContextProperty)
299     {
300         ret = pCertSetCertificateContextProperty(certs[1],
301               CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo);
302         schanCred.dwVersion = SCH_CRED_V3;
303         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
304              NULL, &schanCred, NULL, NULL, &cred, NULL);
305         ok(st == SEC_E_UNKNOWN_CREDENTIALS,
306            "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
307         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
308              NULL, &schanCred, NULL, NULL, &cred, NULL);
309         ok(st == SEC_E_UNKNOWN_CREDENTIALS,
310            "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
311     }
312
313     ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
314      CRYPT_NEWKEYSET);
315     ok(ret, "CryptAcquireContextW failed: %08x\n", GetLastError());
316     ret = 0;
317     if (pCryptImportKey)
318     {
319         ret = pCryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
320         ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
321     }
322     if (ret)
323     {
324         PCCERT_CONTEXT tmp;
325
326         if (0)
327         {
328             /* Crashes */
329             st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
330              NULL, &schanCred, NULL, NULL, NULL, NULL);
331         }
332         /* Good cert with private key, bogus version */
333         schanCred.dwVersion = SCH_CRED_V1;
334         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
335          NULL, &schanCred, NULL, NULL, &cred, NULL);
336         ok(st == SEC_E_INTERNAL_ERROR ||
337            st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
338            "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
339         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
340          NULL, &schanCred, NULL, NULL, &cred, NULL);
341         ok(st == SEC_E_INTERNAL_ERROR ||
342            st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
343            "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
344         schanCred.dwVersion = SCH_CRED_V2;
345         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
346          NULL, &schanCred, NULL, NULL, &cred, NULL);
347         ok(st == SEC_E_INTERNAL_ERROR ||
348            st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
349            "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
350         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
351          NULL, &schanCred, NULL, NULL, &cred, NULL);
352         ok(st == SEC_E_INTERNAL_ERROR ||
353            st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
354            "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
355
356         /* Succeeds on V3 or higher */
357         schanCred.dwVersion = SCH_CRED_V3;
358         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
359          NULL, &schanCred, NULL, NULL, &cred, NULL);
360         ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
361         pFreeCredentialsHandle(&cred);
362         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
363          NULL, &schanCred, NULL, NULL, &cred, NULL);
364         ok(st == SEC_E_OK ||
365            st == SEC_E_UNKNOWN_CREDENTIALS, /* win2k3 */
366            "AcquireCredentialsHandleA failed: %08x\n", st);
367         pFreeCredentialsHandle(&cred);
368         schanCred.dwVersion = SCHANNEL_CRED_VERSION;
369         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
370          NULL, &schanCred, NULL, NULL, &cred, NULL);
371         ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
372         pFreeCredentialsHandle(&cred);
373         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
374          NULL, &schanCred, NULL, NULL, &cred, NULL);
375         ok(st == SEC_E_OK ||
376            st == SEC_E_UNKNOWN_CREDENTIALS, /* win2k3 */
377            "AcquireCredentialsHandleA failed: %08x\n", st);
378         if (st == SEC_E_OK) test_strength(&cred);
379         pFreeCredentialsHandle(&cred);
380
381         /* How about more than one cert? */
382         schanCred.cCreds = 2;
383         schanCred.paCred = certs;
384         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
385          NULL, &schanCred, NULL, NULL, &cred, NULL);
386         ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
387            st == SEC_E_NO_CREDENTIALS /* Vista/win2k8 */,
388            "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_NO_CREDENTIALS, got %08x\n", st);
389         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
390          NULL, &schanCred, NULL, NULL, &cred, NULL);
391         ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
392            st == SEC_E_NO_CREDENTIALS,
393            "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
394         tmp = certs[0];
395         certs[0] = certs[1];
396         certs[1] = tmp;
397         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
398          NULL, &schanCred, NULL, NULL, &cred, NULL);
399         ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
400            st == SEC_E_NO_CREDENTIALS,
401            "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
402         st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
403          NULL, &schanCred, NULL, NULL, &cred, NULL);
404         ok(st == SEC_E_UNKNOWN_CREDENTIALS,
405          "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
406         /* FIXME: what about two valid certs? */
407
408         if (pCryptDestroyKey)
409             pCryptDestroyKey(key);
410     }
411
412     if (pCryptReleaseContext)
413         pCryptReleaseContext(csp, 0);
414     pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
415      CRYPT_DELETEKEYSET);
416
417     if (pCertFreeCertificateContext)
418     {
419         pCertFreeCertificateContext(certs[0]);
420         pCertFreeCertificateContext(certs[1]);
421     }
422 }
423
424 START_TEST(schannel)
425 {
426     InitFunctionPtrs();
427
428     testAcquireSecurityContext();
429
430     if(secdll)
431         FreeLibrary(secdll);
432     if(crypt32dll)
433         FreeLibrary(crypt32dll);
434 }