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