crypt32: Added support for HCCE_LOCAL_MACHINE.
[wine.git] / dlls / secur32 / tests / schannel.c
blobfa61f4a1e635e8e1836b2d31b08c4e97a7028417
1 /*
2 * Schannel tests
4 * Copyright 2006 Juan Lang
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.
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.
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
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 #include <winsock2.h>
28 #include <ws2tcpip.h>
30 #include "wine/test.h"
32 static HMODULE secdll, crypt32dll;
34 static ACQUIRE_CREDENTIALS_HANDLE_FN_A pAcquireCredentialsHandleA;
35 static ENUMERATE_SECURITY_PACKAGES_FN_A pEnumerateSecurityPackagesA;
36 static FREE_CONTEXT_BUFFER_FN pFreeContextBuffer;
37 static FREE_CREDENTIALS_HANDLE_FN pFreeCredentialsHandle;
38 static QUERY_CREDENTIALS_ATTRIBUTES_FN_A pQueryCredentialsAttributesA;
39 static INITIALIZE_SECURITY_CONTEXT_FN_A pInitializeSecurityContextA;
40 static QUERY_CONTEXT_ATTRIBUTES_FN_A pQueryContextAttributesA;
41 static DELETE_SECURITY_CONTEXT_FN pDeleteSecurityContext;
42 static DECRYPT_MESSAGE_FN pDecryptMessage;
43 static ENCRYPT_MESSAGE_FN pEncryptMessage;
45 static PCCERT_CONTEXT (WINAPI *pCertCreateCertificateContext)(DWORD,const BYTE*,DWORD);
46 static BOOL (WINAPI *pCertFreeCertificateContext)(PCCERT_CONTEXT);
47 static BOOL (WINAPI *pCertSetCertificateContextProperty)(PCCERT_CONTEXT,DWORD,DWORD,const void*);
48 static PCCERT_CONTEXT (WINAPI *pCertEnumCertificatesInStore)(HCERTSTORE,PCCERT_CONTEXT);
50 static BOOL (WINAPI *pCryptAcquireContextW)(HCRYPTPROV*, LPCWSTR, LPCWSTR, DWORD, DWORD);
51 static BOOL (WINAPI *pCryptDestroyKey)(HCRYPTKEY);
52 static BOOL (WINAPI *pCryptImportKey)(HCRYPTPROV,const BYTE*,DWORD,HCRYPTKEY,DWORD,HCRYPTKEY*);
53 static BOOL (WINAPI *pCryptReleaseContext)(HCRYPTPROV,ULONG_PTR);
55 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
56 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
57 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
58 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
59 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
60 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
61 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
62 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
63 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
64 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
65 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
66 'm','p',0 };
67 static BYTE privKey[] = {
68 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
69 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
70 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
71 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
72 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
73 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
74 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
75 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
76 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
77 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
78 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
79 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
80 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
81 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
82 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
83 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
84 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
85 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
86 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
87 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
88 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
89 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
90 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
91 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
93 static const BYTE selfSignedCert[] = {
94 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
95 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
96 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
97 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
98 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
99 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
100 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
101 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
102 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
103 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
104 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
105 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
106 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
107 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
108 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
109 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
110 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
111 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
112 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
113 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
114 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
115 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
116 0xa8, 0x76, 0x57, 0x92, 0x36 };
118 static void InitFunctionPtrs(void)
120 HMODULE advapi32dll;
122 crypt32dll = LoadLibraryA("crypt32.dll");
123 secdll = LoadLibraryA("secur32.dll");
124 if(!secdll)
125 secdll = LoadLibraryA("security.dll");
126 advapi32dll = LoadLibraryA("advapi32.dll");
128 #define GET_PROC(h, func) p ## func = (void*)GetProcAddress(h, #func)
130 if(secdll)
132 GET_PROC(secdll, AcquireCredentialsHandleA);
133 GET_PROC(secdll, EnumerateSecurityPackagesA);
134 GET_PROC(secdll, FreeContextBuffer);
135 GET_PROC(secdll, FreeCredentialsHandle);
136 GET_PROC(secdll, QueryCredentialsAttributesA);
137 GET_PROC(secdll, InitializeSecurityContextA);
138 GET_PROC(secdll, QueryContextAttributesA);
139 GET_PROC(secdll, DeleteSecurityContext);
140 GET_PROC(secdll, DecryptMessage);
141 GET_PROC(secdll, EncryptMessage);
144 GET_PROC(advapi32dll, CryptAcquireContextW);
145 GET_PROC(advapi32dll, CryptDestroyKey);
146 GET_PROC(advapi32dll, CryptImportKey);
147 GET_PROC(advapi32dll, CryptReleaseContext);
149 GET_PROC(crypt32dll, CertFreeCertificateContext);
150 GET_PROC(crypt32dll, CertSetCertificateContextProperty);
151 GET_PROC(crypt32dll, CertCreateCertificateContext);
152 GET_PROC(crypt32dll, CertEnumCertificatesInStore);
154 #undef GET_PROC
157 static void test_strength(PCredHandle handle)
159 SecPkgCred_CipherStrengths strength = {-1,-1};
160 SECURITY_STATUS st;
162 st = pQueryCredentialsAttributesA(handle, SECPKG_ATTR_CIPHER_STRENGTHS, &strength);
163 ok(st == SEC_E_OK, "QueryCredentialsAttributesA failed: %u\n", GetLastError());
164 ok(strength.dwMinimumCipherStrength, "dwMinimumCipherStrength not changed\n");
165 ok(strength.dwMaximumCipherStrength, "dwMaximumCipherStrength not changed\n");
166 trace("strength %d - %d\n", strength.dwMinimumCipherStrength, strength.dwMaximumCipherStrength);
169 static void test_supported_protocols(CredHandle *handle, unsigned exprots)
171 SecPkgCred_SupportedProtocols protocols;
172 SECURITY_STATUS status;
174 status = pQueryCredentialsAttributesA(handle, SECPKG_ATTR_SUPPORTED_PROTOCOLS, &protocols);
175 ok(status == SEC_E_OK, "QueryCredentialsAttributes failed: %08x\n", status);
177 if(exprots)
178 ok(protocols.grbitProtocol == exprots, "protocols.grbitProtocol = %x, expected %x\n", protocols.grbitProtocol, exprots);
180 trace("Supported protocols:\n");
182 #define X(flag, name) do { if(protocols.grbitProtocol & flag) { trace(name "\n"); protocols.grbitProtocol &= ~flag; } }while(0)
183 X(SP_PROT_SSL2_CLIENT, "SSL 2 client");
184 X(SP_PROT_SSL3_CLIENT, "SSL 3 client");
185 X(SP_PROT_TLS1_0_CLIENT, "TLS 1.0 client");
186 X(SP_PROT_TLS1_1_CLIENT, "TLS 1.1 client");
187 X(SP_PROT_TLS1_2_CLIENT, "TLS 1.2 client");
188 #undef X
190 if(protocols.grbitProtocol)
191 trace("Unknown flags: %x\n", protocols.grbitProtocol);
194 static void testAcquireSecurityContext(void)
196 BOOL has_schannel = FALSE;
197 SecPkgInfoA *package_info;
198 ULONG i;
199 SECURITY_STATUS st;
200 CredHandle cred;
201 SecPkgCredentials_NamesA names;
202 TimeStamp exp;
203 SCHANNEL_CRED schanCred;
204 PCCERT_CONTEXT certs[2];
205 HCRYPTPROV csp;
206 static CHAR unisp_name_a[] = UNISP_NAME_A;
207 WCHAR ms_def_prov_w[MAX_PATH];
208 BOOL ret;
209 HCRYPTKEY key;
210 CRYPT_KEY_PROV_INFO keyProvInfo;
212 if (!pAcquireCredentialsHandleA || !pCertCreateCertificateContext ||
213 !pEnumerateSecurityPackagesA || !pFreeContextBuffer ||
214 !pFreeCredentialsHandle || !pCryptAcquireContextW)
216 win_skip("Needed functions are not available\n");
217 return;
220 if (SUCCEEDED(pEnumerateSecurityPackagesA(&i, &package_info)))
222 while(i--)
224 if (!strcmp(package_info[i].Name, unisp_name_a))
226 has_schannel = TRUE;
227 break;
230 pFreeContextBuffer(package_info);
232 if (!has_schannel)
234 skip("Schannel not available\n");
235 return;
238 lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
240 keyProvInfo.pwszContainerName = cspNameW;
241 keyProvInfo.pwszProvName = ms_def_prov_w;
242 keyProvInfo.dwProvType = PROV_RSA_FULL;
243 keyProvInfo.dwFlags = 0;
244 keyProvInfo.cProvParam = 0;
245 keyProvInfo.rgProvParam = NULL;
246 keyProvInfo.dwKeySpec = AT_SIGNATURE;
248 certs[0] = pCertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
249 sizeof(bigCert));
250 certs[1] = pCertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
251 sizeof(selfSignedCert));
253 SetLastError(0xdeadbeef);
254 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
255 CRYPT_DELETEKEYSET);
256 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
258 /* WinMe would crash on some tests */
259 win_skip("CryptAcquireContextW is not implemented\n");
260 return;
263 st = pAcquireCredentialsHandleA(NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL,
264 NULL);
265 ok(st == SEC_E_SECPKG_NOT_FOUND,
266 "Expected SEC_E_SECPKG_NOT_FOUND, got %08x\n", st);
267 if (0)
269 /* Crashes on Win2K */
270 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, 0, NULL, NULL, NULL,
271 NULL, NULL, NULL);
272 ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
274 /* Crashes on WinNT */
275 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_BOTH, NULL,
276 NULL, NULL, NULL, NULL, NULL);
277 ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
279 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
280 NULL, NULL, NULL, NULL, NULL, NULL);
281 ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
283 /* Crashes */
284 pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
285 NULL, NULL, NULL, NULL, NULL, NULL);
287 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
288 NULL, NULL, NULL, NULL, &cred, NULL);
289 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
290 if(st == SEC_E_OK) {
291 st = pQueryCredentialsAttributesA(&cred, SECPKG_ATTR_SUPPORTED_PROTOCOLS, NULL);
292 ok(st == SEC_E_INTERNAL_ERROR, "QueryCredentialsAttributes failed: %08x, expected SEC_E_INTERNAL_ERROR\n", st);
294 test_supported_protocols(&cred, 0);
295 pFreeCredentialsHandle(&cred);
297 memset(&cred, 0, sizeof(cred));
298 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
299 NULL, NULL, NULL, NULL, &cred, &exp);
300 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
301 /* expriy is indeterminate in win2k3 */
302 trace("expiry: %08x%08x\n", exp.HighPart, exp.LowPart);
304 st = pQueryCredentialsAttributesA(&cred, SECPKG_CRED_ATTR_NAMES, &names);
305 ok(st == SEC_E_NO_CREDENTIALS || st == SEC_E_UNSUPPORTED_FUNCTION /* before Vista */, "expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
307 pFreeCredentialsHandle(&cred);
309 /* Bad version in SCHANNEL_CRED */
310 memset(&schanCred, 0, sizeof(schanCred));
311 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
312 NULL, &schanCred, NULL, NULL, NULL, NULL);
313 ok(st == SEC_E_INTERNAL_ERROR ||
314 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */ ||
315 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %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_INTERNAL_ERROR ||
319 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */ ||
320 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
322 /* No cert in SCHANNEL_CRED succeeds for outbound.. */
323 schanCred.dwVersion = SCHANNEL_CRED_VERSION;
324 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
325 NULL, &schanCred, NULL, NULL, &cred, NULL);
326 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
327 pFreeCredentialsHandle(&cred);
328 /* but fails for inbound. */
329 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
330 NULL, &schanCred, NULL, NULL, &cred, NULL);
331 ok(st == SEC_E_NO_CREDENTIALS ||
332 st == SEC_E_OK /* Vista/win2k8 */,
333 "Expected SEC_E_NO_CREDENTIALS or SEC_E_OK, got %08x\n", st);
335 if (0)
337 /* Crashes with bad paCred pointer */
338 schanCred.cCreds = 1;
339 pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
340 NULL, &schanCred, NULL, NULL, NULL, NULL);
343 /* Bogus cert in SCHANNEL_CRED. Windows fails with
344 * SEC_E_UNKNOWN_CREDENTIALS, but I'll accept SEC_E_NO_CREDENTIALS too.
346 schanCred.cCreds = 1;
347 schanCred.paCred = &certs[0];
348 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
349 NULL, &schanCred, NULL, NULL, NULL, NULL);
350 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
351 st == SEC_E_NO_CREDENTIALS ||
352 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
353 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
354 NULL, &schanCred, NULL, NULL, NULL, NULL);
355 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
356 st == SEC_E_NO_CREDENTIALS ||
357 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
359 /* Good cert, but missing private key. Windows fails with
360 * SEC_E_NO_CREDENTIALS, but I'll accept SEC_E_UNKNOWN_CREDENTIALS too.
362 schanCred.cCreds = 1;
363 schanCred.paCred = &certs[1];
364 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
365 NULL, &schanCred, NULL, NULL, &cred, NULL);
366 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS ||
367 st == SEC_E_INTERNAL_ERROR, /* win2k */
368 "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
369 "or SEC_E_INTERNAL_ERROR, got %08x\n", st);
370 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
371 NULL, &schanCred, NULL, NULL, NULL, NULL);
372 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS ||
373 st == SEC_E_INTERNAL_ERROR, /* win2k */
374 "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
375 "or SEC_E_INTERNAL_ERROR, got %08x\n", st);
377 /* Good cert, with CRYPT_KEY_PROV_INFO set before it's had a key loaded. */
378 if (pCertSetCertificateContextProperty)
380 ret = pCertSetCertificateContextProperty(certs[1],
381 CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo);
382 schanCred.dwVersion = SCH_CRED_V3;
383 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
384 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
385 NULL, &schanCred, NULL, NULL, &cred, NULL);
386 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INTERNAL_ERROR /* WinNT */,
387 "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st);
388 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
389 NULL, &schanCred, NULL, NULL, &cred, NULL);
390 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INTERNAL_ERROR /* WinNT */,
391 "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st);
394 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
395 CRYPT_NEWKEYSET);
396 ok(ret, "CryptAcquireContextW failed: %08x\n", GetLastError());
397 ret = 0;
398 if (pCryptImportKey)
400 ret = pCryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
401 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
403 if (ret)
405 PCCERT_CONTEXT tmp;
407 if (0)
409 /* Crashes */
410 pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
411 NULL, &schanCred, NULL, NULL, NULL, NULL);
413 /* Crashes on WinNT */
414 /* Good cert with private key, bogus version */
415 schanCred.dwVersion = SCH_CRED_V1;
416 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
417 NULL, &schanCred, NULL, NULL, &cred, NULL);
418 ok(st == SEC_E_INTERNAL_ERROR ||
419 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
420 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
421 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
422 NULL, &schanCred, NULL, NULL, &cred, NULL);
423 ok(st == SEC_E_INTERNAL_ERROR ||
424 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
425 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
426 schanCred.dwVersion = SCH_CRED_V2;
427 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
428 NULL, &schanCred, NULL, NULL, &cred, NULL);
429 ok(st == SEC_E_INTERNAL_ERROR ||
430 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
431 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
432 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
433 NULL, &schanCred, NULL, NULL, &cred, NULL);
434 ok(st == SEC_E_INTERNAL_ERROR ||
435 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
436 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
439 /* Succeeds on V3 or higher */
440 schanCred.dwVersion = SCH_CRED_V3;
441 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
442 NULL, &schanCred, NULL, NULL, &cred, NULL);
443 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
444 pFreeCredentialsHandle(&cred);
445 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
446 NULL, &schanCred, NULL, NULL, &cred, NULL);
447 ok(st == SEC_E_OK ||
448 st == SEC_E_UNKNOWN_CREDENTIALS, /* win2k3 */
449 "AcquireCredentialsHandleA failed: %08x\n", st);
450 pFreeCredentialsHandle(&cred);
451 schanCred.dwVersion = SCHANNEL_CRED_VERSION;
452 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
453 NULL, &schanCred, NULL, NULL, &cred, NULL);
454 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
455 pFreeCredentialsHandle(&cred);
456 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
457 NULL, &schanCred, NULL, NULL, &cred, NULL);
458 ok(st == SEC_E_OK ||
459 st == SEC_E_UNKNOWN_CREDENTIALS, /* win2k3 */
460 "AcquireCredentialsHandleA failed: %08x\n", st);
461 if (st == SEC_E_OK) test_strength(&cred);
462 pFreeCredentialsHandle(&cred);
464 /* How about more than one cert? */
465 schanCred.cCreds = 2;
466 schanCred.paCred = certs;
467 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
468 NULL, &schanCred, NULL, NULL, &cred, NULL);
469 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
470 st == SEC_E_NO_CREDENTIALS /* Vista/win2k8 */ ||
471 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
472 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
473 NULL, &schanCred, NULL, NULL, &cred, NULL);
474 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
475 st == SEC_E_NO_CREDENTIALS ||
476 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
477 tmp = certs[0];
478 certs[0] = certs[1];
479 certs[1] = tmp;
480 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
481 NULL, &schanCred, NULL, NULL, &cred, NULL);
482 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
483 st == SEC_E_NO_CREDENTIALS ||
484 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
485 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
486 NULL, &schanCred, NULL, NULL, &cred, NULL);
487 ok(st == SEC_E_UNKNOWN_CREDENTIALS,
488 "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
489 /* FIXME: what about two valid certs? */
491 if (pCryptDestroyKey)
492 pCryptDestroyKey(key);
495 if (pCryptReleaseContext)
496 pCryptReleaseContext(csp, 0);
497 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
498 CRYPT_DELETEKEYSET);
500 if (pCertFreeCertificateContext)
502 pCertFreeCertificateContext(certs[0]);
503 pCertFreeCertificateContext(certs[1]);
507 static void test_remote_cert(PCCERT_CONTEXT remote_cert)
509 PCCERT_CONTEXT iter = NULL;
510 BOOL incl_remote = FALSE;
511 unsigned cert_cnt = 0;
513 ok(remote_cert->hCertStore != NULL, "hCertStore == NULL\n");
515 while((iter = pCertEnumCertificatesInStore(remote_cert->hCertStore, iter))) {
516 if(iter == remote_cert)
517 incl_remote = TRUE;
518 cert_cnt++;
521 ok(cert_cnt == 2, "cert_cnt = %u\n", cert_cnt);
522 ok(incl_remote, "context does not contain cert itself\n");
525 static const char http_request[] = "HEAD /test.html HTTP/1.1\r\nHost: www.winehq.org\r\nConnection: close\r\n\r\n";
527 static void init_cred(SCHANNEL_CRED *cred)
529 cred->dwVersion = SCHANNEL_CRED_VERSION;
530 cred->cCreds = 0;
531 cred->paCred = 0;
532 cred->hRootStore = NULL;
533 cred->cMappers = 0;
534 cred->aphMappers = NULL;
535 cred->cSupportedAlgs = 0;
536 cred->palgSupportedAlgs = NULL;
537 cred->grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
538 cred->dwMinimumCipherStrength = 0;
539 cred->dwMaximumCipherStrength = 0;
540 cred->dwSessionLifespan = 0;
541 cred->dwFlags = 0;
544 static void init_buffers(SecBufferDesc *desc, unsigned count, unsigned size)
546 desc->ulVersion = SECBUFFER_VERSION;
547 desc->cBuffers = count;
548 desc->pBuffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count*sizeof(SecBuffer));
550 desc->pBuffers[0].cbBuffer = size;
551 desc->pBuffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, size);
554 static void reset_buffers(SecBufferDesc *desc)
556 unsigned i;
558 for (i = 0; i < desc->cBuffers; ++i)
560 desc->pBuffers[i].BufferType = SECBUFFER_EMPTY;
561 if (i > 0)
563 desc->pBuffers[i].cbBuffer = 0;
564 desc->pBuffers[i].pvBuffer = NULL;
569 static void free_buffers(SecBufferDesc *desc)
571 HeapFree(GetProcessHeap(), 0, desc->pBuffers[0].pvBuffer);
572 HeapFree(GetProcessHeap(), 0, desc->pBuffers);
575 static int receive_data(SOCKET sock, SecBuffer *buf)
577 unsigned received = 0;
579 while (1)
581 unsigned char *data = buf->pvBuffer;
582 unsigned expected = 0;
583 int ret;
585 ret = recv(sock, (char *)data+received, buf->cbBuffer-received, 0);
586 if (ret == -1)
588 skip("recv failed\n");
589 return -1;
591 else if(ret == 0)
593 skip("connection closed\n");
594 return -1;
596 received += ret;
598 while (expected < received)
600 unsigned frame_size = 5 + ((data[3]<<8) | data[4]);
601 expected += frame_size;
602 data += frame_size;
605 if (expected == received)
606 break;
609 buf->cbBuffer = received;
611 return received;
614 static void test_communication(void)
616 int ret;
618 WSADATA wsa_data;
619 SOCKET sock;
620 struct hostent *host;
621 struct sockaddr_in addr;
623 SECURITY_STATUS status;
624 ULONG attrs;
626 SCHANNEL_CRED cred;
627 CredHandle cred_handle;
628 CtxtHandle context;
629 SecPkgCredentials_NamesA names;
630 SecPkgContext_StreamSizes sizes;
631 SecPkgContext_ConnectionInfo conn_info;
632 CERT_CONTEXT *cert;
634 SecBufferDesc buffers[2];
635 SecBuffer *buf;
636 unsigned buf_size = 4000;
637 unsigned char *data;
638 unsigned data_size;
640 if (!pAcquireCredentialsHandleA || !pFreeCredentialsHandle ||
641 !pInitializeSecurityContextA || !pDeleteSecurityContext ||
642 !pQueryContextAttributesA || !pDecryptMessage || !pEncryptMessage)
644 skip("Required secur32 functions not available\n");
645 return;
648 /* Create a socket and connect to www.winehq.org */
649 ret = WSAStartup(0x0202, &wsa_data);
650 if (ret)
652 skip("Can't init winsock 2.2\n");
653 return;
656 host = gethostbyname("www.winehq.org");
657 if (!host)
659 skip("Can't resolve www.winehq.org\n");
660 return;
663 addr.sin_family = host->h_addrtype;
664 addr.sin_addr = *(struct in_addr *)host->h_addr_list[0];
665 addr.sin_port = htons(443);
666 sock = socket(host->h_addrtype, SOCK_STREAM, 0);
667 if (sock == SOCKET_ERROR)
669 skip("Can't create socket\n");
670 return;
673 ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
674 if (ret == SOCKET_ERROR)
676 skip("Can't connect to www.winehq.org\n");
677 return;
680 /* Create client credentials */
681 init_cred(&cred);
682 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS|SCH_CRED_MANUAL_CRED_VALIDATION;
684 status = pAcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
685 &cred, NULL, NULL, &cred_handle, NULL);
686 ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", status);
687 if (status != SEC_E_OK) return;
689 test_supported_protocols(&cred_handle, SP_PROT_SSL3_CLIENT);
691 /* Initialize the connection */
692 init_buffers(&buffers[0], 4, buf_size);
693 init_buffers(&buffers[1], 4, buf_size);
695 buffers[0].pBuffers[0].BufferType = SECBUFFER_TOKEN;
696 status = pInitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
697 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
698 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL);
699 ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status);
701 buffers[1].cBuffers = 1;
702 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
703 buffers[0].pBuffers[0].cbBuffer = 1;
704 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
705 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
706 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
707 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
708 todo_wine
709 ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
711 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
712 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
713 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
714 todo_wine
715 ok(status == SEC_E_INSUFFICIENT_MEMORY || status == SEC_E_INVALID_TOKEN,
716 "Expected SEC_E_INSUFFICIENT_MEMORY or SEC_E_INVALID_TOKEN, got %08x\n", status);
718 buffers[0].pBuffers[0].cbBuffer = buf_size;
720 status = pInitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
721 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
722 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL);
723 ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status);
725 buf = &buffers[0].pBuffers[0];
726 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
727 buf->cbBuffer = buf_size;
729 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
730 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
731 0, 0, NULL, 0, NULL, &buffers[0], &attrs, NULL);
732 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status);
733 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
734 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
736 buffers[1].cBuffers = 4;
737 buffers[1].pBuffers[0].cbBuffer = 0;
739 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
740 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
741 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
742 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status);
743 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
744 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
746 buf = &buffers[1].pBuffers[0];
747 buf->cbBuffer = buf_size;
748 ret = receive_data(sock, buf);
749 if (ret == -1)
750 return;
752 buffers[1].pBuffers[0].cbBuffer = 4;
753 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
754 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
755 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
756 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status);
757 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
758 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
760 buffers[1].pBuffers[0].cbBuffer = 5;
761 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
762 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
763 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
764 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status);
765 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
766 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
768 buffers[1].pBuffers[0].cbBuffer = ret;
769 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
770 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
771 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
772 buffers[1].pBuffers[0].cbBuffer = buf_size;
773 while (status == SEC_I_CONTINUE_NEEDED)
775 buf = &buffers[0].pBuffers[0];
776 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
777 buf->cbBuffer = buf_size;
779 buf = &buffers[1].pBuffers[0];
780 ret = receive_data(sock, buf);
781 if (ret == -1)
782 return;
784 buf->BufferType = SECBUFFER_TOKEN;
786 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
787 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
788 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
789 buffers[1].pBuffers[0].cbBuffer = buf_size;
792 ok(status == SEC_E_OK || broken(status == SEC_E_INVALID_TOKEN) /* WinNT */,
793 "InitializeSecurityContext failed: %08x\n", status);
794 if(status != SEC_E_OK) {
795 win_skip("Handshake failed\n");
796 return;
799 status = pQueryCredentialsAttributesA(&cred_handle, SECPKG_CRED_ATTR_NAMES, &names);
800 ok(status == SEC_E_NO_CREDENTIALS || status == SEC_E_UNSUPPORTED_FUNCTION /* before Vista */, "expected SEC_E_NO_CREDENTIALS, got %08x\n", status);
802 status = pQueryContextAttributesA(&context, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (void*)&cert);
803 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_REMOTE_CERT_CONTEXT) failed: %08x\n", status);
804 if(status == SEC_E_OK) {
805 test_remote_cert(cert);
806 pCertFreeCertificateContext(cert);
809 status = pQueryContextAttributesA(&context, SECPKG_ATTR_CONNECTION_INFO, (void*)&conn_info);
810 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_CONNECTION_INFO) failed: %08x\n", status);
811 if(status == SEC_E_OK) {
812 ok(conn_info.dwCipherStrength == 128, "conn_info.dwCipherStrength = %d\n", conn_info.dwCipherStrength);
813 ok(conn_info.dwHashStrength >= 128, "conn_info.dwHashStrength = %d\n", conn_info.dwHashStrength);
816 status = pQueryContextAttributesA(&context, SECPKG_ATTR_STREAM_SIZES, &sizes);
817 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_STREAM_SIZES) failed: %08x\n", status);
819 reset_buffers(&buffers[0]);
821 /* Send a simple request so we get data for testing DecryptMessage */
822 buf = &buffers[0].pBuffers[0];
823 data = buf->pvBuffer;
824 buf->BufferType = SECBUFFER_STREAM_HEADER;
825 buf->cbBuffer = sizes.cbHeader;
826 ++buf;
827 buf->BufferType = SECBUFFER_DATA;
828 buf->pvBuffer = data + sizes.cbHeader;
829 buf->cbBuffer = sizeof(http_request) - 1;
830 memcpy(buf->pvBuffer, http_request, sizeof(http_request) - 1);
831 ++buf;
832 buf->BufferType = SECBUFFER_STREAM_TRAILER;
833 buf->pvBuffer = data + sizes.cbHeader + sizeof(http_request) -1;
834 buf->cbBuffer = sizes.cbTrailer;
836 status = pEncryptMessage(&context, 0, &buffers[0], 0);
837 ok(status == SEC_E_OK, "EncryptMessage failed: %08x\n", status);
838 if (status != SEC_E_OK)
839 return;
841 buf = &buffers[0].pBuffers[0];
842 send(sock, buf->pvBuffer, buffers[0].pBuffers[0].cbBuffer + buffers[0].pBuffers[1].cbBuffer + buffers[0].pBuffers[2].cbBuffer, 0);
844 reset_buffers(&buffers[0]);
845 buf->cbBuffer = buf_size;
846 data_size = receive_data(sock, buf);
848 /* Too few buffers */
849 --buffers[0].cBuffers;
850 status = pDecryptMessage(&context, &buffers[0], 0, NULL);
851 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
853 /* No data buffer */
854 ++buffers[0].cBuffers;
855 status = pDecryptMessage(&context, &buffers[0], 0, NULL);
856 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
858 /* Two data buffers */
859 buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA;
860 buffers[0].pBuffers[1].BufferType = SECBUFFER_DATA;
861 status = pDecryptMessage(&context, &buffers[0], 0, NULL);
862 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
864 /* Too few empty buffers */
865 buffers[0].pBuffers[1].BufferType = SECBUFFER_EXTRA;
866 status = pDecryptMessage(&context, &buffers[0], 0, NULL);
867 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
869 /* Incomplete data */
870 buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY;
871 buffers[0].pBuffers[0].cbBuffer = (data[3]<<8) | data[4];
872 status = pDecryptMessage(&context, &buffers[0], 0, NULL);
873 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Expected SEC_E_INCOMPLETE_MESSAGE, got %08x\n", status);
874 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_MISSING, "Expected first buffer to be SECBUFFER_MISSING\n");
875 ok(buffers[0].pBuffers[0].cbBuffer == 5, "Expected first buffer to be a five bytes\n");
877 buffers[0].pBuffers[0].cbBuffer = data_size;
878 buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA;
879 buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY;
880 status = pDecryptMessage(&context, &buffers[0], 0, NULL);
881 ok(status == SEC_E_OK, "DecryptMessage failed: %08x\n", status);
882 if (status == SEC_E_OK)
884 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_STREAM_HEADER, "Expected first buffer to be SECBUFFER_STREAM_HEADER\n");
885 ok(buffers[0].pBuffers[1].BufferType == SECBUFFER_DATA, "Expected second buffer to be SECBUFFER_DATA\n");
886 ok(buffers[0].pBuffers[2].BufferType == SECBUFFER_STREAM_TRAILER, "Expected third buffer to be SECBUFFER_STREAM_TRAILER\n");
888 data = buffers[0].pBuffers[1].pvBuffer;
889 data[buffers[0].pBuffers[1].cbBuffer] = 0;
892 pDeleteSecurityContext(&context);
893 pFreeCredentialsHandle(&cred_handle);
895 free_buffers(&buffers[0]);
896 free_buffers(&buffers[1]);
898 closesocket(sock);
901 START_TEST(schannel)
903 InitFunctionPtrs();
905 testAcquireSecurityContext();
906 test_communication();
908 if(secdll)
909 FreeLibrary(secdll);
910 if(crypt32dll)
911 FreeLibrary(crypt32dll);