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