gdiplus: Don't call GetDeviceCaps for NULL dc.
[wine.git] / dlls / secur32 / tests / schannel.c
blob412d37034538555942c304c7d4ba31e5783d6bcf
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
21 #include <stdarg.h>
22 #include <windef.h>
23 #include <winsock2.h>
24 #include <ws2tcpip.h>
25 #include <stdio.h>
26 #define SECURITY_WIN32
27 #include <security.h>
28 #define SCHANNEL_USE_BLACKLISTS
29 #include <schannel.h>
31 #include "wine/test.h"
33 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
34 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
35 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
36 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
37 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
38 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
39 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
40 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
41 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
42 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
43 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
44 'm','p',0 };
45 static BYTE privKey[] = {
46 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
47 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
48 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
49 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
50 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
51 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
52 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
53 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
54 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
55 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
56 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
57 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
58 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
59 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
60 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
61 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
62 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
63 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
64 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
65 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
66 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
67 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
68 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
69 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
71 static const BYTE selfSignedCert[] = {
72 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
73 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
74 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
75 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
76 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
77 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
78 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
79 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
80 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
81 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
82 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
83 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
84 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
85 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
86 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
87 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
88 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
89 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
90 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
91 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
92 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
93 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
94 0xa8, 0x76, 0x57, 0x92, 0x36 };
96 static CHAR unisp_name_a[] = UNISP_NAME_A;
98 static const char *algid_to_str(ALG_ID alg)
100 static char buf[12];
101 switch(alg) {
102 #define X(x) case x: return #x
103 X(CALG_MD2);
104 X(CALG_MD4);
105 X(CALG_MD5);
106 X(CALG_SHA1); /* same as CALG_SHA */
107 X(CALG_MAC);
108 X(CALG_RSA_SIGN);
109 X(CALG_DSS_SIGN);
110 X(CALG_NO_SIGN);
111 X(CALG_RSA_KEYX);
112 X(CALG_DES);
113 X(CALG_3DES_112);
114 X(CALG_3DES);
115 X(CALG_DESX);
116 X(CALG_RC2);
117 X(CALG_RC4);
118 X(CALG_SEAL);
119 X(CALG_DH_SF);
120 X(CALG_DH_EPHEM);
121 X(CALG_AGREEDKEY_ANY);
122 X(CALG_KEA_KEYX);
123 X(CALG_HUGHES_MD5);
124 X(CALG_SKIPJACK);
125 X(CALG_TEK);
126 X(CALG_CYLINK_MEK);
127 X(CALG_SSL3_SHAMD5);
128 X(CALG_SSL3_MASTER);
129 X(CALG_SCHANNEL_MASTER_HASH);
130 X(CALG_SCHANNEL_MAC_KEY);
131 X(CALG_SCHANNEL_ENC_KEY);
132 X(CALG_PCT1_MASTER);
133 X(CALG_SSL2_MASTER);
134 X(CALG_TLS1_MASTER);
135 X(CALG_RC5);
136 X(CALG_HMAC);
137 X(CALG_TLS1PRF);
138 X(CALG_HASH_REPLACE_OWF);
139 X(CALG_AES_128);
140 X(CALG_AES_192);
141 X(CALG_AES_256);
142 X(CALG_AES);
143 X(CALG_SHA_256);
144 X(CALG_SHA_384);
145 X(CALG_SHA_512);
146 X(CALG_ECDH);
147 X(CALG_ECMQV);
148 X(CALG_ECDSA);
149 #undef X
152 sprintf(buf, "%x", alg);
153 return buf;
156 static void init_cred(SCHANNEL_CRED *cred)
158 cred->dwVersion = SCHANNEL_CRED_VERSION;
159 cred->cCreds = 0;
160 cred->paCred = 0;
161 cred->hRootStore = NULL;
162 cred->cMappers = 0;
163 cred->aphMappers = NULL;
164 cred->cSupportedAlgs = 0;
165 cred->palgSupportedAlgs = NULL;
166 cred->grbitEnabledProtocols = 0;
167 cred->dwMinimumCipherStrength = 0;
168 cred->dwMaximumCipherStrength = 0;
169 cred->dwSessionLifespan = 0;
170 cred->dwFlags = 0;
173 static void test_strength(PCredHandle handle)
175 SecPkgCred_CipherStrengths strength = {-1,-1};
176 SECURITY_STATUS st;
178 st = QueryCredentialsAttributesA(handle, SECPKG_ATTR_CIPHER_STRENGTHS, &strength);
179 ok(st == SEC_E_OK, "QueryCredentialsAttributesA failed: %lu\n", GetLastError());
180 ok(strength.dwMinimumCipherStrength, "dwMinimumCipherStrength not changed\n");
181 ok(strength.dwMaximumCipherStrength, "dwMaximumCipherStrength not changed\n");
182 trace("strength %ld - %ld\n", strength.dwMinimumCipherStrength, strength.dwMaximumCipherStrength);
185 static void test_supported_protocols(CredHandle *handle, unsigned exprots)
187 SecPkgCred_SupportedProtocols protocols;
188 SECURITY_STATUS status;
190 status = QueryCredentialsAttributesA(handle, SECPKG_ATTR_SUPPORTED_PROTOCOLS, &protocols);
191 ok(status == SEC_E_OK, "QueryCredentialsAttributes failed: %08lx\n", status);
193 if(exprots)
194 ok(protocols.grbitProtocol == exprots, "protocols.grbitProtocol = %lx, expected %x\n", protocols.grbitProtocol, exprots);
196 trace("Supported protocols:\n");
198 #define X(flag, name) do { if(protocols.grbitProtocol & flag) { trace(name "\n"); protocols.grbitProtocol &= ~flag; } }while(0)
199 X(SP_PROT_SSL2_CLIENT, "SSL 2 client");
200 X(SP_PROT_SSL3_CLIENT, "SSL 3 client");
201 X(SP_PROT_TLS1_0_CLIENT, "TLS 1.0 client");
202 X(SP_PROT_TLS1_1_CLIENT, "TLS 1.1 client");
203 X(SP_PROT_TLS1_2_CLIENT, "TLS 1.2 client");
204 X(SP_PROT_TLS1_3_CLIENT, "TLS 1.3 client");
205 X(SP_PROT_DTLS1_0_CLIENT, "DTLS 1.0 client");
206 X(SP_PROT_DTLS1_2_CLIENT, "DTLS 1.2 client");
207 #undef X
209 if(protocols.grbitProtocol)
210 trace("Unknown flags: %lx\n", protocols.grbitProtocol);
213 static void test_supported_algs(CredHandle *handle)
215 SecPkgCred_SupportedAlgs algs;
216 SECURITY_STATUS status;
217 unsigned i;
219 status = QueryCredentialsAttributesA(handle, SECPKG_ATTR_SUPPORTED_ALGS, &algs);
220 todo_wine ok(status == SEC_E_OK, "QueryCredentialsAttributes failed: %08lx\n", status);
221 if(status != SEC_E_OK)
222 return;
224 trace("Supported algorithms (%ld):\n", algs.cSupportedAlgs);
225 for(i=0; i < algs.cSupportedAlgs; i++)
226 trace(" %s\n", algid_to_str(algs.palgSupportedAlgs[i]));
228 FreeContextBuffer(algs.palgSupportedAlgs);
231 static void test_cread_attrs(void)
233 SCHANNEL_CRED schannel_cred;
234 SECURITY_STATUS status;
235 CredHandle cred;
237 status = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
238 NULL, NULL, NULL, NULL, &cred, NULL);
239 ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %lx\n", status);
241 test_supported_protocols(&cred, 0);
242 test_supported_algs(&cred);
244 status = QueryCredentialsAttributesA(&cred, SECPKG_ATTR_SUPPORTED_PROTOCOLS, NULL);
245 ok(status == SEC_E_INTERNAL_ERROR, "QueryCredentialsAttributes failed: %08lx, expected SEC_E_INTERNAL_ERROR\n", status);
247 status = QueryCredentialsAttributesA(&cred, SECPKG_ATTR_SUPPORTED_ALGS, NULL);
248 ok(status == SEC_E_INTERNAL_ERROR, "QueryCredentialsAttributes failed: %08lx, expected SEC_E_INTERNAL_ERROR\n", status);
250 FreeCredentialsHandle(&cred);
252 init_cred(&schannel_cred);
253 schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
254 status = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
255 NULL, &schannel_cred, NULL, NULL, &cred, NULL);
256 ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %lx\n", status);
258 test_supported_protocols(&cred, SP_PROT_TLS1_CLIENT);
259 test_supported_algs(&cred);
261 FreeCredentialsHandle(&cred);
264 static void testAcquireSecurityContext(void)
266 BOOL has_schannel = FALSE;
267 SecPkgInfoA *package_info;
268 ULONG i;
269 SECURITY_STATUS st;
270 CredHandle cred;
271 SecPkgCredentials_NamesA names;
272 TimeStamp exp;
273 SCHANNEL_CRED schanCred;
274 SCH_CREDENTIALS schCred;
275 PCCERT_CONTEXT certs[2];
276 HCRYPTPROV csp;
277 WCHAR ms_def_prov_w[MAX_PATH];
278 BOOL ret;
279 HCRYPTKEY key;
280 CRYPT_KEY_PROV_INFO keyProvInfo;
282 if (SUCCEEDED(EnumerateSecurityPackagesA(&i, &package_info)))
284 while(i--)
286 if (!strcmp(package_info[i].Name, unisp_name_a))
288 has_schannel = TRUE;
289 break;
292 FreeContextBuffer(package_info);
294 if (!has_schannel)
296 skip("Schannel not available\n");
297 return;
300 lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
302 keyProvInfo.pwszContainerName = cspNameW;
303 keyProvInfo.pwszProvName = ms_def_prov_w;
304 keyProvInfo.dwProvType = PROV_RSA_FULL;
305 keyProvInfo.dwFlags = 0;
306 keyProvInfo.cProvParam = 0;
307 keyProvInfo.rgProvParam = NULL;
308 keyProvInfo.dwKeySpec = AT_SIGNATURE;
310 certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
311 certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert, sizeof(selfSignedCert));
313 SetLastError(0xdeadbeef);
314 ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
316 st = AcquireCredentialsHandleA(NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
317 ok(st == SEC_E_SECPKG_NOT_FOUND, "Expected SEC_E_SECPKG_NOT_FOUND, got %08lx\n", st);
319 st = AcquireCredentialsHandleA(NULL, unisp_name_a, 0, NULL, NULL, NULL, NULL, NULL, NULL);
320 ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08lx\n", st);
322 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_BOTH, NULL, NULL, NULL, NULL, NULL, NULL);
323 ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08lx\n", st);
325 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, NULL, NULL);
326 ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08lx\n", st);
328 if (0) /* crash */
330 AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, NULL, NULL);
333 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
334 NULL, NULL, NULL, NULL, &cred, NULL);
335 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", st);
336 if(st == SEC_E_OK)
337 FreeCredentialsHandle(&cred);
338 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &cred, NULL);
339 ok(st == SEC_E_NO_CREDENTIALS, "st = %08lx\n", st);
340 memset(&cred, 0, sizeof(cred));
341 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
342 NULL, NULL, NULL, NULL, &cred, &exp);
343 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", st);
344 /* expriy is indeterminate in win2k3 */
345 trace("expiry: %08lx%08lx\n", exp.HighPart, exp.LowPart);
347 st = QueryCredentialsAttributesA(&cred, SECPKG_CRED_ATTR_NAMES, &names);
348 ok(st == SEC_E_NO_CREDENTIALS, "expected SEC_E_NO_CREDENTIALS, got %08lx\n", st);
350 FreeCredentialsHandle(&cred);
352 /* Should fail if no enabled protocols are available */
353 init_cred(&schanCred);
354 schanCred.grbitEnabledProtocols = SP_PROT_TLS1_X_SERVER;
355 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &schanCred, NULL, NULL, &cred, &exp);
356 ok(st == SEC_E_ALGORITHM_MISMATCH, "st = %08lx\n", st);
357 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND, NULL, &schanCred, NULL, NULL, &cred, &exp);
358 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", st);
359 FreeCredentialsHandle(&cred);
361 schanCred.grbitEnabledProtocols = SP_PROT_TLS1_X_CLIENT;
362 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &schanCred, NULL, NULL, &cred, &exp);
363 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", st);
364 FreeCredentialsHandle(&cred);
365 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND, NULL, &schanCred, NULL, NULL, &cred, &exp);
366 ok(st == SEC_E_ALGORITHM_MISMATCH, "st = %08lx\n", st);
368 /* Bad version in SCHANNEL_CRED */
369 memset(&schanCred, 0, sizeof(schanCred));
370 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
371 NULL, &schanCred, NULL, NULL, NULL, NULL);
372 ok(st == SEC_E_UNKNOWN_CREDENTIALS, "st = %08lx\n", st);
373 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
374 NULL, &schanCred, NULL, NULL, NULL, NULL);
375 ok(st == SEC_E_UNKNOWN_CREDENTIALS, "st = %08lx\n", st);
377 /* No cert in SCHANNEL_CRED succeeds for outbound.. */
378 schanCred.dwVersion = SCHANNEL_CRED_VERSION;
379 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
380 NULL, &schanCred, NULL, NULL, &cred, NULL);
381 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", st);
382 FreeCredentialsHandle(&cred);
383 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
384 NULL, &schanCred, NULL, NULL, &cred, NULL);
385 ok(st == SEC_E_OK, "Expected SEC_E_OK, got %08lx\n", st);
387 if (0)
389 /* Crashes with bad paCred pointer */
390 schanCred.cCreds = 1;
391 AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
392 NULL, &schanCred, NULL, NULL, NULL, NULL);
395 /* Bogus cert in SCHANNEL_CRED. Windows fails with SEC_E_UNKNOWN_CREDENTIALS. */
396 schanCred.cCreds = 1;
397 schanCred.paCred = &certs[0];
398 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
399 NULL, &schanCred, NULL, NULL, NULL, NULL);
400 ok(st == SEC_E_UNKNOWN_CREDENTIALS, "st = %08lx\n", st);
401 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
402 NULL, &schanCred, NULL, NULL, NULL, NULL);
403 ok(st == SEC_E_UNKNOWN_CREDENTIALS, "st = %08lx\n", st);
405 /* Good cert, but missing private key. Windows fails with SEC_E_NO_CREDENTIALS. */
406 schanCred.cCreds = 1;
407 schanCred.paCred = &certs[1];
408 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
409 NULL, &schanCred, NULL, NULL, &cred, NULL);
410 todo_wine ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08lx\n", st);
411 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
412 NULL, &schanCred, NULL, NULL, NULL, NULL);
413 todo_wine ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08lx\n", st);
415 /* Good cert, with CRYPT_KEY_PROV_INFO set before it's had a key loaded. */
416 ret = CertSetCertificateContextProperty(certs[1],
417 CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo);
418 schanCred.dwVersion = SCH_CRED_V3;
419 ok(ret, "CertSetCertificateContextProperty failed: %08lx\n", GetLastError());
420 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
421 NULL, &schanCred, NULL, NULL, &cred, NULL);
422 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INSUFFICIENT_MEMORY /* win10 */,
423 "Expected SEC_E_INSUFFICIENT_MEMORY, got %08lx\n", st);
424 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
425 NULL, &schanCred, NULL, NULL, &cred, NULL);
426 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INSUFFICIENT_MEMORY /* win10 */,
427 "Expected SEC_E_INSUFFICIENT_MEMORY, got %08lx\n", st);
429 ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
430 CRYPT_NEWKEYSET);
431 ok(ret, "CryptAcquireContextW failed: %08lx\n", GetLastError());
432 ret = 0;
434 ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
435 ok(ret, "CryptImportKey failed: %08lx\n", GetLastError());
436 if (ret)
438 PCCERT_CONTEXT tmp;
440 if (0)
442 /* Crashes */
443 AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
444 NULL, &schanCred, NULL, NULL, NULL, NULL);
447 /* Good cert with private key, bogus version */
448 schanCred.dwVersion = SCH_CRED_V1;
449 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
450 NULL, &schanCred, NULL, NULL, &cred, NULL);
451 ok(st == SEC_E_UNKNOWN_CREDENTIALS, "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08lx\n", st);
452 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
453 NULL, &schanCred, NULL, NULL, &cred, NULL);
454 ok(st == SEC_E_UNKNOWN_CREDENTIALS, "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08lx\n", st);
455 schanCred.dwVersion = SCH_CRED_V2;
456 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
457 NULL, &schanCred, NULL, NULL, &cred, NULL);
458 ok(st == SEC_E_UNKNOWN_CREDENTIALS, "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08lx\n", st);
459 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
460 NULL, &schanCred, NULL, NULL, &cred, NULL);
461 ok(st == SEC_E_UNKNOWN_CREDENTIALS, "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08lx\n", st);
463 /* Succeeds on V3 or higher */
464 schanCred.dwVersion = SCH_CRED_V3;
465 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
466 NULL, &schanCred, NULL, NULL, &cred, NULL);
467 todo_wine ok(st == SEC_E_INSUFFICIENT_MEMORY || broken(st == S_OK) /* <win10 */,
468 "AcquireCredentialsHandleA failed: %08lx\n", st);
469 if (st == S_OK) FreeCredentialsHandle(&cred);
470 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
471 NULL, &schanCred, NULL, NULL, &cred, NULL);
472 todo_wine ok(st == SEC_E_INSUFFICIENT_MEMORY || broken(st == S_OK) /* <win10 */,
473 "AcquireCredentialsHandleA failed: %08lx\n", st);
474 if (st == S_OK) FreeCredentialsHandle(&cred);
475 schanCred.dwVersion = SCHANNEL_CRED_VERSION;
476 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
477 NULL, &schanCred, NULL, NULL, &cred, NULL);
478 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", st);
479 FreeCredentialsHandle(&cred);
480 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
481 NULL, &schanCred, NULL, NULL, &cred, NULL);
482 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", st);
483 if (st == SEC_E_OK) test_strength(&cred);
484 FreeCredentialsHandle(&cred);
486 /* How about more than one cert? */
487 schanCred.cCreds = 2;
488 schanCred.paCred = certs;
489 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
490 NULL, &schanCred, NULL, NULL, &cred, NULL);
491 ok(st == SEC_E_UNKNOWN_CREDENTIALS, "st = %08lx\n", st);
492 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
493 NULL, &schanCred, NULL, NULL, &cred, NULL);
494 ok(st == SEC_E_UNKNOWN_CREDENTIALS, "st = %08lx\n", st);
495 tmp = certs[0];
496 certs[0] = certs[1];
497 certs[1] = tmp;
498 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
499 NULL, &schanCred, NULL, NULL, &cred, NULL);
500 ok(st == SEC_E_UNKNOWN_CREDENTIALS, "st = %08lx\n", st);
501 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
502 NULL, &schanCred, NULL, NULL, &cred, NULL);
503 ok(st == SEC_E_UNKNOWN_CREDENTIALS, "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08lx\n", st);
504 /* FIXME: what about two valid certs? */
506 CryptDestroyKey(key);
509 memset(&schCred, 0, sizeof(schCred));
510 schCred.dwVersion = SCH_CREDENTIALS_VERSION;
511 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
512 NULL, &schCred, NULL, NULL, &cred, NULL);
513 ok(st == SEC_E_OK || broken(st == SEC_E_UNKNOWN_CREDENTIALS) /* <= win10v1570 */,
514 "AcquireCredentialsHandleA failed: %08lx\n", st);
515 FreeCredentialsHandle(&cred);
517 CryptReleaseContext(csp, 0);
518 CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
520 CertFreeCertificateContext(certs[0]);
521 CertFreeCertificateContext(certs[1]);
524 static void test_remote_cert(PCCERT_CONTEXT remote_cert)
526 PCCERT_CONTEXT iter = NULL;
527 BOOL incl_remote = FALSE;
528 unsigned cert_cnt = 0;
530 ok(remote_cert->hCertStore != NULL, "hCertStore == NULL\n");
532 while((iter = CertEnumCertificatesInStore(remote_cert->hCertStore, iter))) {
533 if(iter == remote_cert)
534 incl_remote = TRUE;
535 cert_cnt++;
538 ok(cert_cnt == 2, "cert_cnt = %u\n", cert_cnt);
539 ok(incl_remote, "context does not contain cert itself\n");
542 static const char http_request[] = "GET /tests/clientcert/ HTTP/1.1\r\nHost: test.winehq.org\r\nConnection: close\r\n\r\n";
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 init_sec_buffer(SecBuffer *sec_buf, ULONG count, void *buf)
556 sec_buf->cbBuffer = count;
557 sec_buf->pvBuffer = buf;
560 static void reset_buffers(SecBufferDesc *desc)
562 unsigned i;
564 for (i = 0; i < desc->cBuffers; ++i)
566 desc->pBuffers[i].BufferType = SECBUFFER_EMPTY;
567 if (i > 0)
569 desc->pBuffers[i].cbBuffer = 0;
570 desc->pBuffers[i].pvBuffer = NULL;
575 static void free_buffers(SecBufferDesc *desc)
577 HeapFree(GetProcessHeap(), 0, desc->pBuffers[0].pvBuffer);
578 HeapFree(GetProcessHeap(), 0, desc->pBuffers);
581 static int receive_data(SOCKET sock, SecBuffer *buf)
583 unsigned received = 0;
585 while (1)
587 unsigned char *data = buf->pvBuffer;
588 unsigned expected = 0;
589 int ret;
591 ret = recv(sock, (char *)data+received, buf->cbBuffer-received, 0);
592 if (ret == -1)
594 skip("recv failed\n");
595 return -1;
597 else if(ret == 0)
599 skip("connection closed\n");
600 return -1;
602 received += ret;
604 while (expected < received)
606 unsigned frame_size = 5 + ((data[3]<<8) | data[4]);
607 expected += frame_size;
608 data += frame_size;
611 if (expected == received)
612 break;
615 buf->cbBuffer = received;
617 return received;
620 static void test_context_output_buffer_size(DWORD protocol, DWORD flags, ULONG ctxt_flags_req)
622 SCHANNEL_CRED cred;
623 CredHandle cred_handle;
624 CtxtHandle context;
625 SECURITY_STATUS status;
626 SecBuffer in_buffer = {0, SECBUFFER_EMPTY, NULL};
627 SecBufferDesc in_buffers = {SECBUFFER_VERSION, 1, &in_buffer};
628 SecBufferDesc out_buffers;
629 unsigned buf_size = 8192;
630 void *buf, *buf2;
631 ULONG attrs;
632 int i;
634 init_cred(&cred);
635 cred.grbitEnabledProtocols = protocol;
636 cred.dwFlags = flags;
637 status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
638 &cred, NULL, NULL, &cred_handle, NULL);
639 ok( status == SEC_E_OK, "got %08lx\n", status );
640 if (status != SEC_E_OK) return;
642 init_buffers(&out_buffers, 4, buf_size);
643 out_buffers.pBuffers[0].BufferType = SECBUFFER_TOKEN;
644 buf = out_buffers.pBuffers[0].pvBuffer;
645 buf2 = out_buffers.pBuffers[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buf_size);
646 for (i = 0; i < 2; i++)
648 SecBuffer *buffer = !i ? &out_buffers.pBuffers[0] : &out_buffers.pBuffers[1];
650 init_sec_buffer(&out_buffers.pBuffers[0], buf_size, buf);
651 if (i) buffer->BufferType = SECBUFFER_ALERT;
653 buffer->cbBuffer = 0;
654 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost", ctxt_flags_req,
655 0, 0, &in_buffers, 0, &context, &out_buffers, &attrs, NULL);
656 ok(status == SEC_E_INSUFFICIENT_MEMORY, "%d: Expected SEC_E_INSUFFICIENT_MEMORY, got %08lx\n", i, status);
658 if (i) init_sec_buffer(&out_buffers.pBuffers[0], buf_size, (void *)0xdeadbeef);
659 init_sec_buffer(buffer, 0, NULL);
660 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
661 ctxt_flags_req | ISC_REQ_ALLOCATE_MEMORY, 0, 0, &in_buffers, 0, &context, &out_buffers, &attrs, NULL);
662 ok(status == SEC_I_CONTINUE_NEEDED, "%d: Expected SEC_I_CONTINUE_NEEDED, got %08lx\n", i, status);
663 ok(out_buffers.pBuffers[0].pvBuffer != (void *)0xdeadbeef, "got %p.\n", out_buffers.pBuffers[0].pvBuffer);
664 if (i) FreeContextBuffer(out_buffers.pBuffers[0].pvBuffer);
665 FreeContextBuffer(buffer->pvBuffer);
666 DeleteSecurityContext(&context);
668 if (i) init_sec_buffer(&out_buffers.pBuffers[0], buf_size, buf);
669 init_sec_buffer(buffer, buf_size, !i ? buf : buf2);
670 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost", ctxt_flags_req,
671 0, 0, &in_buffers, 0, &context, &out_buffers, &attrs, NULL);
672 ok(status == SEC_I_CONTINUE_NEEDED, "%d: Expected SEC_I_CONTINUE_NEEDED, got %08lx\n", i, status);
673 if (i) ok(!buffer->cbBuffer, "Expected SECBUFFER_ALERT buffer to be empty\n");
674 DeleteSecurityContext(&context);
677 HeapFree(GetProcessHeap(), 0, buf2);
678 free_buffers(&out_buffers);
679 FreeCredentialsHandle(&cred_handle);
682 static void test_InitializeSecurityContext(void)
684 SCHANNEL_CRED cred;
685 CredHandle cred_handle;
686 CtxtHandle context;
687 SECURITY_STATUS status;
688 SecBuffer out_buffer = {1000, SECBUFFER_TOKEN, NULL};
689 SecBuffer in_buffer = {0, SECBUFFER_EMPTY, NULL};
690 SecBufferDesc out_buffers = {SECBUFFER_VERSION, 1, &out_buffer};
691 SecBufferDesc in_buffers = {SECBUFFER_VERSION, 1, &in_buffer};
692 ULONG attrs;
694 init_cred(&cred);
695 cred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
696 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS|SCH_CRED_MANUAL_CRED_VALIDATION;
697 status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
698 &cred, NULL, NULL, &cred_handle, NULL);
699 ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", status);
700 if (status != SEC_E_OK) return;
702 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
703 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM|ISC_REQ_ALLOCATE_MEMORY,
704 0, 0, &in_buffers, 0, &context, &out_buffers, &attrs, NULL);
705 ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08lx\n", status);
707 FreeContextBuffer(out_buffer.pvBuffer);
708 DeleteSecurityContext(&context);
709 FreeCredentialsHandle(&cred_handle);
712 static SOCKET create_ssl_socket( const char *hostname )
714 struct hostent *host;
715 struct sockaddr_in addr;
716 SOCKET sock;
718 if (!(host = gethostbyname(hostname)))
720 skip("Can't resolve \"%s\"\n", hostname);
721 return -1;
724 addr.sin_family = host->h_addrtype;
725 addr.sin_addr = *(struct in_addr *)host->h_addr_list[0];
726 addr.sin_port = htons(443);
727 if ((sock = socket(host->h_addrtype, SOCK_STREAM, 0)) == -1)
729 skip("Can't create socket\n");
730 return 1;
733 if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1)
735 skip("Can't connect to \"%s\"\n", hostname);
736 closesocket(sock);
737 return -1;
740 return sock;
743 static const BYTE pfxdata[] =
745 0x30, 0x82, 0x0b, 0x1d, 0x02, 0x01, 0x03, 0x30, 0x82, 0x0a, 0xe3, 0x06,
746 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82,
747 0x0a, 0xd4, 0x04, 0x82, 0x0a, 0xd0, 0x30, 0x82, 0x0a, 0xcc, 0x30, 0x82,
748 0x05, 0x07, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
749 0x06, 0xa0, 0x82, 0x04, 0xf8, 0x30, 0x82, 0x04, 0xf4, 0x02, 0x01, 0x00,
750 0x30, 0x82, 0x04, 0xed, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
751 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
752 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xac, 0x3e, 0x35,
753 0xa8, 0xed, 0x0d, 0x50, 0x07, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x04,
754 0xc0, 0x5a, 0x62, 0x55, 0x25, 0xf6, 0x2c, 0xf1, 0x78, 0x6c, 0x63, 0x96,
755 0x8a, 0xea, 0x04, 0x64, 0xb3, 0x99, 0x3b, 0x80, 0x50, 0x05, 0x37, 0x55,
756 0xa3, 0x5e, 0x9f, 0x35, 0xc3, 0x3c, 0xdc, 0xf6, 0xc4, 0xc1, 0x39, 0xa2,
757 0xd7, 0x50, 0xad, 0xf9, 0x29, 0x3c, 0x51, 0xea, 0x15, 0x20, 0x25, 0xd3,
758 0x4d, 0x69, 0xdf, 0x10, 0xd8, 0x9d, 0x60, 0x78, 0x8a, 0x70, 0x44, 0x7f,
759 0x01, 0x4f, 0x4a, 0xfa, 0xab, 0xfd, 0x46, 0x48, 0x96, 0x2b, 0x69, 0xfc,
760 0x11, 0xf8, 0x3f, 0xd3, 0x79, 0x09, 0x75, 0x81, 0x47, 0xdf, 0xce, 0xfe,
761 0x07, 0x2f, 0x0a, 0xd8, 0xac, 0x87, 0x14, 0x1f, 0x7b, 0x95, 0x70, 0xee,
762 0x7e, 0x52, 0x90, 0x11, 0xd6, 0x69, 0xf4, 0xd5, 0x38, 0x85, 0xc9, 0xc1,
763 0x07, 0x01, 0xe8, 0xbb, 0xfb, 0xe2, 0x08, 0xa8, 0xfa, 0xbf, 0xf0, 0x92,
764 0x63, 0x1d, 0xbb, 0x2b, 0x45, 0x6f, 0xce, 0x97, 0x01, 0xd7, 0x95, 0xf0,
765 0x9c, 0x9a, 0x6b, 0x73, 0x01, 0xbf, 0xf9, 0x3d, 0xc8, 0x2b, 0x86, 0x7a,
766 0xd5, 0x65, 0x84, 0xd7, 0xff, 0xb2, 0xf9, 0x20, 0x52, 0x35, 0xc5, 0x60,
767 0x33, 0x70, 0x1d, 0x2f, 0x26, 0x09, 0x1c, 0x22, 0x17, 0xd8, 0x08, 0x4e,
768 0x69, 0x20, 0xe2, 0x71, 0xe4, 0x07, 0xb1, 0x48, 0x5f, 0x20, 0x08, 0x7a,
769 0xbf, 0x65, 0x53, 0x23, 0x07, 0xf9, 0x6c, 0xde, 0x3e, 0x29, 0xbf, 0x6b,
770 0xef, 0xbb, 0x6a, 0x5f, 0x79, 0xa1, 0x72, 0xa1, 0x10, 0x24, 0x80, 0xb4,
771 0x44, 0xb8, 0xc9, 0xfc, 0xa3, 0x36, 0x7e, 0x23, 0x37, 0x58, 0xc6, 0x1e,
772 0xe8, 0x42, 0x4d, 0xb5, 0xf5, 0x58, 0x93, 0x21, 0x38, 0xa2, 0xc4, 0xa9,
773 0x01, 0x96, 0xf9, 0x61, 0xac, 0x55, 0xb3, 0x3d, 0xe4, 0x54, 0x8b, 0x6c,
774 0xc3, 0x83, 0xff, 0x50, 0x87, 0x94, 0xe8, 0x35, 0x3c, 0x26, 0x0d, 0x20,
775 0x8a, 0x25, 0x0e, 0xb6, 0x67, 0x78, 0x29, 0xc7, 0xbf, 0x76, 0x8e, 0x62,
776 0x62, 0xc4, 0x50, 0xd6, 0xc5, 0x3c, 0xb4, 0x7a, 0x35, 0xbe, 0x53, 0x52,
777 0xc4, 0xe4, 0x10, 0xb3, 0xe0, 0x73, 0xb0, 0xd1, 0xc1, 0x5a, 0x4f, 0x4e,
778 0x64, 0x0d, 0x92, 0x51, 0x2d, 0x4d, 0xec, 0xb0, 0xc6, 0x40, 0x1b, 0x03,
779 0x89, 0x7f, 0xc2, 0x2c, 0xe3, 0x2c, 0xbd, 0x8c, 0x9c, 0xd9, 0xe0, 0x08,
780 0x59, 0xd3, 0xaf, 0x48, 0x56, 0x89, 0x60, 0x85, 0x76, 0xe0, 0xd8, 0x7c,
781 0xcf, 0x02, 0x8f, 0xfd, 0xb2, 0x8f, 0x2b, 0x61, 0xcf, 0x28, 0x56, 0x8b,
782 0x6b, 0x03, 0x2b, 0x2f, 0x83, 0x31, 0xa0, 0x1c, 0xd1, 0x6c, 0x87, 0x49,
783 0xc4, 0x77, 0x55, 0x1f, 0x61, 0x45, 0x58, 0x88, 0x9f, 0x01, 0xc3, 0x63,
784 0x62, 0x30, 0x35, 0xdf, 0x61, 0x74, 0x55, 0x63, 0x3f, 0xae, 0x41, 0xc1,
785 0xb8, 0xf0, 0x9f, 0xab, 0x25, 0xad, 0x41, 0x5c, 0x1f, 0x00, 0x0d, 0xef,
786 0xf0, 0xcf, 0xaf, 0x41, 0x23, 0xca, 0x8c, 0x38, 0xea, 0x5a, 0xe4, 0x8b,
787 0xb4, 0x89, 0xd0, 0x76, 0x7f, 0x2b, 0x77, 0x8f, 0xe4, 0x44, 0xd5, 0x37,
788 0xac, 0xc2, 0x09, 0x7e, 0x7e, 0x7e, 0x02, 0x5c, 0x27, 0x01, 0xcb, 0x4d,
789 0xea, 0xb3, 0x97, 0x36, 0x35, 0xd2, 0x05, 0x3c, 0x4e, 0xb8, 0x04, 0x5c,
790 0xb8, 0x95, 0x3f, 0xc6, 0xbf, 0xd4, 0x20, 0x01, 0xfb, 0xed, 0x37, 0x5a,
791 0xad, 0x4c, 0x61, 0x93, 0xfe, 0x95, 0x7c, 0x34, 0x11, 0x15, 0x9d, 0x00,
792 0x0b, 0x99, 0x69, 0xcb, 0x7e, 0xb9, 0x53, 0x46, 0x57, 0x39, 0x3f, 0x59,
793 0x4b, 0x30, 0x8d, 0xfb, 0x84, 0x66, 0x2d, 0x06, 0xc9, 0x88, 0xa6, 0x18,
794 0xd7, 0x36, 0xc6, 0xf6, 0xf7, 0x47, 0x85, 0x38, 0xc8, 0x3d, 0x37, 0xea,
795 0x57, 0x4c, 0xb0, 0x7c, 0x95, 0x29, 0x84, 0xab, 0xbb, 0x19, 0x86, 0xc2,
796 0xc5, 0x99, 0x01, 0x38, 0x6b, 0xf1, 0xd3, 0x1d, 0xa8, 0x02, 0xf9, 0x6f,
797 0xaa, 0xf1, 0x57, 0xd0, 0x88, 0x68, 0x62, 0x5f, 0x9f, 0x7a, 0x63, 0xba,
798 0x3a, 0xc9, 0x95, 0x11, 0x3c, 0xf9, 0xa1, 0xc1, 0x35, 0xfe, 0xd5, 0x12,
799 0x49, 0x88, 0x0d, 0x5c, 0xe2, 0xd1, 0x15, 0x18, 0xfb, 0xd5, 0x7f, 0x19,
800 0x3f, 0xaf, 0xa0, 0xcb, 0x31, 0x20, 0x9e, 0x03, 0x93, 0xa4, 0x66, 0xbd,
801 0x83, 0xe8, 0x60, 0x34, 0x55, 0x0d, 0x97, 0x10, 0x23, 0x24, 0x7a, 0x45,
802 0x36, 0xb4, 0xc4, 0xee, 0x60, 0x6f, 0xd8, 0x46, 0xc5, 0xac, 0x2b, 0xa9,
803 0x18, 0x74, 0x83, 0x1e, 0xdf, 0x7c, 0x1a, 0x5a, 0xe8, 0x5f, 0x8b, 0x4f,
804 0x9f, 0x40, 0x3e, 0x5e, 0xfb, 0xd3, 0x68, 0xac, 0x34, 0x62, 0x30, 0x23,
805 0xb6, 0xbc, 0xdf, 0xbc, 0xc7, 0x25, 0xd2, 0x1b, 0x57, 0x33, 0xfb, 0x78,
806 0x22, 0x21, 0x1e, 0x3a, 0xf6, 0x44, 0x18, 0x7e, 0x12, 0x36, 0x47, 0x58,
807 0xd0, 0x59, 0x26, 0x98, 0x98, 0x95, 0xf4, 0xd1, 0xaa, 0x45, 0xaa, 0xe7,
808 0xd1, 0xe6, 0x2d, 0x78, 0xf0, 0x8b, 0x1c, 0xfd, 0xf8, 0x50, 0x60, 0xa2,
809 0x1e, 0x7f, 0xe3, 0x31, 0x77, 0x31, 0x58, 0x99, 0x0f, 0xda, 0x0e, 0xa3,
810 0xc6, 0x7a, 0x30, 0x45, 0x55, 0x11, 0x91, 0x77, 0x41, 0x79, 0xd3, 0x56,
811 0xb2, 0x07, 0x00, 0x61, 0xab, 0xec, 0x27, 0xc7, 0x9f, 0xfa, 0x89, 0x08,
812 0xc2, 0x87, 0xcf, 0xe9, 0xdc, 0x9e, 0x29, 0x22, 0xfb, 0x23, 0x7f, 0x9d,
813 0x89, 0xd5, 0x6e, 0x75, 0x20, 0xd8, 0x00, 0x5b, 0xc4, 0x94, 0xbb, 0xc5,
814 0xb2, 0xba, 0x77, 0x2b, 0xf6, 0x3c, 0x88, 0xb0, 0x4c, 0x38, 0x46, 0x55,
815 0xee, 0x8b, 0x03, 0x15, 0xbc, 0x0a, 0x1d, 0x47, 0x87, 0x44, 0xaf, 0xb1,
816 0x2a, 0xa7, 0x4d, 0x08, 0xdf, 0x3b, 0x2d, 0x70, 0xa1, 0x67, 0x31, 0x76,
817 0x6e, 0x6f, 0x40, 0x3b, 0x3b, 0xe8, 0xf9, 0xdf, 0x90, 0xa4, 0xce, 0x7f,
818 0xb8, 0x2d, 0x69, 0xcb, 0x1c, 0x1e, 0x94, 0xcd, 0xb1, 0xd8, 0x43, 0x22,
819 0xb8, 0x4f, 0x98, 0x92, 0x74, 0xb3, 0xde, 0xeb, 0x7a, 0xcb, 0xfa, 0xd0,
820 0x36, 0xe4, 0x5d, 0xfa, 0xd3, 0xce, 0xf9, 0xba, 0x3e, 0x0f, 0x6c, 0xc3,
821 0x5b, 0xb3, 0x81, 0x84, 0x6e, 0x5d, 0xc1, 0x21, 0x89, 0xec, 0x67, 0x9a,
822 0xfd, 0x55, 0x20, 0xb0, 0x71, 0x53, 0xae, 0xf8, 0xa4, 0x8d, 0xd5, 0xe5,
823 0x2d, 0x3a, 0xce, 0x89, 0x55, 0x8c, 0x4f, 0x3b, 0x37, 0x95, 0x4e, 0x15,
824 0xbe, 0xe7, 0xd1, 0x7a, 0x36, 0x82, 0x45, 0x69, 0x7c, 0x27, 0x4f, 0xb9,
825 0x4b, 0x7d, 0xcd, 0x59, 0xc8, 0xf4, 0x8b, 0x0f, 0x4f, 0x75, 0x23, 0xd3,
826 0xd0, 0xc7, 0x10, 0x79, 0xc0, 0xf1, 0xac, 0x14, 0xf7, 0x0d, 0xc8, 0x5e,
827 0xfc, 0xff, 0x1a, 0x2b, 0x10, 0x88, 0x7e, 0x7e, 0x2f, 0xfa, 0x7b, 0x9f,
828 0x47, 0x23, 0x34, 0xfc, 0xf5, 0xde, 0xd9, 0xa3, 0x05, 0x99, 0x2a, 0x96,
829 0x83, 0x3d, 0xa4, 0x7f, 0x6a, 0x66, 0x9b, 0xe7, 0xf1, 0x00, 0x4e, 0x9a,
830 0xfc, 0x68, 0xd2, 0x74, 0x17, 0xba, 0xc9, 0xc8, 0x20, 0x39, 0xa1, 0xa8,
831 0x85, 0xc6, 0x10, 0x2b, 0xab, 0x97, 0x34, 0x2d, 0x49, 0x68, 0x57, 0xb0,
832 0x43, 0xee, 0x25, 0xbb, 0x35, 0x1b, 0x03, 0x99, 0xa3, 0x21, 0x68, 0x66,
833 0x86, 0x3f, 0xc6, 0xfc, 0x49, 0xf0, 0xba, 0x5f, 0x00, 0xc6, 0xe3, 0x1c,
834 0xb2, 0x9f, 0x16, 0x7f, 0xc7, 0x40, 0x4a, 0x9a, 0x39, 0xc1, 0x95, 0x69,
835 0xa2, 0x87, 0xba, 0x58, 0xc6, 0xf2, 0xd6, 0x66, 0xa6, 0x4c, 0x6d, 0x29,
836 0x9c, 0xa8, 0x6e, 0xa9, 0xd2, 0xe4, 0x54, 0x17, 0x89, 0xe2, 0x43, 0xf0,
837 0xe1, 0x8b, 0x57, 0x84, 0x6c, 0x87, 0x63, 0x17, 0xbb, 0xf6, 0x33, 0x1b,
838 0xe4, 0x34, 0x6a, 0x80, 0x70, 0x7b, 0x1b, 0xfd, 0xf8, 0x79, 0x28, 0xc8,
839 0x3c, 0x8e, 0xa4, 0xd5, 0xb8, 0x96, 0x54, 0xd4, 0xec, 0x72, 0xe5, 0x40,
840 0x8f, 0x56, 0xde, 0x82, 0x15, 0x72, 0x4d, 0xd8, 0x0c, 0x07, 0xea, 0xe6,
841 0x44, 0xcd, 0x94, 0x73, 0x5c, 0x04, 0xe8, 0x8e, 0xb7, 0xc7, 0xc9, 0x29,
842 0xdc, 0x04, 0xef, 0x7c, 0x31, 0x9b, 0x50, 0xbc, 0xea, 0x71, 0x1f, 0x28,
843 0x22, 0xb6, 0x04, 0x53, 0x2e, 0x71, 0xc4, 0xf6, 0xbb, 0x88, 0x51, 0xee,
844 0x3e, 0x76, 0x65, 0xb4, 0x4b, 0x1b, 0xa3, 0xec, 0x7b, 0xa7, 0x9d, 0x31,
845 0x5d, 0xb8, 0x9f, 0xab, 0x6b, 0x54, 0x7d, 0xbd, 0xc1, 0x2c, 0x55, 0xb0,
846 0x23, 0x8c, 0x06, 0x60, 0x01, 0x4f, 0x60, 0x85, 0x56, 0x7f, 0xfb, 0x99,
847 0x0c, 0xdc, 0x8c, 0x09, 0x37, 0x46, 0x5b, 0x97, 0x5d, 0xe8, 0x31, 0x00,
848 0x1b, 0x30, 0x9b, 0x02, 0x92, 0x29, 0xb5, 0x20, 0xce, 0x4b, 0x90, 0xfb,
849 0x91, 0x07, 0x5a, 0xd3, 0xf5, 0xa0, 0xe6, 0x8f, 0xf8, 0x73, 0xc5, 0x4b,
850 0xbb, 0xad, 0x2a, 0xeb, 0xa8, 0xb7, 0x68, 0x34, 0x36, 0x47, 0xd5, 0x4b,
851 0x61, 0x89, 0x53, 0xe6, 0xb6, 0xb1, 0x07, 0xe4, 0x08, 0x2e, 0xed, 0x50,
852 0xd4, 0x1e, 0xed, 0x7f, 0xbf, 0x35, 0x68, 0x04, 0x45, 0x72, 0x86, 0x71,
853 0x15, 0x55, 0xdf, 0xe6, 0x30, 0xc0, 0x8b, 0x8a, 0xb0, 0x6c, 0xd0, 0x35,
854 0x57, 0x8f, 0x04, 0x37, 0xbc, 0xe1, 0xb8, 0xbf, 0x27, 0x37, 0x3d, 0xd0,
855 0xc8, 0x46, 0x67, 0x42, 0x51, 0x30, 0x82, 0x05, 0xbd, 0x06, 0x09, 0x2a,
856 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0xae,
857 0x04, 0x82, 0x05, 0xaa, 0x30, 0x82, 0x05, 0xa6, 0x30, 0x82, 0x05, 0xa2,
858 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01,
859 0x02, 0xa0, 0x82, 0x04, 0xee, 0x30, 0x82, 0x04, 0xea, 0x30, 0x1c, 0x06,
860 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30,
861 0x0e, 0x04, 0x08, 0x9f, 0xa4, 0x72, 0x2b, 0x6b, 0x0e, 0xcb, 0x9f, 0x02,
862 0x02, 0x08, 0x00, 0x04, 0x82, 0x04, 0xc8, 0xe5, 0x35, 0xb9, 0x72, 0x28,
863 0x20, 0x28, 0xad, 0xe3, 0x01, 0xd7, 0x0b, 0xe0, 0x4e, 0x36, 0xc3, 0x73,
864 0x06, 0xd5, 0xf6, 0x75, 0x1a, 0x78, 0xb2, 0xd8, 0xf6, 0x5a, 0x85, 0x8e,
865 0x50, 0xa3, 0x05, 0x49, 0x02, 0x2d, 0xf8, 0xa3, 0x2f, 0xe6, 0x02, 0x7a,
866 0xd5, 0x0b, 0x1d, 0xf1, 0xd1, 0xe4, 0x16, 0xaa, 0x70, 0x2e, 0x34, 0xdb,
867 0x56, 0xd9, 0x33, 0x94, 0x11, 0xaa, 0x60, 0xd4, 0xfa, 0x5b, 0xd1, 0xb3,
868 0x2e, 0x86, 0x6a, 0x5a, 0x69, 0xdf, 0x11, 0x91, 0xb0, 0xca, 0x82, 0xff,
869 0x63, 0xad, 0x6a, 0x0b, 0x90, 0xa6, 0xc7, 0x9b, 0xef, 0x9a, 0xf8, 0x96,
870 0xec, 0xe4, 0xc4, 0xdf, 0x55, 0x4c, 0x12, 0x07, 0xab, 0x7c, 0x5c, 0x68,
871 0x47, 0xf2, 0x92, 0xfb, 0x94, 0xab, 0xc3, 0x64, 0xd3, 0xfe, 0xb2, 0x16,
872 0xb4, 0x78, 0x80, 0x52, 0xe9, 0x32, 0x39, 0x3b, 0x8d, 0x12, 0x91, 0x36,
873 0xfd, 0xa1, 0x97, 0xc2, 0x0a, 0x4a, 0xf1, 0xb3, 0x8a, 0xe4, 0x01, 0xed,
874 0x0a, 0xda, 0x2e, 0xa0, 0x38, 0xa9, 0x47, 0x3d, 0x3a, 0x64, 0x87, 0x06,
875 0xc3, 0x83, 0x60, 0xaf, 0x84, 0xdb, 0x87, 0xff, 0x70, 0x61, 0x43, 0x7d,
876 0x2d, 0x61, 0x9a, 0xf7, 0x0d, 0xca, 0x0c, 0x0f, 0xbe, 0x43, 0x5b, 0x99,
877 0xe1, 0x90, 0x64, 0x1f, 0xa7, 0x1b, 0xa6, 0xa6, 0x5c, 0x13, 0x70, 0xa3,
878 0xdb, 0xd7, 0xf0, 0xe8, 0x7a, 0xb0, 0xd1, 0x9b, 0x52, 0xa6, 0x4f, 0xd6,
879 0xff, 0x54, 0x4d, 0xa6, 0x15, 0x05, 0x5c, 0xe9, 0x04, 0x6a, 0xc3, 0x49,
880 0x12, 0x2f, 0x24, 0x03, 0xc3, 0x80, 0x06, 0xa6, 0x07, 0x8b, 0x96, 0xe7,
881 0x39, 0x31, 0x6d, 0xd3, 0x1b, 0xa5, 0x45, 0x58, 0x04, 0xe7, 0x87, 0xdf,
882 0x26, 0xfb, 0x1b, 0x9f, 0x92, 0x93, 0x32, 0x12, 0x9a, 0xc9, 0xe6, 0xcb,
883 0x88, 0x14, 0x9f, 0x23, 0x0b, 0x52, 0xa2, 0xb8, 0x32, 0x6c, 0xa9, 0x33,
884 0xa1, 0x17, 0xe8, 0x4a, 0xd4, 0x5c, 0x7d, 0xb3, 0xa3, 0x64, 0x86, 0x03,
885 0x7c, 0x7c, 0x3f, 0x99, 0xdc, 0x21, 0x9f, 0x93, 0xc6, 0xb9, 0x1d, 0xe0,
886 0x21, 0x79, 0x78, 0x35, 0xdc, 0x1e, 0x27, 0x3c, 0x73, 0x7f, 0x0f, 0xd6,
887 0x4f, 0xde, 0xe9, 0xb4, 0xb7, 0xe3, 0xf5, 0x72, 0xce, 0x42, 0xf3, 0x91,
888 0x5b, 0x84, 0xba, 0xbb, 0xae, 0xf0, 0x87, 0x0f, 0x50, 0xa4, 0x5e, 0x80,
889 0x23, 0x57, 0x2b, 0xa0, 0xa3, 0xc3, 0x8a, 0x2f, 0xa8, 0x7a, 0x1a, 0x65,
890 0x8f, 0x62, 0xf8, 0x3e, 0xe2, 0xcd, 0xbc, 0x63, 0x56, 0x8e, 0x77, 0xf3,
891 0xf9, 0x69, 0x10, 0x57, 0xa8, 0xaf, 0x67, 0x2a, 0x9f, 0x7f, 0x7e, 0xeb,
892 0x1d, 0x99, 0xa6, 0x67, 0xcd, 0x9e, 0x42, 0x2e, 0x5e, 0x4e, 0x61, 0x24,
893 0xfa, 0xca, 0x2a, 0xeb, 0x62, 0x1f, 0xa3, 0x14, 0x0a, 0x06, 0x4b, 0x77,
894 0x78, 0x77, 0x9b, 0xf1, 0x03, 0xcc, 0xb5, 0xfe, 0xfb, 0x7a, 0x77, 0xa6,
895 0x82, 0x9f, 0xe5, 0xde, 0x9d, 0x0d, 0x4d, 0x37, 0xc6, 0x12, 0x73, 0x6d,
896 0xea, 0xbb, 0x48, 0xf0, 0xd2, 0x81, 0xcc, 0x1a, 0x47, 0xfa, 0xa4, 0xd2,
897 0xb2, 0x27, 0xa0, 0xfc, 0x30, 0x04, 0xdb, 0x05, 0xd3, 0x0b, 0xbc, 0x4d,
898 0x7a, 0x99, 0xef, 0x7f, 0x26, 0x01, 0xd4, 0x07, 0x0b, 0x1e, 0x99, 0x06,
899 0x3c, 0xde, 0x3d, 0x1c, 0x21, 0x82, 0x68, 0x46, 0x35, 0x38, 0x61, 0xea,
900 0xd4, 0xc2, 0x65, 0x09, 0x39, 0x87, 0xb4, 0xd3, 0x5d, 0x3c, 0xa3, 0x79,
901 0xe4, 0x01, 0x4e, 0xbf, 0x18, 0xba, 0x57, 0x3f, 0xdd, 0xea, 0x0a, 0x6b,
902 0x99, 0xfb, 0x93, 0xfa, 0xab, 0xee, 0x08, 0xdf, 0x38, 0x23, 0xae, 0x8d,
903 0xa8, 0x03, 0x13, 0xfe, 0x83, 0x88, 0xb0, 0xc2, 0xf9, 0x90, 0xa5, 0x1c,
904 0x01, 0x6f, 0x71, 0x91, 0x42, 0x35, 0x81, 0x74, 0x71, 0x6c, 0xba, 0x86,
905 0x48, 0xfe, 0x96, 0xd2, 0x88, 0x12, 0x36, 0x4e, 0xa6, 0x2f, 0xd1, 0xdb,
906 0xfa, 0xbf, 0xdb, 0x84, 0x01, 0xfc, 0x7d, 0x7a, 0xac, 0x20, 0xae, 0xf5,
907 0x95, 0xc9, 0xdc, 0x10, 0x5f, 0x4c, 0xae, 0x85, 0x01, 0x8b, 0xfe, 0x77,
908 0x13, 0x01, 0xae, 0x39, 0x59, 0x7e, 0xbc, 0xfd, 0xc9, 0x42, 0xe4, 0x13,
909 0x07, 0x3f, 0xa9, 0x74, 0xd9, 0xd5, 0xfc, 0xb9, 0x78, 0xbe, 0x97, 0xf5,
910 0xe7, 0x36, 0x7f, 0xfa, 0x23, 0x30, 0xeb, 0xab, 0x92, 0xd3, 0xdc, 0x3f,
911 0x7f, 0xc0, 0x77, 0x93, 0xf9, 0x88, 0xe3, 0x4e, 0x13, 0x53, 0x6d, 0x71,
912 0x87, 0xe9, 0x24, 0x2b, 0xae, 0x26, 0xbf, 0x62, 0x51, 0x04, 0x42, 0xe1,
913 0x13, 0x9d, 0xd8, 0x9f, 0x59, 0x87, 0x3f, 0xfc, 0x94, 0xff, 0xcf, 0x88,
914 0x88, 0xe6, 0xeb, 0x6e, 0xc1, 0x96, 0x04, 0x27, 0xc8, 0xda, 0xfa, 0xe8,
915 0x2e, 0xbb, 0x2c, 0x6e, 0xf4, 0xb4, 0x00, 0x7d, 0x8d, 0x3b, 0xef, 0x8b,
916 0x18, 0xa9, 0x5f, 0x32, 0xa9, 0xf2, 0x3a, 0x7e, 0x65, 0x2d, 0x6e, 0x8d,
917 0x75, 0x77, 0xf6, 0xa6, 0xd8, 0xf9, 0x6b, 0x51, 0xe6, 0x66, 0x52, 0x59,
918 0x39, 0x97, 0x22, 0xda, 0xb2, 0xd6, 0x82, 0x5a, 0x6e, 0x61, 0x60, 0x16,
919 0x48, 0x7b, 0xf1, 0xc3, 0x4d, 0x7f, 0x50, 0xfa, 0x4d, 0x58, 0x27, 0x30,
920 0xc8, 0x96, 0xe0, 0x41, 0x4f, 0x6b, 0xeb, 0x88, 0xa2, 0x7a, 0xef, 0x8a,
921 0x88, 0xc8, 0x50, 0x4b, 0x55, 0x66, 0xee, 0xbf, 0xc4, 0x01, 0x82, 0x4c,
922 0xec, 0xde, 0x37, 0x64, 0xd6, 0x1e, 0xcf, 0x3e, 0x2e, 0xfe, 0x84, 0x68,
923 0xbf, 0xa3, 0x68, 0x77, 0xa9, 0x03, 0xe4, 0xf8, 0xd7, 0xb2, 0x6e, 0xa3,
924 0xc4, 0xc3, 0x36, 0x53, 0xf3, 0xdd, 0x7e, 0x4c, 0xf0, 0xe9, 0xb2, 0x44,
925 0xe6, 0x60, 0x3d, 0x00, 0x9a, 0x08, 0xc3, 0x21, 0x17, 0x49, 0xda, 0x49,
926 0xfb, 0x4c, 0x8b, 0xe9, 0x10, 0x66, 0xfe, 0xb7, 0xe0, 0xf9, 0xdd, 0xbf,
927 0x41, 0xfe, 0x04, 0x9b, 0x7f, 0xe8, 0xd6, 0x2e, 0x4d, 0x0f, 0x7b, 0x10,
928 0x73, 0x4c, 0xa1, 0x3e, 0x43, 0xb7, 0xcf, 0x94, 0x97, 0x7e, 0x24, 0xbb,
929 0x87, 0xbf, 0x22, 0xb8, 0x3e, 0xeb, 0x9a, 0x3f, 0xe3, 0x86, 0xee, 0x21,
930 0xbc, 0xf5, 0x44, 0xeb, 0x60, 0x2e, 0xe7, 0x8f, 0x89, 0xa4, 0x91, 0x61,
931 0x28, 0x90, 0x85, 0x68, 0xe0, 0xa9, 0x62, 0x93, 0x86, 0x5a, 0x15, 0xbe,
932 0xb2, 0x76, 0x83, 0xf2, 0x0f, 0x00, 0xc7, 0xb6, 0x57, 0xe9, 0x1f, 0x92,
933 0x49, 0xfe, 0x50, 0x85, 0xbf, 0x39, 0x3d, 0xe4, 0x8b, 0x72, 0x2d, 0x49,
934 0xbe, 0x05, 0x0a, 0x34, 0x56, 0x80, 0xc6, 0x1f, 0x46, 0x59, 0xc9, 0xfe,
935 0x40, 0xfb, 0x78, 0x6d, 0x7a, 0xe5, 0x30, 0xe9, 0x81, 0x55, 0x75, 0x05,
936 0x63, 0xd2, 0x22, 0xee, 0x2e, 0x6e, 0xb9, 0x18, 0xe5, 0x8a, 0x5a, 0x66,
937 0xbd, 0x74, 0x30, 0xe3, 0x8b, 0x76, 0x22, 0x18, 0x1e, 0xef, 0x69, 0xe8,
938 0x9d, 0x07, 0xa7, 0x9a, 0x87, 0x6c, 0x04, 0x4b, 0x74, 0x2b, 0xbe, 0x37,
939 0x2f, 0x29, 0x9b, 0x60, 0x9d, 0x8b, 0x57, 0x55, 0x34, 0xca, 0x41, 0x25,
940 0xae, 0x56, 0x92, 0x34, 0x1b, 0x9e, 0xbd, 0xfe, 0x74, 0xbd, 0x4e, 0x29,
941 0xf0, 0x5e, 0x27, 0x94, 0xb0, 0x9e, 0x23, 0x9f, 0x4a, 0x0f, 0xa1, 0xdf,
942 0xe7, 0xc4, 0xdb, 0xbe, 0x0f, 0x1a, 0x0b, 0x6c, 0xb0, 0xe1, 0x06, 0x7c,
943 0x5a, 0x5b, 0x81, 0x1c, 0xb6, 0x12, 0xec, 0x6f, 0x3b, 0xbb, 0x84, 0x36,
944 0xd5, 0x28, 0x16, 0xea, 0x51, 0xa8, 0x99, 0x24, 0x8f, 0xe7, 0xf8, 0xe9,
945 0xce, 0xa1, 0x65, 0x96, 0x6f, 0x4e, 0x2f, 0xb7, 0x6f, 0x65, 0x39, 0xad,
946 0xfd, 0x2e, 0xa0, 0x37, 0x32, 0x2f, 0xf3, 0x95, 0xa1, 0x3a, 0xa1, 0x9d,
947 0x2c, 0x9e, 0xa1, 0x4b, 0x7e, 0xc9, 0x7e, 0x86, 0xaa, 0x16, 0x00, 0x82,
948 0x1d, 0x36, 0xbf, 0x98, 0x0a, 0x82, 0x5b, 0xcc, 0xc4, 0x6a, 0xad, 0xa0,
949 0x1f, 0x47, 0x98, 0xde, 0x8d, 0x68, 0x38, 0x3f, 0x33, 0xe2, 0x08, 0x3b,
950 0x2a, 0x65, 0xd9, 0x2f, 0x53, 0x68, 0xb8, 0x78, 0xd0, 0x1d, 0xbb, 0x2a,
951 0x73, 0x19, 0xba, 0x58, 0xea, 0xf1, 0x0a, 0xaa, 0xa6, 0xbe, 0x27, 0xd6,
952 0x00, 0x6b, 0x4e, 0x43, 0x8e, 0x5b, 0x19, 0xc1, 0x37, 0x0f, 0xfb, 0x81,
953 0x72, 0x10, 0xb6, 0x20, 0x32, 0xcd, 0xa2, 0x7c, 0x90, 0xd4, 0xf5, 0xcf,
954 0x1c, 0xcb, 0x14, 0x24, 0x7a, 0x4d, 0xf5, 0xd5, 0xd9, 0xce, 0x6a, 0x64,
955 0xc9, 0xd3, 0xa7, 0x36, 0x6f, 0x1d, 0xf1, 0xe9, 0x71, 0x6c, 0x3d, 0x02,
956 0xa4, 0x62, 0xb1, 0x82, 0x5c, 0x13, 0x4b, 0x6b, 0x68, 0xe2, 0x31, 0xef,
957 0xe4, 0x46, 0xfd, 0xe5, 0xa8, 0x29, 0xe9, 0x1e, 0xad, 0xff, 0x33, 0xdb,
958 0x0b, 0xc0, 0x92, 0xb1, 0xef, 0xeb, 0xb3, 0x6f, 0x96, 0x7b, 0xdf, 0xcd,
959 0x07, 0x19, 0x86, 0x60, 0x98, 0xcf, 0x95, 0xfe, 0x98, 0xdd, 0x29, 0xa6,
960 0x35, 0x7b, 0x46, 0x13, 0x03, 0xa8, 0xd9, 0x7c, 0xb3, 0xdf, 0x9f, 0x14,
961 0xb7, 0x34, 0x5a, 0xc4, 0x12, 0x81, 0xc5, 0x98, 0x25, 0x8d, 0x3e, 0xe3,
962 0xd8, 0x2d, 0xe4, 0x54, 0xab, 0xb0, 0x13, 0xfd, 0xd1, 0x3f, 0x3b, 0xbf,
963 0xa9, 0x45, 0x28, 0x8a, 0x2f, 0x9c, 0x1e, 0x2d, 0xe5, 0xab, 0x13, 0x95,
964 0x97, 0xc3, 0x34, 0x37, 0x8d, 0x93, 0x66, 0x31, 0x81, 0xa0, 0x30, 0x23,
965 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31,
966 0x16, 0x04, 0x14, 0xa5, 0x23, 0x9b, 0x7e, 0xe6, 0x45, 0x71, 0xbf, 0x48,
967 0xc6, 0x27, 0x3c, 0x96, 0x87, 0x63, 0xbd, 0x1f, 0xde, 0x72, 0x12, 0x30,
968 0x79, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x11, 0x01,
969 0x31, 0x6c, 0x1e, 0x6a, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72,
970 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20,
971 0x00, 0x45, 0x00, 0x6e, 0x00, 0x68, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63,
972 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x52, 0x00, 0x53, 0x00, 0x41,
973 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x41,
974 0x00, 0x45, 0x00, 0x53, 0x00, 0x20, 0x00, 0x43, 0x00, 0x72, 0x00, 0x79,
975 0x00, 0x70, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x67, 0x00, 0x72, 0x00, 0x61,
976 0x00, 0x70, 0x00, 0x68, 0x00, 0x69, 0x00, 0x63, 0x00, 0x20, 0x00, 0x50,
977 0x00, 0x72, 0x00, 0x6f, 0x00, 0x76, 0x00, 0x69, 0x00, 0x64, 0x00, 0x65,
978 0x00, 0x72, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
979 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x93, 0xa8, 0xb2, 0x7e, 0xb7,
980 0xab, 0xf1, 0x1c, 0x3c, 0x36, 0x58, 0xdc, 0x67, 0x6d, 0x42, 0xa6, 0xfc,
981 0x53, 0x01, 0xe6, 0x04, 0x08, 0x77, 0x57, 0x22, 0xa1, 0x7d, 0xb9, 0xa2,
982 0x69, 0x02, 0x02, 0x08, 0x00
985 static void test_communication(void)
987 int ret;
988 SOCKET sock;
989 SECURITY_STATUS status;
990 ULONG attrs;
991 SCHANNEL_CRED cred;
992 CredHandle cred_handle;
993 CtxtHandle context, context2;
994 SecPkgCredentials_NamesA names;
995 SecPkgContext_StreamSizes sizes;
996 SecPkgContext_ConnectionInfo conn_info;
997 SecPkgContext_KeyInfoA key_info;
998 const CERT_CONTEXT *cert;
999 CRYPT_DATA_BLOB pfx;
1000 HCERTSTORE store;
1001 SecPkgContext_NegotiationInfoA info;
1002 SecPkgContext_CipherInfo cipher;
1003 SecBufferDesc buffers[2];
1004 SecBuffer *buf;
1005 unsigned buf_size = 8192;
1006 unsigned char *data;
1007 unsigned data_size;
1009 test_context_output_buffer_size(SP_PROT_TLS1_CLIENT, SCH_CRED_NO_DEFAULT_CREDS|SCH_CRED_MANUAL_CRED_VALIDATION,
1010 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM);
1012 /* Create a socket and connect to test.winehq.org */
1013 if ((sock = create_ssl_socket( "test.winehq.org" )) == -1) return;
1015 /* Create client credentials */
1016 init_cred(&cred);
1017 cred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
1018 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS|SCH_CRED_MANUAL_CRED_VALIDATION;
1020 status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
1021 &cred, NULL, NULL, &cred_handle, NULL);
1022 ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", status);
1023 if (status != SEC_E_OK) return;
1025 /* Initialize the connection */
1026 init_buffers(&buffers[0], 4, buf_size);
1027 init_buffers(&buffers[1], 4, buf_size);
1029 buffers[0].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1030 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
1031 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1032 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL);
1033 ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08lx\n", status);
1035 buffers[1].cBuffers = 1;
1036 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1037 buffers[0].pBuffers[0].cbBuffer = 1;
1038 memset(buffers[1].pBuffers[0].pvBuffer, 0xfa, buf_size);
1039 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1040 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1041 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1042 todo_wine
1043 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08lx\n", status);
1044 todo_wine
1045 ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
1047 buffers[1].cBuffers = 1;
1048 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1049 buffers[0].pBuffers[0].cbBuffer = 1;
1050 memset(buffers[1].pBuffers[0].pvBuffer, 0, buf_size);
1051 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1052 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1053 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1054 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08lx\n", status);
1055 ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
1057 buffers[0].pBuffers[0].cbBuffer = 0;
1058 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1059 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1060 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1061 ok(status == SEC_E_INSUFFICIENT_MEMORY || status == SEC_E_INVALID_TOKEN,
1062 "Expected SEC_E_INSUFFICIENT_MEMORY or SEC_E_INVALID_TOKEN, got %08lx\n", status);
1063 ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
1065 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
1066 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1067 0, 0, NULL, 0, &context, NULL, &attrs, NULL);
1068 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08lx\n", status);
1070 buffers[0].pBuffers[0].cbBuffer = buf_size;
1071 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
1072 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1073 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL);
1074 ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08lx\n", status);
1076 buf = &buffers[0].pBuffers[0];
1077 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
1078 buf->cbBuffer = buf_size;
1080 context2.dwLower = context2.dwUpper = 0xdeadbeef;
1081 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1082 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1083 0, 0, NULL, 0, &context2, &buffers[0], &attrs, NULL);
1084 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#lx.\n", status);
1085 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
1086 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
1087 ok( context2.dwLower == 0xdeadbeef, "Did not expect dwLower to be set on new context\n");
1088 ok( context2.dwUpper == 0xdeadbeef, "Did not expect dwUpper to be set on new context\n");
1090 buffers[1].cBuffers = 2;
1091 buffers[1].pBuffers[0].cbBuffer = 0;
1092 buffers[1].pBuffers[1].cbBuffer = 0;
1093 buffers[1].pBuffers[1].BufferType = SECBUFFER_EMPTY;
1095 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1096 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1097 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1098 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#lx.\n", status);
1099 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
1100 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
1101 ok(buffers[1].pBuffers[1].cbBuffer == 5 ||
1102 broken(buffers[1].pBuffers[1].cbBuffer == 0), /* < win10 */ "Wrong buffer size.\n");
1103 ok(buffers[1].pBuffers[1].BufferType == SECBUFFER_MISSING ||
1104 broken(buffers[1].pBuffers[1].BufferType == SECBUFFER_EMPTY), /* < win10 */ "Wrong buffer type.\n");
1106 buf = &buffers[1].pBuffers[0];
1107 buf->cbBuffer = buf_size;
1108 ret = receive_data(sock, buf);
1109 if (ret == -1)
1110 return;
1112 buffers[1].pBuffers[0].cbBuffer = 4;
1113 buffers[1].pBuffers[1].cbBuffer = 0;
1114 buffers[1].pBuffers[1].BufferType = SECBUFFER_EMPTY;
1115 buffers[1].pBuffers[1].cbBuffer = 0;
1116 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1117 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1118 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1119 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#lx.\n", status);
1120 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
1121 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
1122 ok(buffers[1].pBuffers[1].cbBuffer == 1 ||
1123 broken(buffers[1].pBuffers[1].cbBuffer == 0), /* < win10 */ "Wrong buffer size.\n");
1124 ok(buffers[1].pBuffers[1].BufferType == SECBUFFER_MISSING ||
1125 broken(buffers[1].pBuffers[1].BufferType == SECBUFFER_EMPTY), /* < win10 */ "Wrong buffer type.\n");
1127 context2.dwLower = context2.dwUpper = 0xdeadbeef;
1128 buffers[1].pBuffers[0].cbBuffer = 5;
1129 buffers[1].pBuffers[1].cbBuffer = 0;
1130 buffers[1].pBuffers[1].BufferType = SECBUFFER_EMPTY;
1131 buffers[1].pBuffers[1].cbBuffer = 0;
1132 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1133 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1134 0, 0, &buffers[1], 0, &context2, &buffers[0], &attrs, NULL);
1135 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#lx.\n", status);
1136 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
1137 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
1138 ok(buffers[1].pBuffers[1].cbBuffer > 5 ||
1139 broken(buffers[1].pBuffers[1].cbBuffer == 0), /* < win10 */ "Wrong buffer size\n" );
1140 ok(buffers[1].pBuffers[1].BufferType == SECBUFFER_MISSING ||
1141 broken(buffers[1].pBuffers[1].BufferType == SECBUFFER_EMPTY), /* < win10 */ "Wrong buffer type.\n");
1142 ok( context2.dwLower == 0xdeadbeef, "Did not expect dwLower to be set on new context\n");
1143 ok( context2.dwUpper == 0xdeadbeef, "Did not expect dwUpper to be set on new context\n");
1145 buffers[1].cBuffers = 1;
1146 buffers[1].pBuffers[0].cbBuffer = ret;
1147 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1148 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM|ISC_REQ_USE_SUPPLIED_CREDS,
1149 0, 0, &buffers[1], 0, &context2, &buffers[0], &attrs, NULL);
1150 buffers[1].pBuffers[0].cbBuffer = buf_size;
1151 while (status == SEC_I_CONTINUE_NEEDED)
1153 buf = &buffers[0].pBuffers[0];
1154 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
1155 buf->cbBuffer = buf_size;
1157 ok( context.dwLower == context2.dwLower, "dwLower mismatch, expected %#Ix, got %#Ix\n",
1158 context.dwLower, context2.dwLower);
1159 ok( context.dwUpper == context2.dwUpper, "dwUpper mismatch, expected %#Ix, got %#Ix\n",
1160 context.dwUpper, context2.dwUpper);
1162 buf = &buffers[1].pBuffers[0];
1163 ret = receive_data(sock, buf);
1164 if (ret == -1)
1165 return;
1167 context2.dwLower = context2.dwUpper = 0xdeadbeef;
1168 buf->BufferType = SECBUFFER_TOKEN;
1170 buffers[1].cBuffers = 2;
1171 buffers[1].pBuffers[1].BufferType = SECBUFFER_EMPTY;
1172 buffers[1].pBuffers[1].cbBuffer = 0xdeadbeef;
1174 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1175 ISC_REQ_USE_SUPPLIED_CREDS,
1176 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1177 ok(status == SEC_E_INVALID_TOKEN, "Got unexpected status %#lx.\n", status);
1179 buffers[1].cBuffers = 1;
1180 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1181 ISC_REQ_USE_SUPPLIED_CREDS,
1182 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1183 buffers[1].pBuffers[0].cbBuffer = buf_size;
1186 ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
1187 ok(status == SEC_E_OK, "InitializeSecurityContext failed: %08lx\n", status);
1188 if(status != SEC_E_OK) {
1189 skip("Handshake failed\n");
1190 return;
1192 ok(attrs == (ISC_RET_REPLAY_DETECT | ISC_RET_SEQUENCE_DETECT | ISC_RET_CONFIDENTIALITY |
1193 ISC_RET_STREAM | ISC_RET_USED_SUPPLIED_CREDS), "got %08lx\n", attrs);
1195 status = QueryCredentialsAttributesA(&cred_handle, SECPKG_CRED_ATTR_NAMES, &names);
1196 ok(status == SEC_E_NO_CREDENTIALS, "expected SEC_E_NO_CREDENTIALS, got %08lx\n", status);
1198 status = QueryContextAttributesA(&context, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (void*)&cert);
1199 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_REMOTE_CERT_CONTEXT) failed: %08lx\n", status);
1200 if(status == SEC_E_OK) {
1201 SecPkgContext_Bindings bindings = {0xdeadbeef, (void*)0xdeadbeef};
1203 test_remote_cert(cert);
1205 status = QueryContextAttributesA(&context, SECPKG_ATTR_ENDPOINT_BINDINGS, &bindings);
1206 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_ENDPOINT_BINDINGS) failed: %08lx\n", status);
1207 if (status == SEC_E_OK)
1209 static const char prefix[] = "tls-server-end-point:";
1210 const char *p;
1211 BYTE hash[64];
1212 DWORD hash_size;
1214 ok(bindings.BindingsLength == sizeof(*bindings.Bindings) + sizeof(prefix)-1 + 32 /* hash size */,
1215 "bindings.BindingsLength = %lu\n", bindings.BindingsLength);
1216 ok(!bindings.Bindings->dwInitiatorAddrType, "dwInitiatorAddrType = %lx\n", bindings.Bindings->dwInitiatorAddrType);
1217 ok(!bindings.Bindings->cbInitiatorLength, "cbInitiatorLength = %lx\n", bindings.Bindings->cbInitiatorLength);
1218 ok(!bindings.Bindings->dwInitiatorOffset, "dwInitiatorOffset = %lx\n", bindings.Bindings->dwInitiatorOffset);
1219 ok(!bindings.Bindings->dwAcceptorAddrType, "dwAcceptorAddrType = %lx\n", bindings.Bindings->dwAcceptorAddrType);
1220 ok(!bindings.Bindings->cbAcceptorLength, "cbAcceptorLength = %lx\n", bindings.Bindings->cbAcceptorLength);
1221 ok(!bindings.Bindings->dwAcceptorOffset, "dwAcceptorOffset = %lx\n", bindings.Bindings->dwAcceptorOffset);
1222 ok(sizeof(*bindings.Bindings) + bindings.Bindings->cbApplicationDataLength == bindings.BindingsLength,
1223 "cbApplicationDataLength = %lx\n", bindings.Bindings->cbApplicationDataLength);
1224 ok(bindings.Bindings->dwApplicationDataOffset == sizeof(*bindings.Bindings),
1225 "dwApplicationDataOffset = %lx\n", bindings.Bindings->dwApplicationDataOffset);
1226 p = (const char*)(bindings.Bindings+1);
1227 ok(!memcmp(p, prefix, sizeof(prefix)-1), "missing prefix\n");
1228 p += sizeof(prefix)-1;
1230 hash_size = sizeof(hash);
1231 ret = CryptHashCertificate(0, CALG_SHA_256, 0, cert->pbCertEncoded, cert->cbCertEncoded, hash, &hash_size);
1232 ok(ret, "got %lu\n", GetLastError());
1233 ok(hash_size == 32, "hash_size = %lu\n", hash_size);
1234 ok(!memcmp(hash, p, hash_size), "unexpected hash part\n");
1235 FreeContextBuffer(bindings.Bindings);
1238 status = QueryContextAttributesA(&context, SECPKG_ATTR_UNIQUE_BINDINGS, &bindings);
1239 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_UNIQUE_BINDINGS) failed: %08lx\n", status);
1240 if (status == SEC_E_OK)
1242 const char *p;
1243 static const char prefix[] = "tls-unique:";
1245 ok(bindings.BindingsLength > sizeof(*bindings.Bindings) + sizeof(prefix)-1,
1246 "bindings.BindingsLength = %lu\n", bindings.BindingsLength);
1247 ok(!bindings.Bindings->dwInitiatorAddrType, "dwInitiatorAddrType = %lx\n", bindings.Bindings->dwInitiatorAddrType);
1248 ok(!bindings.Bindings->cbInitiatorLength, "cbInitiatorLength = %lx\n", bindings.Bindings->cbInitiatorLength);
1249 ok(!bindings.Bindings->dwInitiatorOffset, "dwInitiatorOffset = %lx\n", bindings.Bindings->dwInitiatorOffset);
1250 ok(!bindings.Bindings->dwAcceptorAddrType, "dwAcceptorAddrType = %lx\n", bindings.Bindings->dwAcceptorAddrType);
1251 ok(!bindings.Bindings->cbAcceptorLength, "cbAcceptorLength = %lx\n", bindings.Bindings->cbAcceptorLength);
1252 ok(!bindings.Bindings->dwAcceptorOffset, "dwAcceptorOffset = %lx\n", bindings.Bindings->dwAcceptorOffset);
1253 ok(sizeof(*bindings.Bindings) + bindings.Bindings->cbApplicationDataLength == bindings.BindingsLength,
1254 "cbApplicationDataLength = %lx\n", bindings.Bindings->cbApplicationDataLength);
1255 ok(bindings.Bindings->dwApplicationDataOffset == sizeof(*bindings.Bindings),
1256 "dwApplicationDataOffset = %lx\n", bindings.Bindings->dwApplicationDataOffset);
1257 p = (const char*)(bindings.Bindings+1);
1258 ok(!memcmp(p, prefix, sizeof(prefix)-1), "wrong prefix\n");
1259 FreeContextBuffer(bindings.Bindings);
1261 CertFreeCertificateContext(cert);
1264 status = QueryContextAttributesA(&context, SECPKG_ATTR_CONNECTION_INFO, (void*)&conn_info);
1265 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_CONNECTION_INFO) failed: %08lx\n", status);
1266 if(status == SEC_E_OK) {
1267 ok(conn_info.dwCipherStrength >= 128, "conn_info.dwCipherStrength = %ld\n", conn_info.dwCipherStrength);
1268 ok(conn_info.dwHashStrength >= 128, "conn_info.dwHashStrength = %ld\n", conn_info.dwHashStrength);
1271 memset(&cipher, 0, sizeof(cipher));
1272 cipher.dwVersion = SECPKGCONTEXT_CIPHERINFO_V1;
1273 status = QueryContextAttributesA(&context, SECPKG_ATTR_CIPHER_INFO, &cipher);
1274 ok(status == SEC_E_OK, "got %08lx\n", status);
1275 if (status == SEC_E_OK)
1277 ok(cipher.dwProtocol == 0x301, "got %lx\n", cipher.dwProtocol);
1278 todo_wine ok(cipher.dwCipherSuite == 0xc014, "got %lx\n", cipher.dwCipherSuite);
1279 todo_wine ok(cipher.dwBaseCipherSuite == 0xc014, "got %lx\n", cipher.dwBaseCipherSuite);
1280 ok(!wcscmp(cipher.szCipherSuite, L"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA") ||
1281 !wcscmp(cipher.szCipherSuite, L"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256"), /* < win10 */
1282 "got %s\n", wine_dbgstr_w(cipher.szCipherSuite));
1283 ok(!wcscmp(cipher.szCipher, L"AES"), "got %s\n", wine_dbgstr_w(cipher.szCipher));
1284 ok(cipher.dwCipherLen == 256, "got %lu\n", cipher.dwCipherLen);
1285 ok(cipher.dwCipherBlockLen == 16, "got %lu\n", cipher.dwCipherBlockLen);
1286 ok(!wcscmp(cipher.szHash, L"SHA1"), "got %s\n", wine_dbgstr_w(cipher.szHash));
1287 ok(cipher.dwHashLen == 160, "got %lu\n", cipher.dwHashLen);
1288 ok(!wcscmp(cipher.szExchange, L"ECDH") || !wcscmp(cipher.szExchange, L"ECDH_P256"), /* < win10 */
1289 "got %s\n", wine_dbgstr_w(cipher.szExchange));
1290 ok(cipher.dwMinExchangeLen == 0 || cipher.dwMinExchangeLen == 256, /* < win10 */
1291 "got %lu\n", cipher.dwMinExchangeLen);
1292 ok(cipher.dwMaxExchangeLen == 65536 || cipher.dwMaxExchangeLen == 256, /* < win10 */
1293 "got %lu\n", cipher.dwMaxExchangeLen);
1294 ok(!wcscmp(cipher.szCertificate, L"RSA"), "got %s\n", wine_dbgstr_w(cipher.szCertificate));
1295 todo_wine ok(cipher.dwKeyType == 0x1d || cipher.dwKeyType == 0x17, /* < win10 */
1296 "got %#lx\n", cipher.dwKeyType);
1299 status = QueryContextAttributesA(&context, SECPKG_ATTR_KEY_INFO, &key_info);
1300 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_KEY_INFO) failed: %08lx\n", status);
1301 if(status == SEC_E_OK) {
1302 ok(key_info.SignatureAlgorithm == CALG_RSA_SIGN,
1303 "key_info.SignatureAlgorithm = %04lx\n", key_info.SignatureAlgorithm);
1304 ok(!strcmp(key_info.sSignatureAlgorithmName, "RSA"),
1305 "key_info.sSignatureAlgorithmName = %s\n", key_info.sSignatureAlgorithmName);
1306 ok(key_info.KeySize >= 128, "key_info.KeySize = %ld\n", key_info.KeySize);
1309 status = QueryContextAttributesA(&context, SECPKG_ATTR_STREAM_SIZES, &sizes);
1310 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_STREAM_SIZES) failed: %08lx\n", status);
1312 status = QueryContextAttributesA(&context, SECPKG_ATTR_NEGOTIATION_INFO, &info);
1313 ok(status == SEC_E_UNSUPPORTED_FUNCTION, "QueryContextAttributesA returned %08lx\n", status);
1315 reset_buffers(&buffers[0]);
1317 /* Send a simple request so we get data for testing DecryptMessage */
1318 buf = &buffers[0].pBuffers[0];
1319 data = buf->pvBuffer;
1320 buf->BufferType = SECBUFFER_STREAM_HEADER;
1321 buf->cbBuffer = sizes.cbHeader;
1322 ++buf;
1323 buf->BufferType = SECBUFFER_DATA;
1324 buf->pvBuffer = data + sizes.cbHeader;
1325 buf->cbBuffer = sizeof(http_request) - 1;
1326 memcpy(buf->pvBuffer, http_request, sizeof(http_request) - 1);
1327 ++buf;
1328 buf->BufferType = SECBUFFER_STREAM_TRAILER;
1329 buf->pvBuffer = data + sizes.cbHeader + sizeof(http_request) -1;
1330 buf->cbBuffer = sizes.cbTrailer;
1332 status = EncryptMessage(&context, 0, &buffers[0], 0);
1333 ok(status == SEC_E_OK, "EncryptMessage failed: %08lx\n", status);
1334 if (status != SEC_E_OK)
1335 return;
1337 buf = &buffers[0].pBuffers[0];
1338 send(sock, buf->pvBuffer,
1339 buffers[0].pBuffers[0].cbBuffer + buffers[0].pBuffers[1].cbBuffer + buffers[0].pBuffers[2].cbBuffer, 0);
1341 reset_buffers(&buffers[0]);
1342 buf->cbBuffer = buf_size;
1343 data_size = receive_data(sock, buf);
1345 /* Too few buffers */
1346 --buffers[0].cBuffers;
1347 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1348 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08lx\n", status);
1350 /* No data buffer */
1351 ++buffers[0].cBuffers;
1352 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1353 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08lx\n", status);
1355 /* Two data buffers */
1356 buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA;
1357 buffers[0].pBuffers[1].BufferType = SECBUFFER_DATA;
1358 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1359 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08lx\n", status);
1361 /* Too few empty buffers */
1362 buffers[0].pBuffers[1].BufferType = SECBUFFER_EXTRA;
1363 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1364 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08lx\n", status);
1366 /* Incomplete data */
1367 buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY;
1368 buffers[0].pBuffers[0].cbBuffer = (data[3]<<8) | data[4];
1369 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1370 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Expected SEC_E_INCOMPLETE_MESSAGE, got %08lx\n", status);
1371 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_MISSING, "Expected first buffer to be SECBUFFER_MISSING\n");
1372 ok(buffers[0].pBuffers[0].cbBuffer == 5, "Expected first buffer to be a five bytes\n");
1374 /* Renegotiate */
1375 buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA;
1376 buffers[0].pBuffers[0].cbBuffer = data_size;
1377 buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY;
1378 buffers[0].pBuffers[1].cbBuffer = 0;
1379 buffers[0].pBuffers[2].BufferType = SECBUFFER_EMPTY;
1380 buffers[0].pBuffers[2].cbBuffer = 0;
1381 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1382 ok(status == SEC_I_RENEGOTIATE, "Expected SEC_I_RENEGOTIATE, got %08lx\n", status);
1383 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_STREAM_HEADER, "got %lu\n", buffers[0].pBuffers[0].BufferType);
1384 ok(buffers[0].pBuffers[0].cbBuffer == 5, "got %lu\n", buffers[0].pBuffers[0].cbBuffer);
1385 ok(buffers[0].pBuffers[1].BufferType == SECBUFFER_DATA, "got %lu\n", buffers[0].pBuffers[1].BufferType);
1386 ok(buffers[0].pBuffers[1].cbBuffer == 0, "got %lu\n", buffers[0].pBuffers[1].cbBuffer);
1387 ok(buffers[0].pBuffers[2].BufferType == SECBUFFER_STREAM_TRAILER, "got %lu\n", buffers[0].pBuffers[2].BufferType);
1388 todo_wine ok(buffers[0].pBuffers[2].cbBuffer == 32, "got %lu\n", buffers[0].pBuffers[2].cbBuffer);
1390 pfx.pbData = (BYTE *)pfxdata;
1391 pfx.cbData = sizeof(pfxdata);
1392 store = PFXImportCertStore(&pfx, NULL, CRYPT_EXPORTABLE|CRYPT_USER_KEYSET|PKCS12_NO_PERSIST_KEY);
1393 ok(store != NULL, "got %lu\n", GetLastError());
1395 cert = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL);
1396 ok(cert != NULL, "got %lu\n", GetLastError());
1398 cred.paCred = &cert;
1399 cred.cCreds = 1;
1401 FreeCredentialsHandle(&cred_handle);
1402 status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
1403 &cred, NULL, NULL, &cred_handle, NULL);
1404 ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %08lx\n", status);
1406 init_buffers(&buffers[0], 4, buf_size);
1407 init_buffers(&buffers[1], 4, buf_size);
1409 buffers[0].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1410 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1411 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1412 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL);
1413 todo_wine ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08lx\n", status);
1414 if (status != SEC_I_CONTINUE_NEEDED)
1416 skip("skipping remaining renegotiate test\n");
1417 goto done;
1420 buf = &buffers[0].pBuffers[0];
1421 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
1422 buf->cbBuffer = buf_size;
1424 buf = &buffers[1].pBuffers[0];
1425 buf->cbBuffer = buf_size;
1426 ret = receive_data(sock, buf);
1427 if (ret == -1)
1428 return;
1430 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1431 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1432 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM|ISC_REQ_USE_SUPPLIED_CREDS, 0, 0, &buffers[1], 0, &context2,
1433 &buffers[0], &attrs, NULL);
1434 buffers[1].pBuffers[0].cbBuffer = buf_size;
1435 while (status == SEC_I_CONTINUE_NEEDED)
1437 buf = &buffers[0].pBuffers[0];
1438 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
1439 buf->cbBuffer = buf_size;
1441 todo_wine ok( context.dwLower == context2.dwLower, "dwLower mismatch, expected %#Ix, got %#Ix\n",
1442 context.dwLower, context2.dwLower);
1443 todo_wine ok( context.dwUpper == context2.dwUpper, "dwUpper mismatch, expected %#Ix, got %#Ix\n",
1444 context.dwUpper, context2.dwUpper);
1446 buf = &buffers[1].pBuffers[0];
1447 ret = receive_data(sock, buf);
1448 if (ret == -1)
1449 return;
1451 context2.dwLower = context2.dwUpper = 0xdeadbeef;
1452 buf->BufferType = SECBUFFER_TOKEN;
1453 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1454 ISC_REQ_USE_SUPPLIED_CREDS, 0, 0, &buffers[1], 0, &context2, &buffers[0], &attrs, NULL);
1455 buffers[1].pBuffers[0].cbBuffer = buf_size;
1457 ok (status == SEC_E_CERT_EXPIRED, "got %08lx\n", status);
1459 done:
1460 DeleteSecurityContext(&context);
1462 status = QueryContextAttributesW(&context, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (void*)&cert);
1463 ok(status == SEC_E_INVALID_HANDLE, "QueryContextAttributesW(SECPKG_ATTR_REMOTE_CERT_CONTEXT) got %08lx\n", status);
1465 FreeCredentialsHandle(&cred_handle);
1467 CertFreeCertificateContext(cert);
1468 CertCloseStore(store, 0);
1470 free_buffers(&buffers[0]);
1471 free_buffers(&buffers[1]);
1473 closesocket(sock);
1476 static void test_application_protocol_negotiation(void)
1478 int ret;
1479 SOCKET sock;
1480 SECURITY_STATUS status;
1481 ULONG attrs;
1482 SCHANNEL_CRED cred;
1483 CredHandle cred_handle;
1484 CtxtHandle context, context2;
1485 SecPkgContext_ApplicationProtocol protocol;
1486 SecBufferDesc buffers[3];
1487 SecBuffer *buf;
1488 unsigned buf_size = 8192;
1489 unsigned char *alpn_buffer;
1490 unsigned int *extension_len;
1491 unsigned short *list_len;
1492 int list_start_index, offset = 0;
1494 if ((sock = create_ssl_socket( "test.winehq.org" )) == -1) return;
1496 init_cred(&cred);
1497 cred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
1498 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS|SCH_CRED_MANUAL_CRED_VALIDATION;
1500 status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
1501 &cred, NULL, NULL, &cred_handle, NULL);
1502 ok(status == SEC_E_OK, "got %08lx\n", status);
1503 if (status != SEC_E_OK) return;
1505 init_buffers(&buffers[0], 4, buf_size);
1506 init_buffers(&buffers[1], 4, buf_size);
1507 init_buffers(&buffers[2], 1, 128);
1509 alpn_buffer = buffers[2].pBuffers[0].pvBuffer;
1510 extension_len = (unsigned int *)&alpn_buffer[offset];
1511 offset += sizeof(*extension_len);
1512 *(unsigned int *)&alpn_buffer[offset] = SecApplicationProtocolNegotiationExt_ALPN;
1513 offset += sizeof(unsigned int);
1514 list_len = (unsigned short *)&alpn_buffer[offset];
1515 offset += sizeof(*list_len);
1516 list_start_index = offset;
1518 alpn_buffer[offset++] = sizeof("http/1.1") - 1;
1519 memcpy(&alpn_buffer[offset], "http/1.1", sizeof("http/1.1") - 1);
1520 offset += sizeof("http/1.1") - 1;
1521 alpn_buffer[offset++] = sizeof("h2") - 1;
1522 memcpy(&alpn_buffer[offset], "h2", sizeof("h2") - 1);
1523 offset += sizeof("h2") - 1;
1525 *list_len = offset - list_start_index;
1526 *extension_len = *list_len + sizeof(*extension_len) + sizeof(*list_len);
1528 buffers[2].pBuffers[0].BufferType = SECBUFFER_APPLICATION_PROTOCOLS;
1529 buffers[2].pBuffers[0].cbBuffer = offset;
1531 buffers[0].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1532 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
1533 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, &buffers[2], 0, &context, &buffers[0], &attrs, NULL);
1534 ok(status == SEC_I_CONTINUE_NEEDED, "got %08lx\n", status);
1536 buf = &buffers[0].pBuffers[0];
1537 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
1538 buf->cbBuffer = buf_size;
1540 buf = &buffers[1].pBuffers[0];
1541 buf->cbBuffer = buf_size;
1542 ret = receive_data(sock, buf);
1543 if (ret == -1)
1544 return;
1546 context2.dwLower = context2.dwUpper = 0xdeadbeef;
1547 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1548 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1549 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM|ISC_REQ_USE_SUPPLIED_CREDS, 0, 0, &buffers[1], 0, &context2,
1550 &buffers[0], &attrs, NULL);
1551 buffers[1].pBuffers[0].cbBuffer = buf_size;
1552 while (status == SEC_I_CONTINUE_NEEDED)
1554 buf = &buffers[0].pBuffers[0];
1555 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
1556 buf->cbBuffer = buf_size;
1558 ok( context.dwLower == context2.dwLower, "dwLower mismatch, expected %#Ix, got %#Ix\n",
1559 context.dwLower, context2.dwLower);
1560 ok( context.dwUpper == context2.dwUpper, "dwUpper mismatch, expected %#Ix, got %#Ix\n",
1561 context.dwUpper, context2.dwUpper);
1563 buf = &buffers[1].pBuffers[0];
1564 ret = receive_data(sock, buf);
1565 if (ret == -1)
1566 return;
1568 context2.dwLower = context2.dwUpper = 0xdeadbeef;
1569 buf->BufferType = SECBUFFER_TOKEN;
1570 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1571 ISC_REQ_USE_SUPPLIED_CREDS, 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1572 buffers[1].pBuffers[0].cbBuffer = buf_size;
1575 ok (status == SEC_E_OK, "got %08lx\n", status);
1576 if (status != SEC_E_OK)
1578 skip("Handshake failed\n");
1579 return;
1582 memset(&protocol, 0, sizeof(protocol));
1583 status = QueryContextAttributesA(&context, SECPKG_ATTR_APPLICATION_PROTOCOL, &protocol);
1584 ok(status == SEC_E_OK || broken(status == SEC_E_UNSUPPORTED_FUNCTION) /* < win8 */, "got %08lx\n", status);
1585 if (status == SEC_E_OK)
1587 ok(protocol.ProtoNegoStatus == SecApplicationProtocolNegotiationStatus_Success, "got %u\n", protocol.ProtoNegoStatus);
1588 ok(protocol.ProtoNegoExt == SecApplicationProtocolNegotiationExt_ALPN, "got %u\n", protocol.ProtoNegoExt);
1589 ok(protocol.ProtocolIdSize == 8, "got %u\n", protocol.ProtocolIdSize);
1590 ok(!memcmp(protocol.ProtocolId, "http/1.1", 8), "wrong protocol id\n");
1593 DeleteSecurityContext(&context);
1594 FreeCredentialsHandle(&cred_handle);
1596 free_buffers(&buffers[0]);
1597 free_buffers(&buffers[1]);
1598 free_buffers(&buffers[2]);
1600 closesocket(sock);
1603 static void test_server_protocol_negotiation(void) {
1604 BOOL ret;
1605 SECURITY_STATUS status;
1606 ULONG attrs;
1607 SCHANNEL_CRED client_cred, server_cred;
1608 CredHandle client_cred_handle, server_cred_handle;
1609 CtxtHandle client_context, server_context, client_context2, server_context2;
1610 SecPkgContext_ApplicationProtocol protocol;
1611 SecBufferDesc buffers[3];
1612 PCCERT_CONTEXT cert;
1613 HCRYPTPROV csp;
1614 HCRYPTKEY key;
1615 CRYPT_KEY_PROV_INFO keyProvInfo;
1616 WCHAR ms_def_prov_w[MAX_PATH];
1617 unsigned buf_size = 8192;
1618 unsigned char *alpn_buffer;
1619 unsigned int *extension_len;
1620 unsigned short *list_len;
1621 int list_start_index, offset = 0;
1623 lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
1624 keyProvInfo.pwszContainerName = cspNameW;
1625 keyProvInfo.pwszProvName = ms_def_prov_w;
1626 keyProvInfo.dwProvType = PROV_RSA_FULL;
1627 keyProvInfo.dwFlags = 0;
1628 keyProvInfo.cProvParam = 0;
1629 keyProvInfo.rgProvParam = NULL;
1630 keyProvInfo.dwKeySpec = AT_SIGNATURE;
1632 cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert, sizeof(selfSignedCert));
1633 ret = CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo);
1634 ok(ret, "CertSetCertificateContextProperty failed: %08lx", GetLastError());
1635 ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET);
1636 ok(ret, "CryptAcquireContextW failed: %08lx\n", GetLastError());
1637 ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
1638 ok(ret, "CryptImportKey failed: %08lx\n", GetLastError());
1639 if (!ret) return;
1641 init_cred(&client_cred);
1642 init_cred(&server_cred);
1643 client_cred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
1644 client_cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS|SCH_CRED_MANUAL_CRED_VALIDATION;
1645 server_cred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER;
1646 server_cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS|SCH_CRED_MANUAL_CRED_VALIDATION;
1647 server_cred.cCreds = 1;
1648 server_cred.paCred = &cert;
1650 status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL, &client_cred,
1651 NULL, NULL, &client_cred_handle, NULL);
1652 ok(status == SEC_E_OK, "got %08lx\n", status);
1653 if (status != SEC_E_OK) return;
1654 status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_INBOUND, NULL, &server_cred,
1655 NULL, NULL, &server_cred_handle, NULL);
1656 ok(status == SEC_E_OK, "got %08lx\n", status);
1657 if (status != SEC_E_OK) return;
1659 init_buffers(&buffers[0], 4, buf_size);
1660 init_buffers(&buffers[1], 4, buf_size);
1661 init_buffers(&buffers[2], 1, 128);
1663 alpn_buffer = buffers[2].pBuffers[0].pvBuffer;
1664 extension_len = (unsigned int *)&alpn_buffer[offset];
1665 offset += sizeof(*extension_len);
1666 *(unsigned int *)&alpn_buffer[offset] = SecApplicationProtocolNegotiationExt_ALPN;
1667 offset += sizeof(unsigned int);
1668 list_len = (unsigned short *)&alpn_buffer[offset];
1669 offset += sizeof(*list_len);
1670 list_start_index = offset;
1672 alpn_buffer[offset++] = sizeof("http/1.1") - 1;
1673 memcpy(&alpn_buffer[offset], "http/1.1", sizeof("http/1.1") - 1);
1674 offset += sizeof("http/1.1") - 1;
1675 alpn_buffer[offset++] = sizeof("h2") - 1;
1676 memcpy(&alpn_buffer[offset], "h2", sizeof("h2") - 1);
1677 offset += sizeof("h2") - 1;
1679 *list_len = offset - list_start_index;
1680 *extension_len = *list_len + sizeof(*extension_len) + sizeof(*list_len);
1682 buffers[2].pBuffers[0].BufferType = SECBUFFER_APPLICATION_PROTOCOLS;
1683 buffers[2].pBuffers[0].cbBuffer = offset;
1684 buffers[0].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1685 status = InitializeSecurityContextA(&client_cred_handle, NULL, (SEC_CHAR *)"localhost",
1686 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, &buffers[2], 0,
1687 &client_context, &buffers[0], &attrs, NULL);
1688 ok(status == SEC_I_CONTINUE_NEEDED, "got %08lx\n", status);
1690 buffers[1].pBuffers[0].cbBuffer = buf_size;
1691 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1692 buffers[0].pBuffers[1] = buffers[2].pBuffers[0];
1693 status = AcceptSecurityContext(&server_cred_handle, NULL, &buffers[0], ASC_REQ_CONFIDENTIALITY|ASC_REQ_STREAM,
1694 0, &server_context, &buffers[1], &attrs, NULL);
1695 ok(status == SEC_I_CONTINUE_NEEDED, "got %08lx\n", status);
1696 memset(&buffers[0].pBuffers[1], 0, sizeof(buffers[0].pBuffers[1]));
1698 client_context2.dwLower = client_context2.dwUpper = 0xdeadbeef;
1699 buffers[0].pBuffers[0].cbBuffer = buf_size;
1700 status = InitializeSecurityContextA(&client_cred_handle, &client_context, (SEC_CHAR *)"localhost",
1701 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM|ISC_REQ_USE_SUPPLIED_CREDS, 0, 0,
1702 &buffers[1], 0, &client_context2, &buffers[0], &attrs, NULL);
1703 ok(client_context.dwLower == client_context2.dwLower, "dwLower mismatch, expected %#Ix, got %#Ix\n",
1704 client_context.dwLower, client_context2.dwLower);
1705 ok(client_context.dwUpper == client_context2.dwUpper, "dwUpper mismatch, expected %#Ix, got %#Ix\n",
1706 client_context.dwUpper, client_context2.dwUpper);
1707 ok(status == SEC_I_CONTINUE_NEEDED, "got %08lx\n", status);
1709 server_context2.dwLower = server_context2.dwUpper = 0xdeadbeef;
1710 buffers[1].pBuffers[0].cbBuffer = buf_size;
1711 status = AcceptSecurityContext(&server_cred_handle, &server_context, &buffers[0],
1712 ASC_REQ_CONFIDENTIALITY|ASC_REQ_STREAM, 0, &server_context2, &buffers[1],
1713 &attrs, NULL);
1714 ok(server_context.dwLower == server_context2.dwLower, "dwLower mismatch, expected %#Ix, got %#Ix\n",
1715 server_context.dwLower, server_context2.dwLower);
1716 ok(server_context.dwUpper == server_context2.dwUpper, "dwUpper mismatch, expected %#Ix, got %#Ix\n",
1717 server_context.dwUpper, server_context2.dwUpper);
1718 ok(status == SEC_E_OK, "got %08lx\n", status);
1720 buffers[0].pBuffers[0].cbBuffer = buf_size;
1721 status = InitializeSecurityContextA(&client_cred_handle, &client_context, (SEC_CHAR *)"localhost",
1722 ISC_REQ_USE_SUPPLIED_CREDS, 0, 0, &buffers[1], 0, NULL, &buffers[0],
1723 &attrs, NULL);
1724 ok(status == SEC_E_OK, "got %08lx\n", status);
1726 memset(&protocol, 0, sizeof(protocol));
1727 status = QueryContextAttributesA(&client_context, SECPKG_ATTR_APPLICATION_PROTOCOL, &protocol);
1728 ok(status == SEC_E_OK || broken(status == SEC_E_UNSUPPORTED_FUNCTION) /* < win8 */, "got %08lx\n", status);
1729 if (status == SEC_E_OK)
1731 ok(protocol.ProtoNegoStatus == SecApplicationProtocolNegotiationStatus_Success, "got %u\n",
1732 protocol.ProtoNegoStatus);
1733 ok(protocol.ProtoNegoExt == SecApplicationProtocolNegotiationExt_ALPN, "got %u\n", protocol.ProtoNegoExt);
1734 ok(protocol.ProtocolIdSize == 8, "got %u\n", protocol.ProtocolIdSize);
1735 ok(!memcmp(protocol.ProtocolId, "http/1.1", 8), "wrong protocol id\n");
1738 DeleteSecurityContext(&client_context);
1739 DeleteSecurityContext(&server_context);
1740 FreeCredentialsHandle(&client_cred_handle);
1741 FreeCredentialsHandle(&server_cred_handle);
1743 free_buffers(&buffers[0]);
1744 free_buffers(&buffers[1]);
1745 free_buffers(&buffers[2]);
1747 CryptDestroyKey(key);
1748 CryptReleaseContext(csp, 0);
1749 CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
1750 CertFreeCertificateContext(cert);
1753 static void init_dtls_output_buffer(SecBufferDesc *buffer)
1755 buffer->pBuffers[0].BufferType = SECBUFFER_TOKEN;
1756 buffer->pBuffers[0].cbBuffer = 1420;
1757 buffer->pBuffers[1].BufferType = SECBUFFER_ALERT;
1758 buffer->pBuffers[1].cbBuffer = 1024;
1759 if (!buffer->pBuffers[1].pvBuffer)
1760 buffer->pBuffers[1].pvBuffer = HeapAlloc( GetProcessHeap(), 0, 1024 );
1763 static void test_dtls(void)
1765 SECURITY_STATUS status;
1766 TimeStamp exp;
1767 SCHANNEL_CRED cred;
1768 CredHandle cred_handle, cred_handle2;
1769 CtxtHandle ctx_handle, ctx_handle2;
1770 SecBufferDesc buffers[3];
1771 ULONG flags_req, flags_ret, attr, prev_buf_len;
1772 char *buf, *buf2;
1774 init_cred( &cred );
1775 cred.grbitEnabledProtocols = SP_PROT_DTLS_CLIENT | SP_PROT_DTLS1_2_CLIENT;
1776 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS;
1778 status = AcquireCredentialsHandleA( NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL,
1779 &cred_handle, &exp );
1780 if (status == SEC_E_ALGORITHM_MISMATCH)
1782 win_skip( "no DTLS support\n" );
1783 return;
1785 ok( status == SEC_E_OK, "got %08lx\n", status );
1787 /* Should fail if both DTLS and TLS protocols are requested */
1788 cred.grbitEnabledProtocols |= SP_PROT_TLS1_CLIENT;
1789 status = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL,
1790 &cred_handle2, &exp);
1791 ok(status == SEC_E_ALGORITHM_MISMATCH, "status = %08lx\n", status);
1793 cred.grbitEnabledProtocols = SP_PROT_DTLS1_X_CLIENT | SP_PROT_TLS1_SERVER;
1794 status = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL,
1795 &cred_handle2, &exp);
1796 ok(status == SEC_E_ALGORITHM_MISMATCH, "status = got %08lx\n", status);
1798 cred.grbitEnabledProtocols = SP_PROT_DTLS1_X_CLIENT | SP_PROT_SSL3_SERVER;
1799 status = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL,
1800 &cred_handle2, &exp);
1801 ok(status == SEC_E_ALGORITHM_MISMATCH, "status = got %08lx\n", status);
1803 flags_req = ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_EXTENDED_ERROR | ISC_REQ_DATAGRAM |
1804 ISC_REQ_USE_SUPPLIED_CREDS | ISC_REQ_CONFIDENTIALITY | ISC_REQ_SEQUENCE_DETECT |
1805 ISC_REQ_REPLAY_DETECT;
1806 test_context_output_buffer_size(SP_PROT_DTLS_CLIENT | SP_PROT_DTLS1_2_CLIENT, SCH_CRED_NO_DEFAULT_CREDS,
1807 flags_req);
1809 init_buffers( &buffers[0], 1, 128 );
1810 buffers[0].pBuffers[0].BufferType = SECBUFFER_DTLS_MTU;
1811 *(WORD *)(buffers[0].pBuffers[0].pvBuffer) = 1024;
1812 buffers[0].pBuffers[0].cbBuffer = 2;
1814 init_buffers( &buffers[1], 2, 2048 );
1815 init_dtls_output_buffer(&buffers[1]);
1817 attr = 0;
1818 exp.LowPart = exp.HighPart = 0xdeadbeef;
1819 status = InitializeSecurityContextA( &cred_handle, NULL, (SEC_CHAR *)"winetest", flags_req, 0, 16, &buffers[0], 0,
1820 &ctx_handle, &buffers[1], &attr, &exp );
1821 ok( status == SEC_I_CONTINUE_NEEDED, "got %08lx\n", status );
1823 flags_ret = ISC_RET_MANUAL_CRED_VALIDATION | ISC_RET_STREAM | ISC_RET_EXTENDED_ERROR |
1824 ISC_RET_DATAGRAM | ISC_RET_USED_SUPPLIED_CREDS | ISC_RET_CONFIDENTIALITY |
1825 ISC_RET_SEQUENCE_DETECT | ISC_RET_REPLAY_DETECT;
1826 ok( attr == flags_ret, "got %08lx\n", attr );
1827 ok( !exp.LowPart, "got %08lx\n", exp.LowPart );
1828 ok( !exp.HighPart, "got %08lx\n", exp.HighPart );
1829 ok( buffers[1].pBuffers[1].BufferType == SECBUFFER_ALERT, "Expected buffertype SECBUFFER_ALERT, got %#lx\n",
1830 buffers[1].pBuffers[1].BufferType);
1831 ok( !buffers[1].pBuffers[1].cbBuffer, "Expected SECBUFFER_ALERT buffer to be empty, got %#lx\n",
1832 buffers[1].pBuffers[1].cbBuffer);
1833 prev_buf_len = buffers[1].pBuffers[0].cbBuffer;
1834 buf = HeapAlloc( GetProcessHeap(), 0, prev_buf_len );
1835 memcpy( buf, buffers[1].pBuffers[0].pvBuffer, prev_buf_len );
1836 ok( buf[10] == 0, "Expected initial packet to have sequence number value of 0, got %d\n", buf[10]);
1838 /* If we don't set the SECBUFFER_ALERT cbBuffer value we will get SEC_E_INSUFFICIENT_MEMORY. */
1839 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1840 buffers[1].pBuffers[0].cbBuffer = 1420;
1842 attr = 0;
1843 exp.LowPart = exp.HighPart = 0xdeadbeef;
1844 ctx_handle2.dwLower = ctx_handle2.dwUpper = 0xdeadbeef;
1845 status = InitializeSecurityContextA( &cred_handle, &ctx_handle, (SEC_CHAR *)"winetest", flags_req, 0, 16, NULL, 0,
1846 &ctx_handle2, &buffers[1], &attr, &exp );
1847 ok( status == SEC_E_INSUFFICIENT_MEMORY, "got %08lx\n", status );
1849 flags_ret = ISC_RET_CONFIDENTIALITY | ISC_RET_SEQUENCE_DETECT | ISC_RET_REPLAY_DETECT;
1850 todo_wine ok( attr == flags_ret, "got %08lx\n", attr );
1851 ok( !exp.LowPart, "got %08lx\n", exp.LowPart );
1852 ok( !exp.HighPart, "got %08lx\n", exp.HighPart );
1853 ok( ctx_handle2.dwLower == 0xdeadbeef, "Did not expect dwLower to be set on new context\n");
1854 ok( ctx_handle2.dwUpper == 0xdeadbeef, "Did not expect dwUpper to be set on new context\n");
1856 /* No new input buffer value, just repeats the same behavior as before. */
1857 init_dtls_output_buffer(&buffers[1]);
1859 attr = 0;
1860 exp.LowPart = exp.HighPart = 0xdeadbeef;
1861 ctx_handle2.dwLower = ctx_handle2.dwUpper = 0xdeadbeef;
1862 status = InitializeSecurityContextA( &cred_handle, &ctx_handle, (SEC_CHAR *)"winetest", flags_req, 0, 16, NULL, 0,
1863 &ctx_handle2, &buffers[1], &attr, &exp );
1864 ok( status == SEC_I_CONTINUE_NEEDED, "got %08lx\n", status );
1866 flags_ret = ISC_RET_MANUAL_CRED_VALIDATION | ISC_RET_STREAM | ISC_RET_EXTENDED_ERROR |
1867 ISC_RET_DATAGRAM | ISC_RET_USED_SUPPLIED_CREDS | ISC_RET_CONFIDENTIALITY |
1868 ISC_RET_SEQUENCE_DETECT | ISC_RET_REPLAY_DETECT;
1869 ok( attr == flags_ret, "got %08lx\n", attr );
1870 todo_wine ok( exp.LowPart, "got %08lx\n", exp.LowPart );
1871 todo_wine ok( exp.HighPart, "got %08lx\n", exp.HighPart );
1872 ok( buffers[1].pBuffers[1].BufferType == SECBUFFER_ALERT, "Expected buffertype SECBUFFER_ALERT, got %#lx\n",
1873 buffers[1].pBuffers[1].BufferType);
1874 ok( !buffers[1].pBuffers[1].cbBuffer, "Expected SECBUFFER_ALERT buffer to be empty, got %#lx\n",
1875 buffers[1].pBuffers[1].cbBuffer);
1876 ok( ctx_handle.dwLower == ctx_handle2.dwLower, "dwLower mismatch, expected %#Ix, got %#Ix\n",
1877 ctx_handle.dwLower, ctx_handle2.dwLower);
1878 ok( ctx_handle.dwUpper == ctx_handle2.dwUpper, "dwUpper mismatch, expected %#Ix, got %#Ix\n",
1879 ctx_handle.dwUpper, ctx_handle2.dwUpper);
1881 /* With no new input buffer, output buffer length should match prior call. */
1882 ok(buffers[1].pBuffers[0].cbBuffer == prev_buf_len, "Output buffer size mismatch, expected %#lx, got %#lx\n",
1883 prev_buf_len, buffers[1].pBuffers[0].cbBuffer);
1885 /* The retransmission packet and the original packet should only differ in their sequence number value. */
1886 buf2 = (char *)buffers[1].pBuffers[0].pvBuffer;
1887 ok( buf2[10] == 1, "Expected retransmitted packet to have sequence number value of 1, got %d\n", buf2[10]);
1888 ok( !memcmp(buf2, buf, 9), "Lower portion mismatch between retransmitted packet and original packet\n");
1889 ok( !memcmp(buf2 + 11, buf + 11, prev_buf_len - 11),
1890 "Upper portion mismatch between retransmitted packet and original packet\n");
1892 free_buffers( &buffers[0] );
1893 HeapFree(GetProcessHeap(), 0, buf);
1894 HeapFree(GetProcessHeap(), 0, buffers[1].pBuffers[1].pvBuffer);
1895 free_buffers( &buffers[1] );
1896 DeleteSecurityContext( &ctx_handle );
1897 FreeCredentialsHandle( &cred_handle );
1900 static void test_connection_shutdown(void)
1902 static const BYTE message[] = {0x15, 0x03, 0x01, 0x00, 0x02, 0x01, 0x00};
1903 static const BYTE message2[] = {0x15, 0x03, 0x01, 0x00, 0x02, 0x02, 0x2a};
1904 CtxtHandle context, context2;
1905 SecBufferDesc buffers[2];
1906 SECURITY_STATUS status;
1907 CredHandle cred_handle;
1908 SCHANNEL_CRED cred;
1909 SecBuffer *buf;
1910 SCHANNEL_ALERT_TOKEN alert;
1911 ULONG attrs;
1912 void *tmp;
1914 init_cred(&cred);
1915 cred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
1916 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_MANUAL_CRED_VALIDATION;
1918 status = AcquireCredentialsHandleA( NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
1919 &cred, NULL, NULL, &cred_handle, NULL );
1920 ok( status == SEC_E_OK, "got %08lx\n", status );
1922 init_buffers( &buffers[0], 2, 24 );
1923 init_buffers( &buffers[1], 1, 1000 );
1924 buffers[0].cBuffers = 1;
1925 buffers[0].pBuffers[0].BufferType = SECBUFFER_EMPTY;
1926 buffers[1].cBuffers = 1;
1927 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1928 buffers[1].pBuffers[0].cbBuffer = 1000;
1929 tmp = buffers[1].pBuffers[0].pvBuffer;
1930 buffers[1].pBuffers[0].pvBuffer = NULL;
1931 status = InitializeSecurityContextA( &cred_handle, NULL, (SEC_CHAR *)"localhost",
1932 ISC_REQ_CONFIDENTIALITY | ISC_REQ_STREAM,
1933 0, 0, &buffers[0], 0, &context, &buffers[1], &attrs, NULL );
1934 ok( status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08lx\n", status );
1935 ok( !!buffers[1].pBuffers[0].pvBuffer, "Got NULL buffer.\n" );
1936 FreeContextBuffer( buffers[1].pBuffers[0].pvBuffer );
1937 buffers[1].pBuffers[0].pvBuffer = tmp;
1939 buf = &buffers[0].pBuffers[0];
1940 buffers[0].cBuffers = 2;
1941 buf->cbBuffer = sizeof(DWORD);
1942 *(DWORD *)buf->pvBuffer = SCHANNEL_SHUTDOWN;
1943 buf->BufferType = SECBUFFER_TOKEN;
1944 buffers[0].pBuffers[1] = buffers[0].pBuffers[0];
1946 status = ApplyControlToken( &context, buffers );
1947 ok( status == SEC_E_INVALID_TOKEN, "got %08lx.\n", status );
1949 buffers[0].pBuffers[1].cbBuffer = 0;
1950 buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY;
1951 status = ApplyControlToken( &context, buffers );
1952 ok( status == SEC_E_INVALID_TOKEN, "got %08lx.\n", status );
1954 *(DWORD *)buf->pvBuffer = SCHANNEL_RENEGOTIATE;
1955 buffers[0].cBuffers = 1;
1956 status = ApplyControlToken( &context, buffers );
1957 ok( status == SEC_E_UNSUPPORTED_FUNCTION, "got %08lx.\n", status );
1959 status = ApplyControlToken(NULL, buffers);
1960 ok( status == SEC_E_INVALID_HANDLE, "got %08lx.\n", status );
1962 status = ApplyControlToken( &context, NULL );
1963 ok( status == SEC_E_INTERNAL_ERROR, "got %08lx.\n", status );
1965 *(DWORD *)buf->pvBuffer = SCHANNEL_SHUTDOWN;
1967 buf->BufferType = SECBUFFER_ALERT;
1968 status = ApplyControlToken( &context, buffers );
1969 ok( status == SEC_E_INVALID_TOKEN, "got %08lx.\n", status );
1970 buf->BufferType = SECBUFFER_DATA;
1971 status = ApplyControlToken( &context, buffers );
1972 ok( status == SEC_E_INVALID_TOKEN, "got %08lx.\n", status );
1974 buf->BufferType = SECBUFFER_TOKEN;
1976 buf->cbBuffer = 2;
1977 status = ApplyControlToken( &context, buffers );
1978 ok( status == SEC_E_UNSUPPORTED_FUNCTION, "got %08lx.\n", status );
1980 buf->cbBuffer = sizeof(DWORD) + 1;
1981 status = ApplyControlToken( &context, buffers );
1982 ok( status == SEC_E_OK, "got %08lx.\n", status );
1984 status = ApplyControlToken( &context, buffers );
1985 ok( status == SEC_E_OK, "got %08lx.\n", status );
1987 buf->cbBuffer = 1000;
1988 buf->BufferType = SECBUFFER_TOKEN;
1989 context2.dwLower = context2.dwUpper = 0xdeadbeef;
1990 status = InitializeSecurityContextA( &cred_handle, &context, NULL, 0, 0, 0, &buffers[1], 0,
1991 &context2, &buffers[0], &attrs, NULL );
1992 ok( status == SEC_E_OK, "got %08lx.\n", status );
1993 ok( context.dwLower == context2.dwLower, "dwLower mismatch, expected %#Ix, got %#Ix\n",
1994 context.dwLower, context2.dwLower );
1995 ok( context.dwUpper == context2.dwUpper, "dwUpper mismatch, expected %#Ix, got %#Ix\n",
1996 context.dwUpper, context2.dwUpper );
1997 ok( buf->cbBuffer == sizeof(message), "got cbBuffer %#lx.\n", buf->cbBuffer );
1998 ok( !memcmp( buf->pvBuffer, message, sizeof(message) ), "message data mismatch.\n" );
2000 buf->BufferType = SECBUFFER_TOKEN;
2001 buf->cbBuffer = 1000;
2002 context2.dwLower = context2.dwUpper = 0xdeadbeef;
2003 status = InitializeSecurityContextA( &cred_handle, &context, NULL, 0, 0, 0, NULL, 0,
2004 &context2, &buffers[1], &attrs, NULL );
2005 ok( status == SEC_E_INCOMPLETE_MESSAGE, "got %08lx.\n", status );
2006 ok( buf->cbBuffer == 1000, "got cbBuffer %#lx.\n", buf->cbBuffer );
2007 ok( context2.dwLower == 0xdeadbeef, "dwLower mismatch, got %#Ix\n", context2.dwLower );
2008 ok( context2.dwUpper == 0xdeadbeef, "dwUpper mismatch, got %#Ix\n", context2.dwUpper );
2010 buf->cbBuffer = sizeof(DWORD);
2011 *(DWORD *)buf->pvBuffer = SCHANNEL_SHUTDOWN;
2012 buf->BufferType = SECBUFFER_TOKEN;
2013 status = ApplyControlToken( &context, buffers );
2014 ok( status == SEC_E_OK, "got %08lx.\n", status );
2016 buffers[1].pBuffers[0].cbBuffer = 1000;
2017 status = InitializeSecurityContextA( &cred_handle, &context, NULL, 0, 0, 0,
2018 NULL, 0, NULL, &buffers[1], &attrs, NULL );
2019 ok( status == SEC_E_OK, "got %08lx.\n", status );
2020 ok( buffers[1].pBuffers[0].cbBuffer == sizeof(message), "got cbBuffer %#lx.\n", buffers[1].pBuffers[0].cbBuffer );
2021 ok( !memcmp( buffers[1].pBuffers[0].pvBuffer, message, sizeof(message) ), "message data mismatch.\n" );
2023 alert.dwTokenType = SCHANNEL_ALERT;
2024 alert.dwAlertType = TLS1_ALERT_FATAL;
2025 alert.dwAlertNumber = TLS1_ALERT_BAD_CERTIFICATE;
2026 memcpy(buf->pvBuffer, &alert, sizeof(alert));
2027 buf->cbBuffer = sizeof(alert);
2028 status = ApplyControlToken( &context, buffers );
2029 ok( status == SEC_E_OK, "got %08lx.\n", status );
2031 buffers[1].pBuffers[0].cbBuffer = 1000;
2032 status = InitializeSecurityContextA( &cred_handle, &context, NULL, 0, 0, 0,
2033 NULL, 0, NULL, &buffers[1], &attrs, NULL );
2034 ok( status == SEC_E_OK, "got %08lx.\n", status );
2035 ok( buffers[1].pBuffers[0].cbBuffer == sizeof(message2), "got cbBuffer %#lx.\n", buffers[1].pBuffers[0].cbBuffer );
2036 ok( !memcmp( buffers[1].pBuffers[0].pvBuffer, message2, sizeof(message2) ), "message data mismatch.\n" );
2038 free_buffers( &buffers[0] );
2039 free_buffers( &buffers[1] );
2040 DeleteSecurityContext( &context );
2041 FreeCredentialsHandle( &cred_handle );
2044 START_TEST(schannel)
2046 WSADATA wsa_data;
2048 WSAStartup(0x0202, &wsa_data);
2050 test_cread_attrs();
2051 testAcquireSecurityContext();
2052 test_InitializeSecurityContext();
2053 test_communication();
2054 test_application_protocol_negotiation();
2055 test_server_protocol_negotiation();
2056 test_dtls();
2057 test_connection_shutdown();