d2d1: Create feature level 10.0 device context state objects.
[wine.git] / dlls / secur32 / tests / schannel.c
blob7cb3871193c576ea4c70d08d0362d3fe4c131b6f
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 #include <schannel.h>
30 #include "wine/test.h"
32 static QUERY_CONTEXT_ATTRIBUTES_FN_A pQueryContextAttributesA;
34 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
35 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
36 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
37 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
38 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
39 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
40 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
41 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
42 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
43 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
44 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
45 'm','p',0 };
46 static BYTE privKey[] = {
47 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
48 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
49 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
50 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
51 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
52 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
53 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
54 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
55 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
56 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
57 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
58 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
59 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
60 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
61 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
62 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
63 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
64 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
65 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
66 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
67 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
68 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
69 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
70 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
72 static const BYTE selfSignedCert[] = {
73 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
74 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
75 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
76 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
77 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
78 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
79 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
80 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
81 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
82 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
83 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
84 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
85 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
86 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
87 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
88 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
89 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
90 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
91 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
92 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
93 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
94 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
95 0xa8, 0x76, 0x57, 0x92, 0x36 };
97 static CHAR unisp_name_a[] = UNISP_NAME_A;
99 static const char *algid_to_str(ALG_ID alg)
101 static char buf[12];
102 switch(alg) {
103 #define X(x) case x: return #x
104 X(CALG_MD2);
105 X(CALG_MD4);
106 X(CALG_MD5);
107 X(CALG_SHA1); /* same as CALG_SHA */
108 X(CALG_MAC);
109 X(CALG_RSA_SIGN);
110 X(CALG_DSS_SIGN);
111 X(CALG_NO_SIGN);
112 X(CALG_RSA_KEYX);
113 X(CALG_DES);
114 X(CALG_3DES_112);
115 X(CALG_3DES);
116 X(CALG_DESX);
117 X(CALG_RC2);
118 X(CALG_RC4);
119 X(CALG_SEAL);
120 X(CALG_DH_SF);
121 X(CALG_DH_EPHEM);
122 X(CALG_AGREEDKEY_ANY);
123 X(CALG_KEA_KEYX);
124 X(CALG_HUGHES_MD5);
125 X(CALG_SKIPJACK);
126 X(CALG_TEK);
127 X(CALG_CYLINK_MEK);
128 X(CALG_SSL3_SHAMD5);
129 X(CALG_SSL3_MASTER);
130 X(CALG_SCHANNEL_MASTER_HASH);
131 X(CALG_SCHANNEL_MAC_KEY);
132 X(CALG_SCHANNEL_ENC_KEY);
133 X(CALG_PCT1_MASTER);
134 X(CALG_SSL2_MASTER);
135 X(CALG_TLS1_MASTER);
136 X(CALG_RC5);
137 X(CALG_HMAC);
138 X(CALG_TLS1PRF);
139 X(CALG_HASH_REPLACE_OWF);
140 X(CALG_AES_128);
141 X(CALG_AES_192);
142 X(CALG_AES_256);
143 X(CALG_AES);
144 X(CALG_SHA_256);
145 X(CALG_SHA_384);
146 X(CALG_SHA_512);
147 X(CALG_ECDH);
148 X(CALG_ECMQV);
149 X(CALG_ECDSA);
150 #undef X
153 sprintf(buf, "%x", alg);
154 return buf;
157 static void init_cred(SCHANNEL_CRED *cred)
159 cred->dwVersion = SCHANNEL_CRED_VERSION;
160 cred->cCreds = 0;
161 cred->paCred = 0;
162 cred->hRootStore = NULL;
163 cred->cMappers = 0;
164 cred->aphMappers = NULL;
165 cred->cSupportedAlgs = 0;
166 cred->palgSupportedAlgs = NULL;
167 cred->grbitEnabledProtocols = 0;
168 cred->dwMinimumCipherStrength = 0;
169 cred->dwMaximumCipherStrength = 0;
170 cred->dwSessionLifespan = 0;
171 cred->dwFlags = 0;
174 static void test_strength(PCredHandle handle)
176 SecPkgCred_CipherStrengths strength = {-1,-1};
177 SECURITY_STATUS st;
179 st = QueryCredentialsAttributesA(handle, SECPKG_ATTR_CIPHER_STRENGTHS, &strength);
180 ok(st == SEC_E_OK, "QueryCredentialsAttributesA failed: %u\n", GetLastError());
181 ok(strength.dwMinimumCipherStrength, "dwMinimumCipherStrength not changed\n");
182 ok(strength.dwMaximumCipherStrength, "dwMaximumCipherStrength not changed\n");
183 trace("strength %d - %d\n", strength.dwMinimumCipherStrength, strength.dwMaximumCipherStrength);
186 static void test_supported_protocols(CredHandle *handle, unsigned exprots)
188 SecPkgCred_SupportedProtocols protocols;
189 SECURITY_STATUS status;
191 status = QueryCredentialsAttributesA(handle, SECPKG_ATTR_SUPPORTED_PROTOCOLS, &protocols);
192 ok(status == SEC_E_OK, "QueryCredentialsAttributes failed: %08x\n", status);
194 if(exprots)
195 ok(protocols.grbitProtocol == exprots, "protocols.grbitProtocol = %x, expected %x\n", protocols.grbitProtocol, exprots);
197 trace("Supported protocols:\n");
199 #define X(flag, name) do { if(protocols.grbitProtocol & flag) { trace(name "\n"); protocols.grbitProtocol &= ~flag; } }while(0)
200 X(SP_PROT_SSL2_CLIENT, "SSL 2 client");
201 X(SP_PROT_SSL3_CLIENT, "SSL 3 client");
202 X(SP_PROT_TLS1_0_CLIENT, "TLS 1.0 client");
203 X(SP_PROT_TLS1_1_CLIENT, "TLS 1.1 client");
204 X(SP_PROT_TLS1_2_CLIENT, "TLS 1.2 client");
205 X(SP_PROT_TLS1_3_CLIENT, "TLS 1.3 client");
206 X(SP_PROT_DTLS1_0_CLIENT, "DTLS 1.0 client");
207 X(SP_PROT_DTLS1_2_CLIENT, "DTLS 1.2 client");
208 #undef X
210 if(protocols.grbitProtocol)
211 trace("Unknown flags: %x\n", protocols.grbitProtocol);
214 static void test_supported_algs(CredHandle *handle)
216 SecPkgCred_SupportedAlgs algs;
217 SECURITY_STATUS status;
218 unsigned i;
220 status = QueryCredentialsAttributesA(handle, SECPKG_ATTR_SUPPORTED_ALGS, &algs);
221 todo_wine ok(status == SEC_E_OK, "QueryCredentialsAttributes failed: %08x\n", status);
222 if(status != SEC_E_OK)
223 return;
225 trace("Supported algorithms (%d):\n", algs.cSupportedAlgs);
226 for(i=0; i < algs.cSupportedAlgs; i++)
227 trace(" %s\n", algid_to_str(algs.palgSupportedAlgs[i]));
229 FreeContextBuffer(algs.palgSupportedAlgs);
232 static void test_cread_attrs(void)
234 SCHANNEL_CRED schannel_cred;
235 SECURITY_STATUS status;
236 CredHandle cred;
238 status = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
239 NULL, NULL, NULL, NULL, &cred, NULL);
240 ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %x\n", status);
242 test_supported_protocols(&cred, 0);
243 test_supported_algs(&cred);
245 status = QueryCredentialsAttributesA(&cred, SECPKG_ATTR_SUPPORTED_PROTOCOLS, NULL);
246 ok(status == SEC_E_INTERNAL_ERROR, "QueryCredentialsAttributes failed: %08x, expected SEC_E_INTERNAL_ERROR\n", status);
248 status = QueryCredentialsAttributesA(&cred, SECPKG_ATTR_SUPPORTED_ALGS, NULL);
249 ok(status == SEC_E_INTERNAL_ERROR, "QueryCredentialsAttributes failed: %08x, expected SEC_E_INTERNAL_ERROR\n", status);
251 FreeCredentialsHandle(&cred);
253 init_cred(&schannel_cred);
254 schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
255 status = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
256 NULL, &schannel_cred, NULL, NULL, &cred, NULL);
257 ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %x\n", status);
259 test_supported_protocols(&cred, SP_PROT_TLS1_CLIENT);
260 test_supported_algs(&cred);
262 FreeCredentialsHandle(&cred);
265 static void testAcquireSecurityContext(void)
267 BOOL has_schannel = FALSE;
268 SecPkgInfoA *package_info;
269 ULONG i;
270 SECURITY_STATUS st;
271 CredHandle cred;
272 SecPkgCredentials_NamesA names;
273 TimeStamp exp;
274 SCHANNEL_CRED schanCred;
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;
283 if (SUCCEEDED(EnumerateSecurityPackagesA(&i, &package_info)))
285 while(i--)
287 if (!strcmp(package_info[i].Name, unisp_name_a))
289 has_schannel = TRUE;
290 break;
293 FreeContextBuffer(package_info);
295 if (!has_schannel)
297 skip("Schannel not available\n");
298 return;
301 lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
303 keyProvInfo.pwszContainerName = cspNameW;
304 keyProvInfo.pwszProvName = ms_def_prov_w;
305 keyProvInfo.dwProvType = PROV_RSA_FULL;
306 keyProvInfo.dwFlags = 0;
307 keyProvInfo.cProvParam = 0;
308 keyProvInfo.rgProvParam = NULL;
309 keyProvInfo.dwKeySpec = AT_SIGNATURE;
311 certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
312 certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert, sizeof(selfSignedCert));
314 SetLastError(0xdeadbeef);
315 ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
316 CRYPT_DELETEKEYSET);
317 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
319 /* WinMe would crash on some tests */
320 win_skip("CryptAcquireContextW is not implemented\n");
321 return;
324 st = AcquireCredentialsHandleA(NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL,
325 NULL);
326 ok(st == SEC_E_SECPKG_NOT_FOUND,
327 "Expected SEC_E_SECPKG_NOT_FOUND, got %08x\n", st);
328 if (0)
330 /* Crashes on Win2K */
331 st = AcquireCredentialsHandleA(NULL, unisp_name_a, 0, NULL, NULL, NULL,
332 NULL, NULL, NULL);
333 ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
335 /* Crashes on WinNT */
336 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_BOTH, NULL,
337 NULL, NULL, NULL, NULL, NULL);
338 ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
340 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
341 NULL, NULL, NULL, NULL, NULL, NULL);
342 ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
344 /* Crashes */
345 AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
346 NULL, NULL, NULL, NULL, NULL, NULL);
348 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
349 NULL, NULL, NULL, NULL, &cred, NULL);
350 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
351 if(st == SEC_E_OK)
352 FreeCredentialsHandle(&cred);
353 memset(&cred, 0, sizeof(cred));
354 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
355 NULL, NULL, NULL, NULL, &cred, &exp);
356 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
357 /* expriy is indeterminate in win2k3 */
358 trace("expiry: %08x%08x\n", exp.HighPart, exp.LowPart);
360 st = QueryCredentialsAttributesA(&cred, SECPKG_CRED_ATTR_NAMES, &names);
361 ok(st == SEC_E_NO_CREDENTIALS || st == SEC_E_UNSUPPORTED_FUNCTION /* before Vista */, "expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
363 FreeCredentialsHandle(&cred);
365 /* Bad version in SCHANNEL_CRED */
366 memset(&schanCred, 0, sizeof(schanCred));
367 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
368 NULL, &schanCred, NULL, NULL, NULL, NULL);
369 ok(st == SEC_E_INTERNAL_ERROR ||
370 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */ ||
371 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
372 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
373 NULL, &schanCred, NULL, NULL, NULL, NULL);
374 ok(st == SEC_E_INTERNAL_ERROR ||
375 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */ ||
376 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
378 /* No cert in SCHANNEL_CRED succeeds for outbound.. */
379 schanCred.dwVersion = SCHANNEL_CRED_VERSION;
380 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
381 NULL, &schanCred, NULL, NULL, &cred, NULL);
382 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
383 FreeCredentialsHandle(&cred);
384 /* but fails for inbound. */
385 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
386 NULL, &schanCred, NULL, NULL, &cred, NULL);
387 ok(st == SEC_E_NO_CREDENTIALS ||
388 st == SEC_E_OK /* Vista/win2k8 */,
389 "Expected SEC_E_NO_CREDENTIALS or SEC_E_OK, got %08x\n", st);
391 if (0)
393 /* Crashes with bad paCred pointer */
394 schanCred.cCreds = 1;
395 AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
396 NULL, &schanCred, NULL, NULL, NULL, NULL);
399 /* Bogus cert in SCHANNEL_CRED. Windows fails with
400 * SEC_E_UNKNOWN_CREDENTIALS, but I'll accept SEC_E_NO_CREDENTIALS too.
402 schanCred.cCreds = 1;
403 schanCred.paCred = &certs[0];
404 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
405 NULL, &schanCred, NULL, NULL, NULL, NULL);
406 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
407 st == SEC_E_NO_CREDENTIALS ||
408 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
409 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
410 NULL, &schanCred, NULL, NULL, NULL, NULL);
411 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
412 st == SEC_E_NO_CREDENTIALS ||
413 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
415 /* Good cert, but missing private key. Windows fails with
416 * SEC_E_NO_CREDENTIALS, but I'll accept SEC_E_UNKNOWN_CREDENTIALS too.
418 schanCred.cCreds = 1;
419 schanCred.paCred = &certs[1];
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_NO_CREDENTIALS ||
423 st == SEC_E_INTERNAL_ERROR, /* win2k */
424 "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
425 "or SEC_E_INTERNAL_ERROR, got %08x\n", st);
426 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
427 NULL, &schanCred, NULL, NULL, NULL, NULL);
428 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS ||
429 st == SEC_E_INTERNAL_ERROR, /* win2k */
430 "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
431 "or SEC_E_INTERNAL_ERROR, got %08x\n", st);
433 /* Good cert, with CRYPT_KEY_PROV_INFO set before it's had a key loaded. */
434 ret = CertSetCertificateContextProperty(certs[1],
435 CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo);
436 schanCred.dwVersion = SCH_CRED_V3;
437 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
438 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
439 NULL, &schanCred, NULL, NULL, &cred, NULL);
440 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INTERNAL_ERROR /* WinNT */ ||
441 st == SEC_E_INSUFFICIENT_MEMORY /* win10 */,
442 "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st);
443 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
444 NULL, &schanCred, NULL, NULL, &cred, NULL);
445 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INTERNAL_ERROR /* WinNT */ ||
446 st == SEC_E_INSUFFICIENT_MEMORY /* win10 */,
447 "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st);
449 ret = CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
450 CRYPT_NEWKEYSET);
451 ok(ret, "CryptAcquireContextW failed: %08x\n", GetLastError());
452 ret = 0;
454 ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
455 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
456 if (ret)
458 PCCERT_CONTEXT tmp;
460 if (0)
462 /* Crashes */
463 AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
464 NULL, &schanCred, NULL, NULL, NULL, NULL);
466 /* Crashes on WinNT */
467 /* Good cert with private key, bogus version */
468 schanCred.dwVersion = SCH_CRED_V1;
469 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
470 NULL, &schanCred, NULL, NULL, &cred, NULL);
471 ok(st == SEC_E_INTERNAL_ERROR ||
472 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
473 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
474 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
475 NULL, &schanCred, NULL, NULL, &cred, NULL);
476 ok(st == SEC_E_INTERNAL_ERROR ||
477 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
478 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
479 schanCred.dwVersion = SCH_CRED_V2;
480 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
481 NULL, &schanCred, NULL, NULL, &cred, NULL);
482 ok(st == SEC_E_INTERNAL_ERROR ||
483 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
484 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
485 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
486 NULL, &schanCred, NULL, NULL, &cred, NULL);
487 ok(st == SEC_E_INTERNAL_ERROR ||
488 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
489 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
492 /* Succeeds on V3 or higher */
493 schanCred.dwVersion = SCH_CRED_V3;
494 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
495 NULL, &schanCred, NULL, NULL, &cred, NULL);
496 ok(st == SEC_E_OK || st == SEC_E_INSUFFICIENT_MEMORY /* win10 */,
497 "AcquireCredentialsHandleA failed: %08x\n", st);
498 FreeCredentialsHandle(&cred);
499 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
500 NULL, &schanCred, NULL, NULL, &cred, NULL);
501 ok(st == SEC_E_OK || st == SEC_E_UNKNOWN_CREDENTIALS /* win2k3 */ ||
502 st == SEC_E_INSUFFICIENT_MEMORY /* win10 */,
503 "AcquireCredentialsHandleA failed: %08x\n", st);
504 FreeCredentialsHandle(&cred);
505 schanCred.dwVersion = SCHANNEL_CRED_VERSION;
506 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
507 NULL, &schanCred, NULL, NULL, &cred, NULL);
508 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
509 FreeCredentialsHandle(&cred);
510 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
511 NULL, &schanCred, NULL, NULL, &cred, NULL);
512 ok(st == SEC_E_OK ||
513 st == SEC_E_UNKNOWN_CREDENTIALS, /* win2k3 */
514 "AcquireCredentialsHandleA failed: %08x\n", st);
515 if (st == SEC_E_OK) test_strength(&cred);
516 FreeCredentialsHandle(&cred);
518 /* How about more than one cert? */
519 schanCred.cCreds = 2;
520 schanCred.paCred = certs;
521 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
522 NULL, &schanCred, NULL, NULL, &cred, NULL);
523 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
524 st == SEC_E_NO_CREDENTIALS /* Vista/win2k8 */ ||
525 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
526 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
527 NULL, &schanCred, NULL, NULL, &cred, NULL);
528 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
529 st == SEC_E_NO_CREDENTIALS ||
530 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
531 tmp = certs[0];
532 certs[0] = certs[1];
533 certs[1] = tmp;
534 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
535 NULL, &schanCred, NULL, NULL, &cred, NULL);
536 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
537 st == SEC_E_NO_CREDENTIALS ||
538 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
539 st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
540 NULL, &schanCred, NULL, NULL, &cred, NULL);
541 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS,
542 "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
543 /* FIXME: what about two valid certs? */
545 CryptDestroyKey(key);
548 CryptReleaseContext(csp, 0);
549 CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
551 CertFreeCertificateContext(certs[0]);
552 CertFreeCertificateContext(certs[1]);
555 static void test_remote_cert(PCCERT_CONTEXT remote_cert)
557 PCCERT_CONTEXT iter = NULL;
558 BOOL incl_remote = FALSE;
559 unsigned cert_cnt = 0;
561 ok(remote_cert->hCertStore != NULL, "hCertStore == NULL\n");
563 while((iter = CertEnumCertificatesInStore(remote_cert->hCertStore, iter))) {
564 if(iter == remote_cert)
565 incl_remote = TRUE;
566 cert_cnt++;
569 ok(cert_cnt == 2, "cert_cnt = %u\n", cert_cnt);
570 ok(incl_remote, "context does not contain cert itself\n");
573 static const char http_request[] = "GET /tests/clientcert/ HTTP/1.1\r\nHost: test.winehq.org\r\nConnection: close\r\n\r\n";
575 static void init_buffers(SecBufferDesc *desc, unsigned count, unsigned size)
577 desc->ulVersion = SECBUFFER_VERSION;
578 desc->cBuffers = count;
579 desc->pBuffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count*sizeof(SecBuffer));
581 desc->pBuffers[0].cbBuffer = size;
582 desc->pBuffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, size);
585 static void reset_buffers(SecBufferDesc *desc)
587 unsigned i;
589 for (i = 0; i < desc->cBuffers; ++i)
591 desc->pBuffers[i].BufferType = SECBUFFER_EMPTY;
592 if (i > 0)
594 desc->pBuffers[i].cbBuffer = 0;
595 desc->pBuffers[i].pvBuffer = NULL;
600 static void free_buffers(SecBufferDesc *desc)
602 HeapFree(GetProcessHeap(), 0, desc->pBuffers[0].pvBuffer);
603 HeapFree(GetProcessHeap(), 0, desc->pBuffers);
606 static int receive_data(SOCKET sock, SecBuffer *buf)
608 unsigned received = 0;
610 while (1)
612 unsigned char *data = buf->pvBuffer;
613 unsigned expected = 0;
614 int ret;
616 ret = recv(sock, (char *)data+received, buf->cbBuffer-received, 0);
617 if (ret == -1)
619 skip("recv failed\n");
620 return -1;
622 else if(ret == 0)
624 skip("connection closed\n");
625 return -1;
627 received += ret;
629 while (expected < received)
631 unsigned frame_size = 5 + ((data[3]<<8) | data[4]);
632 expected += frame_size;
633 data += frame_size;
636 if (expected == received)
637 break;
640 buf->cbBuffer = received;
642 return received;
645 static void test_InitializeSecurityContext(void)
647 SCHANNEL_CRED cred;
648 CredHandle cred_handle;
649 CtxtHandle context;
650 SECURITY_STATUS status;
651 SecBuffer out_buffer = {1000, SECBUFFER_TOKEN, NULL};
652 SecBuffer in_buffer = {0, SECBUFFER_EMPTY, NULL};
653 SecBufferDesc out_buffers = {SECBUFFER_VERSION, 1, &out_buffer};
654 SecBufferDesc in_buffers = {SECBUFFER_VERSION, 1, &in_buffer};
655 ULONG attrs;
657 init_cred(&cred);
658 cred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
659 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS|SCH_CRED_MANUAL_CRED_VALIDATION;
660 status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
661 &cred, NULL, NULL, &cred_handle, NULL);
662 ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", status);
663 if (status != SEC_E_OK) return;
665 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
666 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM|ISC_REQ_ALLOCATE_MEMORY,
667 0, 0, &in_buffers, 0, &context, &out_buffers, &attrs, NULL);
668 ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status);
670 FreeContextBuffer(out_buffer.pvBuffer);
671 DeleteSecurityContext(&context);
672 FreeCredentialsHandle(&cred_handle);
675 static SOCKET create_ssl_socket( const char *hostname )
677 struct hostent *host;
678 struct sockaddr_in addr;
679 SOCKET sock;
681 if (!(host = gethostbyname(hostname)))
683 skip("Can't resolve \"%s\"\n", hostname);
684 return -1;
687 addr.sin_family = host->h_addrtype;
688 addr.sin_addr = *(struct in_addr *)host->h_addr_list[0];
689 addr.sin_port = htons(443);
690 if ((sock = socket(host->h_addrtype, SOCK_STREAM, 0)) == -1)
692 skip("Can't create socket\n");
693 return 1;
696 if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1)
698 skip("Can't connect to \"%s\"\n", hostname);
699 closesocket(sock);
700 return -1;
703 return sock;
706 static const BYTE pfxdata[] =
708 0x30, 0x82, 0x0b, 0x1d, 0x02, 0x01, 0x03, 0x30, 0x82, 0x0a, 0xe3, 0x06,
709 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82,
710 0x0a, 0xd4, 0x04, 0x82, 0x0a, 0xd0, 0x30, 0x82, 0x0a, 0xcc, 0x30, 0x82,
711 0x05, 0x07, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
712 0x06, 0xa0, 0x82, 0x04, 0xf8, 0x30, 0x82, 0x04, 0xf4, 0x02, 0x01, 0x00,
713 0x30, 0x82, 0x04, 0xed, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
714 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
715 0x0d, 0x01, 0x0c, 0x01, 0x06, 0x30, 0x0e, 0x04, 0x08, 0xac, 0x3e, 0x35,
716 0xa8, 0xed, 0x0d, 0x50, 0x07, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x04,
717 0xc0, 0x5a, 0x62, 0x55, 0x25, 0xf6, 0x2c, 0xf1, 0x78, 0x6c, 0x63, 0x96,
718 0x8a, 0xea, 0x04, 0x64, 0xb3, 0x99, 0x3b, 0x80, 0x50, 0x05, 0x37, 0x55,
719 0xa3, 0x5e, 0x9f, 0x35, 0xc3, 0x3c, 0xdc, 0xf6, 0xc4, 0xc1, 0x39, 0xa2,
720 0xd7, 0x50, 0xad, 0xf9, 0x29, 0x3c, 0x51, 0xea, 0x15, 0x20, 0x25, 0xd3,
721 0x4d, 0x69, 0xdf, 0x10, 0xd8, 0x9d, 0x60, 0x78, 0x8a, 0x70, 0x44, 0x7f,
722 0x01, 0x4f, 0x4a, 0xfa, 0xab, 0xfd, 0x46, 0x48, 0x96, 0x2b, 0x69, 0xfc,
723 0x11, 0xf8, 0x3f, 0xd3, 0x79, 0x09, 0x75, 0x81, 0x47, 0xdf, 0xce, 0xfe,
724 0x07, 0x2f, 0x0a, 0xd8, 0xac, 0x87, 0x14, 0x1f, 0x7b, 0x95, 0x70, 0xee,
725 0x7e, 0x52, 0x90, 0x11, 0xd6, 0x69, 0xf4, 0xd5, 0x38, 0x85, 0xc9, 0xc1,
726 0x07, 0x01, 0xe8, 0xbb, 0xfb, 0xe2, 0x08, 0xa8, 0xfa, 0xbf, 0xf0, 0x92,
727 0x63, 0x1d, 0xbb, 0x2b, 0x45, 0x6f, 0xce, 0x97, 0x01, 0xd7, 0x95, 0xf0,
728 0x9c, 0x9a, 0x6b, 0x73, 0x01, 0xbf, 0xf9, 0x3d, 0xc8, 0x2b, 0x86, 0x7a,
729 0xd5, 0x65, 0x84, 0xd7, 0xff, 0xb2, 0xf9, 0x20, 0x52, 0x35, 0xc5, 0x60,
730 0x33, 0x70, 0x1d, 0x2f, 0x26, 0x09, 0x1c, 0x22, 0x17, 0xd8, 0x08, 0x4e,
731 0x69, 0x20, 0xe2, 0x71, 0xe4, 0x07, 0xb1, 0x48, 0x5f, 0x20, 0x08, 0x7a,
732 0xbf, 0x65, 0x53, 0x23, 0x07, 0xf9, 0x6c, 0xde, 0x3e, 0x29, 0xbf, 0x6b,
733 0xef, 0xbb, 0x6a, 0x5f, 0x79, 0xa1, 0x72, 0xa1, 0x10, 0x24, 0x80, 0xb4,
734 0x44, 0xb8, 0xc9, 0xfc, 0xa3, 0x36, 0x7e, 0x23, 0x37, 0x58, 0xc6, 0x1e,
735 0xe8, 0x42, 0x4d, 0xb5, 0xf5, 0x58, 0x93, 0x21, 0x38, 0xa2, 0xc4, 0xa9,
736 0x01, 0x96, 0xf9, 0x61, 0xac, 0x55, 0xb3, 0x3d, 0xe4, 0x54, 0x8b, 0x6c,
737 0xc3, 0x83, 0xff, 0x50, 0x87, 0x94, 0xe8, 0x35, 0x3c, 0x26, 0x0d, 0x20,
738 0x8a, 0x25, 0x0e, 0xb6, 0x67, 0x78, 0x29, 0xc7, 0xbf, 0x76, 0x8e, 0x62,
739 0x62, 0xc4, 0x50, 0xd6, 0xc5, 0x3c, 0xb4, 0x7a, 0x35, 0xbe, 0x53, 0x52,
740 0xc4, 0xe4, 0x10, 0xb3, 0xe0, 0x73, 0xb0, 0xd1, 0xc1, 0x5a, 0x4f, 0x4e,
741 0x64, 0x0d, 0x92, 0x51, 0x2d, 0x4d, 0xec, 0xb0, 0xc6, 0x40, 0x1b, 0x03,
742 0x89, 0x7f, 0xc2, 0x2c, 0xe3, 0x2c, 0xbd, 0x8c, 0x9c, 0xd9, 0xe0, 0x08,
743 0x59, 0xd3, 0xaf, 0x48, 0x56, 0x89, 0x60, 0x85, 0x76, 0xe0, 0xd8, 0x7c,
744 0xcf, 0x02, 0x8f, 0xfd, 0xb2, 0x8f, 0x2b, 0x61, 0xcf, 0x28, 0x56, 0x8b,
745 0x6b, 0x03, 0x2b, 0x2f, 0x83, 0x31, 0xa0, 0x1c, 0xd1, 0x6c, 0x87, 0x49,
746 0xc4, 0x77, 0x55, 0x1f, 0x61, 0x45, 0x58, 0x88, 0x9f, 0x01, 0xc3, 0x63,
747 0x62, 0x30, 0x35, 0xdf, 0x61, 0x74, 0x55, 0x63, 0x3f, 0xae, 0x41, 0xc1,
748 0xb8, 0xf0, 0x9f, 0xab, 0x25, 0xad, 0x41, 0x5c, 0x1f, 0x00, 0x0d, 0xef,
749 0xf0, 0xcf, 0xaf, 0x41, 0x23, 0xca, 0x8c, 0x38, 0xea, 0x5a, 0xe4, 0x8b,
750 0xb4, 0x89, 0xd0, 0x76, 0x7f, 0x2b, 0x77, 0x8f, 0xe4, 0x44, 0xd5, 0x37,
751 0xac, 0xc2, 0x09, 0x7e, 0x7e, 0x7e, 0x02, 0x5c, 0x27, 0x01, 0xcb, 0x4d,
752 0xea, 0xb3, 0x97, 0x36, 0x35, 0xd2, 0x05, 0x3c, 0x4e, 0xb8, 0x04, 0x5c,
753 0xb8, 0x95, 0x3f, 0xc6, 0xbf, 0xd4, 0x20, 0x01, 0xfb, 0xed, 0x37, 0x5a,
754 0xad, 0x4c, 0x61, 0x93, 0xfe, 0x95, 0x7c, 0x34, 0x11, 0x15, 0x9d, 0x00,
755 0x0b, 0x99, 0x69, 0xcb, 0x7e, 0xb9, 0x53, 0x46, 0x57, 0x39, 0x3f, 0x59,
756 0x4b, 0x30, 0x8d, 0xfb, 0x84, 0x66, 0x2d, 0x06, 0xc9, 0x88, 0xa6, 0x18,
757 0xd7, 0x36, 0xc6, 0xf6, 0xf7, 0x47, 0x85, 0x38, 0xc8, 0x3d, 0x37, 0xea,
758 0x57, 0x4c, 0xb0, 0x7c, 0x95, 0x29, 0x84, 0xab, 0xbb, 0x19, 0x86, 0xc2,
759 0xc5, 0x99, 0x01, 0x38, 0x6b, 0xf1, 0xd3, 0x1d, 0xa8, 0x02, 0xf9, 0x6f,
760 0xaa, 0xf1, 0x57, 0xd0, 0x88, 0x68, 0x62, 0x5f, 0x9f, 0x7a, 0x63, 0xba,
761 0x3a, 0xc9, 0x95, 0x11, 0x3c, 0xf9, 0xa1, 0xc1, 0x35, 0xfe, 0xd5, 0x12,
762 0x49, 0x88, 0x0d, 0x5c, 0xe2, 0xd1, 0x15, 0x18, 0xfb, 0xd5, 0x7f, 0x19,
763 0x3f, 0xaf, 0xa0, 0xcb, 0x31, 0x20, 0x9e, 0x03, 0x93, 0xa4, 0x66, 0xbd,
764 0x83, 0xe8, 0x60, 0x34, 0x55, 0x0d, 0x97, 0x10, 0x23, 0x24, 0x7a, 0x45,
765 0x36, 0xb4, 0xc4, 0xee, 0x60, 0x6f, 0xd8, 0x46, 0xc5, 0xac, 0x2b, 0xa9,
766 0x18, 0x74, 0x83, 0x1e, 0xdf, 0x7c, 0x1a, 0x5a, 0xe8, 0x5f, 0x8b, 0x4f,
767 0x9f, 0x40, 0x3e, 0x5e, 0xfb, 0xd3, 0x68, 0xac, 0x34, 0x62, 0x30, 0x23,
768 0xb6, 0xbc, 0xdf, 0xbc, 0xc7, 0x25, 0xd2, 0x1b, 0x57, 0x33, 0xfb, 0x78,
769 0x22, 0x21, 0x1e, 0x3a, 0xf6, 0x44, 0x18, 0x7e, 0x12, 0x36, 0x47, 0x58,
770 0xd0, 0x59, 0x26, 0x98, 0x98, 0x95, 0xf4, 0xd1, 0xaa, 0x45, 0xaa, 0xe7,
771 0xd1, 0xe6, 0x2d, 0x78, 0xf0, 0x8b, 0x1c, 0xfd, 0xf8, 0x50, 0x60, 0xa2,
772 0x1e, 0x7f, 0xe3, 0x31, 0x77, 0x31, 0x58, 0x99, 0x0f, 0xda, 0x0e, 0xa3,
773 0xc6, 0x7a, 0x30, 0x45, 0x55, 0x11, 0x91, 0x77, 0x41, 0x79, 0xd3, 0x56,
774 0xb2, 0x07, 0x00, 0x61, 0xab, 0xec, 0x27, 0xc7, 0x9f, 0xfa, 0x89, 0x08,
775 0xc2, 0x87, 0xcf, 0xe9, 0xdc, 0x9e, 0x29, 0x22, 0xfb, 0x23, 0x7f, 0x9d,
776 0x89, 0xd5, 0x6e, 0x75, 0x20, 0xd8, 0x00, 0x5b, 0xc4, 0x94, 0xbb, 0xc5,
777 0xb2, 0xba, 0x77, 0x2b, 0xf6, 0x3c, 0x88, 0xb0, 0x4c, 0x38, 0x46, 0x55,
778 0xee, 0x8b, 0x03, 0x15, 0xbc, 0x0a, 0x1d, 0x47, 0x87, 0x44, 0xaf, 0xb1,
779 0x2a, 0xa7, 0x4d, 0x08, 0xdf, 0x3b, 0x2d, 0x70, 0xa1, 0x67, 0x31, 0x76,
780 0x6e, 0x6f, 0x40, 0x3b, 0x3b, 0xe8, 0xf9, 0xdf, 0x90, 0xa4, 0xce, 0x7f,
781 0xb8, 0x2d, 0x69, 0xcb, 0x1c, 0x1e, 0x94, 0xcd, 0xb1, 0xd8, 0x43, 0x22,
782 0xb8, 0x4f, 0x98, 0x92, 0x74, 0xb3, 0xde, 0xeb, 0x7a, 0xcb, 0xfa, 0xd0,
783 0x36, 0xe4, 0x5d, 0xfa, 0xd3, 0xce, 0xf9, 0xba, 0x3e, 0x0f, 0x6c, 0xc3,
784 0x5b, 0xb3, 0x81, 0x84, 0x6e, 0x5d, 0xc1, 0x21, 0x89, 0xec, 0x67, 0x9a,
785 0xfd, 0x55, 0x20, 0xb0, 0x71, 0x53, 0xae, 0xf8, 0xa4, 0x8d, 0xd5, 0xe5,
786 0x2d, 0x3a, 0xce, 0x89, 0x55, 0x8c, 0x4f, 0x3b, 0x37, 0x95, 0x4e, 0x15,
787 0xbe, 0xe7, 0xd1, 0x7a, 0x36, 0x82, 0x45, 0x69, 0x7c, 0x27, 0x4f, 0xb9,
788 0x4b, 0x7d, 0xcd, 0x59, 0xc8, 0xf4, 0x8b, 0x0f, 0x4f, 0x75, 0x23, 0xd3,
789 0xd0, 0xc7, 0x10, 0x79, 0xc0, 0xf1, 0xac, 0x14, 0xf7, 0x0d, 0xc8, 0x5e,
790 0xfc, 0xff, 0x1a, 0x2b, 0x10, 0x88, 0x7e, 0x7e, 0x2f, 0xfa, 0x7b, 0x9f,
791 0x47, 0x23, 0x34, 0xfc, 0xf5, 0xde, 0xd9, 0xa3, 0x05, 0x99, 0x2a, 0x96,
792 0x83, 0x3d, 0xa4, 0x7f, 0x6a, 0x66, 0x9b, 0xe7, 0xf1, 0x00, 0x4e, 0x9a,
793 0xfc, 0x68, 0xd2, 0x74, 0x17, 0xba, 0xc9, 0xc8, 0x20, 0x39, 0xa1, 0xa8,
794 0x85, 0xc6, 0x10, 0x2b, 0xab, 0x97, 0x34, 0x2d, 0x49, 0x68, 0x57, 0xb0,
795 0x43, 0xee, 0x25, 0xbb, 0x35, 0x1b, 0x03, 0x99, 0xa3, 0x21, 0x68, 0x66,
796 0x86, 0x3f, 0xc6, 0xfc, 0x49, 0xf0, 0xba, 0x5f, 0x00, 0xc6, 0xe3, 0x1c,
797 0xb2, 0x9f, 0x16, 0x7f, 0xc7, 0x40, 0x4a, 0x9a, 0x39, 0xc1, 0x95, 0x69,
798 0xa2, 0x87, 0xba, 0x58, 0xc6, 0xf2, 0xd6, 0x66, 0xa6, 0x4c, 0x6d, 0x29,
799 0x9c, 0xa8, 0x6e, 0xa9, 0xd2, 0xe4, 0x54, 0x17, 0x89, 0xe2, 0x43, 0xf0,
800 0xe1, 0x8b, 0x57, 0x84, 0x6c, 0x87, 0x63, 0x17, 0xbb, 0xf6, 0x33, 0x1b,
801 0xe4, 0x34, 0x6a, 0x80, 0x70, 0x7b, 0x1b, 0xfd, 0xf8, 0x79, 0x28, 0xc8,
802 0x3c, 0x8e, 0xa4, 0xd5, 0xb8, 0x96, 0x54, 0xd4, 0xec, 0x72, 0xe5, 0x40,
803 0x8f, 0x56, 0xde, 0x82, 0x15, 0x72, 0x4d, 0xd8, 0x0c, 0x07, 0xea, 0xe6,
804 0x44, 0xcd, 0x94, 0x73, 0x5c, 0x04, 0xe8, 0x8e, 0xb7, 0xc7, 0xc9, 0x29,
805 0xdc, 0x04, 0xef, 0x7c, 0x31, 0x9b, 0x50, 0xbc, 0xea, 0x71, 0x1f, 0x28,
806 0x22, 0xb6, 0x04, 0x53, 0x2e, 0x71, 0xc4, 0xf6, 0xbb, 0x88, 0x51, 0xee,
807 0x3e, 0x76, 0x65, 0xb4, 0x4b, 0x1b, 0xa3, 0xec, 0x7b, 0xa7, 0x9d, 0x31,
808 0x5d, 0xb8, 0x9f, 0xab, 0x6b, 0x54, 0x7d, 0xbd, 0xc1, 0x2c, 0x55, 0xb0,
809 0x23, 0x8c, 0x06, 0x60, 0x01, 0x4f, 0x60, 0x85, 0x56, 0x7f, 0xfb, 0x99,
810 0x0c, 0xdc, 0x8c, 0x09, 0x37, 0x46, 0x5b, 0x97, 0x5d, 0xe8, 0x31, 0x00,
811 0x1b, 0x30, 0x9b, 0x02, 0x92, 0x29, 0xb5, 0x20, 0xce, 0x4b, 0x90, 0xfb,
812 0x91, 0x07, 0x5a, 0xd3, 0xf5, 0xa0, 0xe6, 0x8f, 0xf8, 0x73, 0xc5, 0x4b,
813 0xbb, 0xad, 0x2a, 0xeb, 0xa8, 0xb7, 0x68, 0x34, 0x36, 0x47, 0xd5, 0x4b,
814 0x61, 0x89, 0x53, 0xe6, 0xb6, 0xb1, 0x07, 0xe4, 0x08, 0x2e, 0xed, 0x50,
815 0xd4, 0x1e, 0xed, 0x7f, 0xbf, 0x35, 0x68, 0x04, 0x45, 0x72, 0x86, 0x71,
816 0x15, 0x55, 0xdf, 0xe6, 0x30, 0xc0, 0x8b, 0x8a, 0xb0, 0x6c, 0xd0, 0x35,
817 0x57, 0x8f, 0x04, 0x37, 0xbc, 0xe1, 0xb8, 0xbf, 0x27, 0x37, 0x3d, 0xd0,
818 0xc8, 0x46, 0x67, 0x42, 0x51, 0x30, 0x82, 0x05, 0xbd, 0x06, 0x09, 0x2a,
819 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x05, 0xae,
820 0x04, 0x82, 0x05, 0xaa, 0x30, 0x82, 0x05, 0xa6, 0x30, 0x82, 0x05, 0xa2,
821 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01,
822 0x02, 0xa0, 0x82, 0x04, 0xee, 0x30, 0x82, 0x04, 0xea, 0x30, 0x1c, 0x06,
823 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30,
824 0x0e, 0x04, 0x08, 0x9f, 0xa4, 0x72, 0x2b, 0x6b, 0x0e, 0xcb, 0x9f, 0x02,
825 0x02, 0x08, 0x00, 0x04, 0x82, 0x04, 0xc8, 0xe5, 0x35, 0xb9, 0x72, 0x28,
826 0x20, 0x28, 0xad, 0xe3, 0x01, 0xd7, 0x0b, 0xe0, 0x4e, 0x36, 0xc3, 0x73,
827 0x06, 0xd5, 0xf6, 0x75, 0x1a, 0x78, 0xb2, 0xd8, 0xf6, 0x5a, 0x85, 0x8e,
828 0x50, 0xa3, 0x05, 0x49, 0x02, 0x2d, 0xf8, 0xa3, 0x2f, 0xe6, 0x02, 0x7a,
829 0xd5, 0x0b, 0x1d, 0xf1, 0xd1, 0xe4, 0x16, 0xaa, 0x70, 0x2e, 0x34, 0xdb,
830 0x56, 0xd9, 0x33, 0x94, 0x11, 0xaa, 0x60, 0xd4, 0xfa, 0x5b, 0xd1, 0xb3,
831 0x2e, 0x86, 0x6a, 0x5a, 0x69, 0xdf, 0x11, 0x91, 0xb0, 0xca, 0x82, 0xff,
832 0x63, 0xad, 0x6a, 0x0b, 0x90, 0xa6, 0xc7, 0x9b, 0xef, 0x9a, 0xf8, 0x96,
833 0xec, 0xe4, 0xc4, 0xdf, 0x55, 0x4c, 0x12, 0x07, 0xab, 0x7c, 0x5c, 0x68,
834 0x47, 0xf2, 0x92, 0xfb, 0x94, 0xab, 0xc3, 0x64, 0xd3, 0xfe, 0xb2, 0x16,
835 0xb4, 0x78, 0x80, 0x52, 0xe9, 0x32, 0x39, 0x3b, 0x8d, 0x12, 0x91, 0x36,
836 0xfd, 0xa1, 0x97, 0xc2, 0x0a, 0x4a, 0xf1, 0xb3, 0x8a, 0xe4, 0x01, 0xed,
837 0x0a, 0xda, 0x2e, 0xa0, 0x38, 0xa9, 0x47, 0x3d, 0x3a, 0x64, 0x87, 0x06,
838 0xc3, 0x83, 0x60, 0xaf, 0x84, 0xdb, 0x87, 0xff, 0x70, 0x61, 0x43, 0x7d,
839 0x2d, 0x61, 0x9a, 0xf7, 0x0d, 0xca, 0x0c, 0x0f, 0xbe, 0x43, 0x5b, 0x99,
840 0xe1, 0x90, 0x64, 0x1f, 0xa7, 0x1b, 0xa6, 0xa6, 0x5c, 0x13, 0x70, 0xa3,
841 0xdb, 0xd7, 0xf0, 0xe8, 0x7a, 0xb0, 0xd1, 0x9b, 0x52, 0xa6, 0x4f, 0xd6,
842 0xff, 0x54, 0x4d, 0xa6, 0x15, 0x05, 0x5c, 0xe9, 0x04, 0x6a, 0xc3, 0x49,
843 0x12, 0x2f, 0x24, 0x03, 0xc3, 0x80, 0x06, 0xa6, 0x07, 0x8b, 0x96, 0xe7,
844 0x39, 0x31, 0x6d, 0xd3, 0x1b, 0xa5, 0x45, 0x58, 0x04, 0xe7, 0x87, 0xdf,
845 0x26, 0xfb, 0x1b, 0x9f, 0x92, 0x93, 0x32, 0x12, 0x9a, 0xc9, 0xe6, 0xcb,
846 0x88, 0x14, 0x9f, 0x23, 0x0b, 0x52, 0xa2, 0xb8, 0x32, 0x6c, 0xa9, 0x33,
847 0xa1, 0x17, 0xe8, 0x4a, 0xd4, 0x5c, 0x7d, 0xb3, 0xa3, 0x64, 0x86, 0x03,
848 0x7c, 0x7c, 0x3f, 0x99, 0xdc, 0x21, 0x9f, 0x93, 0xc6, 0xb9, 0x1d, 0xe0,
849 0x21, 0x79, 0x78, 0x35, 0xdc, 0x1e, 0x27, 0x3c, 0x73, 0x7f, 0x0f, 0xd6,
850 0x4f, 0xde, 0xe9, 0xb4, 0xb7, 0xe3, 0xf5, 0x72, 0xce, 0x42, 0xf3, 0x91,
851 0x5b, 0x84, 0xba, 0xbb, 0xae, 0xf0, 0x87, 0x0f, 0x50, 0xa4, 0x5e, 0x80,
852 0x23, 0x57, 0x2b, 0xa0, 0xa3, 0xc3, 0x8a, 0x2f, 0xa8, 0x7a, 0x1a, 0x65,
853 0x8f, 0x62, 0xf8, 0x3e, 0xe2, 0xcd, 0xbc, 0x63, 0x56, 0x8e, 0x77, 0xf3,
854 0xf9, 0x69, 0x10, 0x57, 0xa8, 0xaf, 0x67, 0x2a, 0x9f, 0x7f, 0x7e, 0xeb,
855 0x1d, 0x99, 0xa6, 0x67, 0xcd, 0x9e, 0x42, 0x2e, 0x5e, 0x4e, 0x61, 0x24,
856 0xfa, 0xca, 0x2a, 0xeb, 0x62, 0x1f, 0xa3, 0x14, 0x0a, 0x06, 0x4b, 0x77,
857 0x78, 0x77, 0x9b, 0xf1, 0x03, 0xcc, 0xb5, 0xfe, 0xfb, 0x7a, 0x77, 0xa6,
858 0x82, 0x9f, 0xe5, 0xde, 0x9d, 0x0d, 0x4d, 0x37, 0xc6, 0x12, 0x73, 0x6d,
859 0xea, 0xbb, 0x48, 0xf0, 0xd2, 0x81, 0xcc, 0x1a, 0x47, 0xfa, 0xa4, 0xd2,
860 0xb2, 0x27, 0xa0, 0xfc, 0x30, 0x04, 0xdb, 0x05, 0xd3, 0x0b, 0xbc, 0x4d,
861 0x7a, 0x99, 0xef, 0x7f, 0x26, 0x01, 0xd4, 0x07, 0x0b, 0x1e, 0x99, 0x06,
862 0x3c, 0xde, 0x3d, 0x1c, 0x21, 0x82, 0x68, 0x46, 0x35, 0x38, 0x61, 0xea,
863 0xd4, 0xc2, 0x65, 0x09, 0x39, 0x87, 0xb4, 0xd3, 0x5d, 0x3c, 0xa3, 0x79,
864 0xe4, 0x01, 0x4e, 0xbf, 0x18, 0xba, 0x57, 0x3f, 0xdd, 0xea, 0x0a, 0x6b,
865 0x99, 0xfb, 0x93, 0xfa, 0xab, 0xee, 0x08, 0xdf, 0x38, 0x23, 0xae, 0x8d,
866 0xa8, 0x03, 0x13, 0xfe, 0x83, 0x88, 0xb0, 0xc2, 0xf9, 0x90, 0xa5, 0x1c,
867 0x01, 0x6f, 0x71, 0x91, 0x42, 0x35, 0x81, 0x74, 0x71, 0x6c, 0xba, 0x86,
868 0x48, 0xfe, 0x96, 0xd2, 0x88, 0x12, 0x36, 0x4e, 0xa6, 0x2f, 0xd1, 0xdb,
869 0xfa, 0xbf, 0xdb, 0x84, 0x01, 0xfc, 0x7d, 0x7a, 0xac, 0x20, 0xae, 0xf5,
870 0x95, 0xc9, 0xdc, 0x10, 0x5f, 0x4c, 0xae, 0x85, 0x01, 0x8b, 0xfe, 0x77,
871 0x13, 0x01, 0xae, 0x39, 0x59, 0x7e, 0xbc, 0xfd, 0xc9, 0x42, 0xe4, 0x13,
872 0x07, 0x3f, 0xa9, 0x74, 0xd9, 0xd5, 0xfc, 0xb9, 0x78, 0xbe, 0x97, 0xf5,
873 0xe7, 0x36, 0x7f, 0xfa, 0x23, 0x30, 0xeb, 0xab, 0x92, 0xd3, 0xdc, 0x3f,
874 0x7f, 0xc0, 0x77, 0x93, 0xf9, 0x88, 0xe3, 0x4e, 0x13, 0x53, 0x6d, 0x71,
875 0x87, 0xe9, 0x24, 0x2b, 0xae, 0x26, 0xbf, 0x62, 0x51, 0x04, 0x42, 0xe1,
876 0x13, 0x9d, 0xd8, 0x9f, 0x59, 0x87, 0x3f, 0xfc, 0x94, 0xff, 0xcf, 0x88,
877 0x88, 0xe6, 0xeb, 0x6e, 0xc1, 0x96, 0x04, 0x27, 0xc8, 0xda, 0xfa, 0xe8,
878 0x2e, 0xbb, 0x2c, 0x6e, 0xf4, 0xb4, 0x00, 0x7d, 0x8d, 0x3b, 0xef, 0x8b,
879 0x18, 0xa9, 0x5f, 0x32, 0xa9, 0xf2, 0x3a, 0x7e, 0x65, 0x2d, 0x6e, 0x8d,
880 0x75, 0x77, 0xf6, 0xa6, 0xd8, 0xf9, 0x6b, 0x51, 0xe6, 0x66, 0x52, 0x59,
881 0x39, 0x97, 0x22, 0xda, 0xb2, 0xd6, 0x82, 0x5a, 0x6e, 0x61, 0x60, 0x16,
882 0x48, 0x7b, 0xf1, 0xc3, 0x4d, 0x7f, 0x50, 0xfa, 0x4d, 0x58, 0x27, 0x30,
883 0xc8, 0x96, 0xe0, 0x41, 0x4f, 0x6b, 0xeb, 0x88, 0xa2, 0x7a, 0xef, 0x8a,
884 0x88, 0xc8, 0x50, 0x4b, 0x55, 0x66, 0xee, 0xbf, 0xc4, 0x01, 0x82, 0x4c,
885 0xec, 0xde, 0x37, 0x64, 0xd6, 0x1e, 0xcf, 0x3e, 0x2e, 0xfe, 0x84, 0x68,
886 0xbf, 0xa3, 0x68, 0x77, 0xa9, 0x03, 0xe4, 0xf8, 0xd7, 0xb2, 0x6e, 0xa3,
887 0xc4, 0xc3, 0x36, 0x53, 0xf3, 0xdd, 0x7e, 0x4c, 0xf0, 0xe9, 0xb2, 0x44,
888 0xe6, 0x60, 0x3d, 0x00, 0x9a, 0x08, 0xc3, 0x21, 0x17, 0x49, 0xda, 0x49,
889 0xfb, 0x4c, 0x8b, 0xe9, 0x10, 0x66, 0xfe, 0xb7, 0xe0, 0xf9, 0xdd, 0xbf,
890 0x41, 0xfe, 0x04, 0x9b, 0x7f, 0xe8, 0xd6, 0x2e, 0x4d, 0x0f, 0x7b, 0x10,
891 0x73, 0x4c, 0xa1, 0x3e, 0x43, 0xb7, 0xcf, 0x94, 0x97, 0x7e, 0x24, 0xbb,
892 0x87, 0xbf, 0x22, 0xb8, 0x3e, 0xeb, 0x9a, 0x3f, 0xe3, 0x86, 0xee, 0x21,
893 0xbc, 0xf5, 0x44, 0xeb, 0x60, 0x2e, 0xe7, 0x8f, 0x89, 0xa4, 0x91, 0x61,
894 0x28, 0x90, 0x85, 0x68, 0xe0, 0xa9, 0x62, 0x93, 0x86, 0x5a, 0x15, 0xbe,
895 0xb2, 0x76, 0x83, 0xf2, 0x0f, 0x00, 0xc7, 0xb6, 0x57, 0xe9, 0x1f, 0x92,
896 0x49, 0xfe, 0x50, 0x85, 0xbf, 0x39, 0x3d, 0xe4, 0x8b, 0x72, 0x2d, 0x49,
897 0xbe, 0x05, 0x0a, 0x34, 0x56, 0x80, 0xc6, 0x1f, 0x46, 0x59, 0xc9, 0xfe,
898 0x40, 0xfb, 0x78, 0x6d, 0x7a, 0xe5, 0x30, 0xe9, 0x81, 0x55, 0x75, 0x05,
899 0x63, 0xd2, 0x22, 0xee, 0x2e, 0x6e, 0xb9, 0x18, 0xe5, 0x8a, 0x5a, 0x66,
900 0xbd, 0x74, 0x30, 0xe3, 0x8b, 0x76, 0x22, 0x18, 0x1e, 0xef, 0x69, 0xe8,
901 0x9d, 0x07, 0xa7, 0x9a, 0x87, 0x6c, 0x04, 0x4b, 0x74, 0x2b, 0xbe, 0x37,
902 0x2f, 0x29, 0x9b, 0x60, 0x9d, 0x8b, 0x57, 0x55, 0x34, 0xca, 0x41, 0x25,
903 0xae, 0x56, 0x92, 0x34, 0x1b, 0x9e, 0xbd, 0xfe, 0x74, 0xbd, 0x4e, 0x29,
904 0xf0, 0x5e, 0x27, 0x94, 0xb0, 0x9e, 0x23, 0x9f, 0x4a, 0x0f, 0xa1, 0xdf,
905 0xe7, 0xc4, 0xdb, 0xbe, 0x0f, 0x1a, 0x0b, 0x6c, 0xb0, 0xe1, 0x06, 0x7c,
906 0x5a, 0x5b, 0x81, 0x1c, 0xb6, 0x12, 0xec, 0x6f, 0x3b, 0xbb, 0x84, 0x36,
907 0xd5, 0x28, 0x16, 0xea, 0x51, 0xa8, 0x99, 0x24, 0x8f, 0xe7, 0xf8, 0xe9,
908 0xce, 0xa1, 0x65, 0x96, 0x6f, 0x4e, 0x2f, 0xb7, 0x6f, 0x65, 0x39, 0xad,
909 0xfd, 0x2e, 0xa0, 0x37, 0x32, 0x2f, 0xf3, 0x95, 0xa1, 0x3a, 0xa1, 0x9d,
910 0x2c, 0x9e, 0xa1, 0x4b, 0x7e, 0xc9, 0x7e, 0x86, 0xaa, 0x16, 0x00, 0x82,
911 0x1d, 0x36, 0xbf, 0x98, 0x0a, 0x82, 0x5b, 0xcc, 0xc4, 0x6a, 0xad, 0xa0,
912 0x1f, 0x47, 0x98, 0xde, 0x8d, 0x68, 0x38, 0x3f, 0x33, 0xe2, 0x08, 0x3b,
913 0x2a, 0x65, 0xd9, 0x2f, 0x53, 0x68, 0xb8, 0x78, 0xd0, 0x1d, 0xbb, 0x2a,
914 0x73, 0x19, 0xba, 0x58, 0xea, 0xf1, 0x0a, 0xaa, 0xa6, 0xbe, 0x27, 0xd6,
915 0x00, 0x6b, 0x4e, 0x43, 0x8e, 0x5b, 0x19, 0xc1, 0x37, 0x0f, 0xfb, 0x81,
916 0x72, 0x10, 0xb6, 0x20, 0x32, 0xcd, 0xa2, 0x7c, 0x90, 0xd4, 0xf5, 0xcf,
917 0x1c, 0xcb, 0x14, 0x24, 0x7a, 0x4d, 0xf5, 0xd5, 0xd9, 0xce, 0x6a, 0x64,
918 0xc9, 0xd3, 0xa7, 0x36, 0x6f, 0x1d, 0xf1, 0xe9, 0x71, 0x6c, 0x3d, 0x02,
919 0xa4, 0x62, 0xb1, 0x82, 0x5c, 0x13, 0x4b, 0x6b, 0x68, 0xe2, 0x31, 0xef,
920 0xe4, 0x46, 0xfd, 0xe5, 0xa8, 0x29, 0xe9, 0x1e, 0xad, 0xff, 0x33, 0xdb,
921 0x0b, 0xc0, 0x92, 0xb1, 0xef, 0xeb, 0xb3, 0x6f, 0x96, 0x7b, 0xdf, 0xcd,
922 0x07, 0x19, 0x86, 0x60, 0x98, 0xcf, 0x95, 0xfe, 0x98, 0xdd, 0x29, 0xa6,
923 0x35, 0x7b, 0x46, 0x13, 0x03, 0xa8, 0xd9, 0x7c, 0xb3, 0xdf, 0x9f, 0x14,
924 0xb7, 0x34, 0x5a, 0xc4, 0x12, 0x81, 0xc5, 0x98, 0x25, 0x8d, 0x3e, 0xe3,
925 0xd8, 0x2d, 0xe4, 0x54, 0xab, 0xb0, 0x13, 0xfd, 0xd1, 0x3f, 0x3b, 0xbf,
926 0xa9, 0x45, 0x28, 0x8a, 0x2f, 0x9c, 0x1e, 0x2d, 0xe5, 0xab, 0x13, 0x95,
927 0x97, 0xc3, 0x34, 0x37, 0x8d, 0x93, 0x66, 0x31, 0x81, 0xa0, 0x30, 0x23,
928 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31,
929 0x16, 0x04, 0x14, 0xa5, 0x23, 0x9b, 0x7e, 0xe6, 0x45, 0x71, 0xbf, 0x48,
930 0xc6, 0x27, 0x3c, 0x96, 0x87, 0x63, 0xbd, 0x1f, 0xde, 0x72, 0x12, 0x30,
931 0x79, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x11, 0x01,
932 0x31, 0x6c, 0x1e, 0x6a, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72,
933 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x20,
934 0x00, 0x45, 0x00, 0x6e, 0x00, 0x68, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63,
935 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x52, 0x00, 0x53, 0x00, 0x41,
936 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x41,
937 0x00, 0x45, 0x00, 0x53, 0x00, 0x20, 0x00, 0x43, 0x00, 0x72, 0x00, 0x79,
938 0x00, 0x70, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x67, 0x00, 0x72, 0x00, 0x61,
939 0x00, 0x70, 0x00, 0x68, 0x00, 0x69, 0x00, 0x63, 0x00, 0x20, 0x00, 0x50,
940 0x00, 0x72, 0x00, 0x6f, 0x00, 0x76, 0x00, 0x69, 0x00, 0x64, 0x00, 0x65,
941 0x00, 0x72, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
942 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x93, 0xa8, 0xb2, 0x7e, 0xb7,
943 0xab, 0xf1, 0x1c, 0x3c, 0x36, 0x58, 0xdc, 0x67, 0x6d, 0x42, 0xa6, 0xfc,
944 0x53, 0x01, 0xe6, 0x04, 0x08, 0x77, 0x57, 0x22, 0xa1, 0x7d, 0xb9, 0xa2,
945 0x69, 0x02, 0x02, 0x08, 0x00
948 static void test_communication(void)
950 int ret;
951 SOCKET sock;
952 SECURITY_STATUS status;
953 ULONG attrs;
954 SCHANNEL_CRED cred;
955 CredHandle cred_handle;
956 CtxtHandle context;
957 SecPkgCredentials_NamesA names;
958 SecPkgContext_StreamSizes sizes;
959 SecPkgContext_ConnectionInfo conn_info;
960 SecPkgContext_KeyInfoA key_info;
961 const CERT_CONTEXT *cert;
962 CRYPT_DATA_BLOB pfx;
963 HCERTSTORE store;
964 SecPkgContext_NegotiationInfoA info;
965 SecBufferDesc buffers[2];
966 SecBuffer *buf;
967 unsigned buf_size = 8192;
968 unsigned char *data;
969 unsigned data_size;
971 if (!pQueryContextAttributesA)
973 win_skip("Required secur32 functions not available\n");
974 return;
977 /* Create a socket and connect to test.winehq.org */
978 if ((sock = create_ssl_socket( "test.winehq.org" )) == -1) return;
980 /* Create client credentials */
981 init_cred(&cred);
982 cred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
983 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS|SCH_CRED_MANUAL_CRED_VALIDATION;
985 status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
986 &cred, NULL, NULL, &cred_handle, NULL);
987 ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", status);
988 if (status != SEC_E_OK) return;
990 /* Initialize the connection */
991 init_buffers(&buffers[0], 4, buf_size);
992 init_buffers(&buffers[1], 4, buf_size);
994 buffers[0].pBuffers[0].BufferType = SECBUFFER_TOKEN;
995 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
996 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
997 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL);
998 ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status);
1000 buffers[1].cBuffers = 1;
1001 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1002 buffers[0].pBuffers[0].cbBuffer = 1;
1003 memset(buffers[1].pBuffers[0].pvBuffer, 0xfa, buf_size);
1004 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1005 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1006 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1007 todo_wine
1008 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
1009 todo_wine
1010 ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
1012 buffers[1].cBuffers = 1;
1013 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1014 buffers[0].pBuffers[0].cbBuffer = 1;
1015 memset(buffers[1].pBuffers[0].pvBuffer, 0, buf_size);
1016 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1017 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1018 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1019 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
1020 ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
1022 buffers[0].pBuffers[0].cbBuffer = 0;
1023 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1024 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1025 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1026 todo_wine
1027 ok(status == SEC_E_INSUFFICIENT_MEMORY || status == SEC_E_INVALID_TOKEN,
1028 "Expected SEC_E_INSUFFICIENT_MEMORY or SEC_E_INVALID_TOKEN, got %08x\n", status);
1029 ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
1031 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
1032 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1033 0, 0, NULL, 0, &context, NULL, &attrs, NULL);
1034 todo_wine
1035 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
1037 buffers[0].pBuffers[0].cbBuffer = buf_size;
1038 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
1039 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1040 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL);
1041 ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status);
1043 buf = &buffers[0].pBuffers[0];
1044 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
1045 buf->cbBuffer = buf_size;
1047 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1048 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1049 0, 0, NULL, 0, NULL, &buffers[0], &attrs, NULL);
1050 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status);
1051 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
1052 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
1054 buffers[1].cBuffers = 1;
1055 buffers[1].pBuffers[0].cbBuffer = 0;
1057 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1058 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1059 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1060 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status);
1061 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
1062 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
1064 buf = &buffers[1].pBuffers[0];
1065 buf->cbBuffer = buf_size;
1066 ret = receive_data(sock, buf);
1067 if (ret == -1)
1068 return;
1070 buffers[1].pBuffers[0].cbBuffer = 4;
1071 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1072 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1073 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1074 ok(status == SEC_E_INCOMPLETE_MESSAGE || status == SEC_E_INVALID_TOKEN,
1075 "Got unexpected status %#x.\n", status);
1076 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
1077 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
1079 buffers[1].pBuffers[0].cbBuffer = 5;
1080 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1081 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1082 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1083 ok(status == SEC_E_INCOMPLETE_MESSAGE || status == SEC_E_INVALID_TOKEN,
1084 "Got unexpected status %#x.\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");
1088 buffers[1].pBuffers[0].cbBuffer = ret;
1089 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1090 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM|ISC_REQ_USE_SUPPLIED_CREDS,
1091 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1092 buffers[1].pBuffers[0].cbBuffer = buf_size;
1093 while (status == SEC_I_CONTINUE_NEEDED)
1095 buf = &buffers[0].pBuffers[0];
1096 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
1097 buf->cbBuffer = buf_size;
1099 buf = &buffers[1].pBuffers[0];
1100 ret = receive_data(sock, buf);
1101 if (ret == -1)
1102 return;
1104 buf->BufferType = SECBUFFER_TOKEN;
1106 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1107 ISC_REQ_USE_SUPPLIED_CREDS,
1108 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1109 buffers[1].pBuffers[0].cbBuffer = buf_size;
1112 ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
1113 ok(status == SEC_E_OK || broken(status == SEC_E_ILLEGAL_MESSAGE) /* winxp */,
1114 "InitializeSecurityContext failed: %08x\n", status);
1115 if(status != SEC_E_OK) {
1116 skip("Handshake failed\n");
1117 return;
1119 ok(attrs == (ISC_RET_REPLAY_DETECT|ISC_RET_SEQUENCE_DETECT|ISC_RET_CONFIDENTIALITY|ISC_RET_STREAM|ISC_RET_USED_SUPPLIED_CREDS),
1120 "got %08x\n", attrs);
1122 status = QueryCredentialsAttributesA(&cred_handle, SECPKG_CRED_ATTR_NAMES, &names);
1123 ok(status == SEC_E_NO_CREDENTIALS || status == SEC_E_UNSUPPORTED_FUNCTION /* before Vista */, "expected SEC_E_NO_CREDENTIALS, got %08x\n", status);
1125 status = pQueryContextAttributesA(&context, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (void*)&cert);
1126 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_REMOTE_CERT_CONTEXT) failed: %08x\n", status);
1127 if(status == SEC_E_OK) {
1128 SecPkgContext_Bindings bindings = {0xdeadbeef, (void*)0xdeadbeef};
1130 test_remote_cert(cert);
1132 status = pQueryContextAttributesA(&context, SECPKG_ATTR_ENDPOINT_BINDINGS, &bindings);
1133 ok(status == SEC_E_OK || broken(status == SEC_E_UNSUPPORTED_FUNCTION),
1134 "QueryContextAttributesW(SECPKG_ATTR_ENDPOINT_BINDINGS) failed: %08x\n", status);
1135 if(status == SEC_E_OK) {
1136 static const char prefix[] = "tls-server-end-point:";
1137 const char *p;
1138 BYTE hash[64];
1139 DWORD hash_size;
1141 ok(bindings.BindingsLength == sizeof(*bindings.Bindings) + sizeof(prefix)-1 + 32 /* hash size */,
1142 "bindings.BindingsLength = %u\n", bindings.BindingsLength);
1143 ok(!bindings.Bindings->dwInitiatorAddrType, "dwInitiatorAddrType = %x\n", bindings.Bindings->dwInitiatorAddrType);
1144 ok(!bindings.Bindings->cbInitiatorLength, "cbInitiatorLength = %x\n", bindings.Bindings->cbInitiatorLength);
1145 ok(!bindings.Bindings->dwInitiatorOffset, "dwInitiatorOffset = %x\n", bindings.Bindings->dwInitiatorOffset);
1146 ok(!bindings.Bindings->dwAcceptorAddrType, "dwAcceptorAddrType = %x\n", bindings.Bindings->dwAcceptorAddrType);
1147 ok(!bindings.Bindings->cbAcceptorLength, "cbAcceptorLength = %x\n", bindings.Bindings->cbAcceptorLength);
1148 ok(!bindings.Bindings->dwAcceptorOffset, "dwAcceptorOffset = %x\n", bindings.Bindings->dwAcceptorOffset);
1149 ok(sizeof(*bindings.Bindings) + bindings.Bindings->cbApplicationDataLength == bindings.BindingsLength,
1150 "cbApplicationDataLength = %x\n", bindings.Bindings->cbApplicationDataLength);
1151 ok(bindings.Bindings->dwApplicationDataOffset == sizeof(*bindings.Bindings),
1152 "dwApplicationDataOffset = %x\n", bindings.Bindings->dwApplicationDataOffset);
1153 p = (const char*)(bindings.Bindings+1);
1154 ok(!memcmp(p, prefix, sizeof(prefix)-1), "missing prefix\n");
1155 p += sizeof(prefix)-1;
1157 hash_size = sizeof(hash);
1158 ret = CryptHashCertificate(0, CALG_SHA_256, 0, cert->pbCertEncoded, cert->cbCertEncoded, hash, &hash_size);
1159 if(ret) {
1160 ok(hash_size == 32, "hash_size = %u\n", hash_size);
1161 ok(!memcmp(hash, p, hash_size), "unexpected hash part\n");
1162 }else {
1163 win_skip("SHA 256 hash not supported.\n");
1166 FreeContextBuffer(bindings.Bindings);
1167 }else {
1168 win_skip("SECPKG_ATTR_ENDPOINT_BINDINGS not supported\n");
1171 status = pQueryContextAttributesA(&context, SECPKG_ATTR_UNIQUE_BINDINGS, &bindings);
1172 ok(status == SEC_E_OK || broken(status == SEC_E_UNSUPPORTED_FUNCTION),
1173 "QueryContextAttributesW(SECPKG_ATTR_UNIQUE_BINDINGS) failed: %08x\n", status);
1174 if(status == SEC_E_OK) {
1175 const char *p;
1176 static const char prefix[] = "tls-unique:";
1178 ok(bindings.BindingsLength > sizeof(*bindings.Bindings) + sizeof(prefix)-1,
1179 "bindings.BindingsLength = %u\n", bindings.BindingsLength);
1180 ok(!bindings.Bindings->dwInitiatorAddrType, "dwInitiatorAddrType = %x\n", bindings.Bindings->dwInitiatorAddrType);
1181 ok(!bindings.Bindings->cbInitiatorLength, "cbInitiatorLength = %x\n", bindings.Bindings->cbInitiatorLength);
1182 ok(!bindings.Bindings->dwInitiatorOffset, "dwInitiatorOffset = %x\n", bindings.Bindings->dwInitiatorOffset);
1183 ok(!bindings.Bindings->dwAcceptorAddrType, "dwAcceptorAddrType = %x\n", bindings.Bindings->dwAcceptorAddrType);
1184 ok(!bindings.Bindings->cbAcceptorLength, "cbAcceptorLength = %x\n", bindings.Bindings->cbAcceptorLength);
1185 ok(!bindings.Bindings->dwAcceptorOffset, "dwAcceptorOffset = %x\n", bindings.Bindings->dwAcceptorOffset);
1186 ok(sizeof(*bindings.Bindings) + bindings.Bindings->cbApplicationDataLength == bindings.BindingsLength,
1187 "cbApplicationDataLength = %x\n", bindings.Bindings->cbApplicationDataLength);
1188 ok(bindings.Bindings->dwApplicationDataOffset == sizeof(*bindings.Bindings),
1189 "dwApplicationDataOffset = %x\n", bindings.Bindings->dwApplicationDataOffset);
1190 p = (const char*)(bindings.Bindings+1);
1191 ok(!memcmp(p, prefix, sizeof(prefix)-1), "wrong prefix\n");
1192 FreeContextBuffer(bindings.Bindings);
1193 } else {
1194 win_skip("SECPKG_ATTR_UNIQUE_BINDINGS not supported\n");
1197 CertFreeCertificateContext(cert);
1200 status = pQueryContextAttributesA(&context, SECPKG_ATTR_CONNECTION_INFO, (void*)&conn_info);
1201 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_CONNECTION_INFO) failed: %08x\n", status);
1202 if(status == SEC_E_OK) {
1203 ok(conn_info.dwCipherStrength >= 128, "conn_info.dwCipherStrength = %d\n", conn_info.dwCipherStrength);
1204 ok(conn_info.dwHashStrength >= 128, "conn_info.dwHashStrength = %d\n", conn_info.dwHashStrength);
1207 status = pQueryContextAttributesA(&context, SECPKG_ATTR_KEY_INFO, &key_info);
1208 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_KEY_INFO) failed: %08x\n", status);
1209 if(status == SEC_E_OK) {
1210 ok(broken(key_info.SignatureAlgorithm == 0 /* WinXP,2003 */) ||
1211 key_info.SignatureAlgorithm == CALG_RSA_SIGN,
1212 "key_info.SignatureAlgorithm = %04x\n", key_info.SignatureAlgorithm);
1213 ok(broken(key_info.SignatureAlgorithm == 0 /* WinXP,2003 */) ||
1214 !strcmp(key_info.sSignatureAlgorithmName, "RSA"),
1215 "key_info.sSignatureAlgorithmName = %s\n", key_info.sSignatureAlgorithmName);
1216 ok(key_info.KeySize >= 128, "key_info.KeySize = %d\n", key_info.KeySize);
1219 status = pQueryContextAttributesA(&context, SECPKG_ATTR_STREAM_SIZES, &sizes);
1220 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_STREAM_SIZES) failed: %08x\n", status);
1222 status = pQueryContextAttributesA(&context, SECPKG_ATTR_NEGOTIATION_INFO, &info);
1223 ok(status == SEC_E_UNSUPPORTED_FUNCTION, "QueryContextAttributesA returned %08x\n", status);
1225 reset_buffers(&buffers[0]);
1227 /* Send a simple request so we get data for testing DecryptMessage */
1228 buf = &buffers[0].pBuffers[0];
1229 data = buf->pvBuffer;
1230 buf->BufferType = SECBUFFER_STREAM_HEADER;
1231 buf->cbBuffer = sizes.cbHeader;
1232 ++buf;
1233 buf->BufferType = SECBUFFER_DATA;
1234 buf->pvBuffer = data + sizes.cbHeader;
1235 buf->cbBuffer = sizeof(http_request) - 1;
1236 memcpy(buf->pvBuffer, http_request, sizeof(http_request) - 1);
1237 ++buf;
1238 buf->BufferType = SECBUFFER_STREAM_TRAILER;
1239 buf->pvBuffer = data + sizes.cbHeader + sizeof(http_request) -1;
1240 buf->cbBuffer = sizes.cbTrailer;
1242 status = EncryptMessage(&context, 0, &buffers[0], 0);
1243 ok(status == SEC_E_OK, "EncryptMessage failed: %08x\n", status);
1244 if (status != SEC_E_OK)
1245 return;
1247 buf = &buffers[0].pBuffers[0];
1248 send(sock, buf->pvBuffer, buffers[0].pBuffers[0].cbBuffer + buffers[0].pBuffers[1].cbBuffer + buffers[0].pBuffers[2].cbBuffer, 0);
1250 reset_buffers(&buffers[0]);
1251 buf->cbBuffer = buf_size;
1252 data_size = receive_data(sock, buf);
1254 /* Too few buffers */
1255 --buffers[0].cBuffers;
1256 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1257 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
1259 /* No data buffer */
1260 ++buffers[0].cBuffers;
1261 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1262 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
1264 /* Two data buffers */
1265 buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA;
1266 buffers[0].pBuffers[1].BufferType = SECBUFFER_DATA;
1267 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1268 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
1270 /* Too few empty buffers */
1271 buffers[0].pBuffers[1].BufferType = SECBUFFER_EXTRA;
1272 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1273 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
1275 /* Incomplete data */
1276 buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY;
1277 buffers[0].pBuffers[0].cbBuffer = (data[3]<<8) | data[4];
1278 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1279 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Expected SEC_E_INCOMPLETE_MESSAGE, got %08x\n", status);
1280 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_MISSING, "Expected first buffer to be SECBUFFER_MISSING\n");
1281 ok(buffers[0].pBuffers[0].cbBuffer == 5, "Expected first buffer to be a five bytes\n");
1283 /* Renegotiate */
1284 buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA;
1285 buffers[0].pBuffers[0].cbBuffer = data_size;
1286 buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY;
1287 buffers[0].pBuffers[1].cbBuffer = 0;
1288 buffers[0].pBuffers[2].BufferType = SECBUFFER_EMPTY;
1289 buffers[0].pBuffers[2].cbBuffer = 0;
1290 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1291 ok(status == SEC_I_RENEGOTIATE, "Expected SEC_I_RENEGOTIATE, got %08x\n", status);
1292 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_STREAM_HEADER, "got %u\n", buffers[0].pBuffers[0].BufferType);
1293 ok(buffers[0].pBuffers[0].cbBuffer == 5, "got %u\n", buffers[0].pBuffers[0].cbBuffer);
1294 ok(buffers[0].pBuffers[1].BufferType == SECBUFFER_DATA, "got %u\n", buffers[0].pBuffers[1].BufferType);
1295 ok(buffers[0].pBuffers[1].cbBuffer == 0, "got %u\n", buffers[0].pBuffers[1].cbBuffer);
1296 ok(buffers[0].pBuffers[2].BufferType == SECBUFFER_STREAM_TRAILER, "got %u\n", buffers[0].pBuffers[2].BufferType);
1297 todo_wine ok(buffers[0].pBuffers[2].cbBuffer == 32, "got %u\n", buffers[0].pBuffers[2].cbBuffer);
1299 pfx.pbData = (BYTE *)pfxdata;
1300 pfx.cbData = sizeof(pfxdata);
1301 store = PFXImportCertStore(&pfx, NULL, CRYPT_EXPORTABLE|CRYPT_USER_KEYSET|PKCS12_NO_PERSIST_KEY);
1302 ok(store != NULL, "got %u\n", GetLastError());
1304 cert = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL);
1305 ok(cert != NULL, "got %u\n", GetLastError());
1307 cred.paCred = &cert;
1308 cred.cCreds = 1;
1310 FreeCredentialsHandle(&cred_handle);
1311 status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
1312 &cred, NULL, NULL, &cred_handle, NULL);
1313 ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", status);
1315 init_buffers(&buffers[0], 4, buf_size);
1316 init_buffers(&buffers[1], 4, buf_size);
1318 buffers[0].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1319 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1320 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
1321 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL);
1322 todo_wine ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status);
1323 if (status != SEC_I_CONTINUE_NEEDED)
1325 skip("skipping remaining renegotiate test\n");
1326 goto done;
1329 buf = &buffers[0].pBuffers[0];
1330 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
1331 buf->cbBuffer = buf_size;
1333 buf = &buffers[1].pBuffers[0];
1334 buf->cbBuffer = buf_size;
1335 ret = receive_data(sock, buf);
1336 if (ret == -1)
1337 return;
1339 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1340 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1341 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM|ISC_REQ_USE_SUPPLIED_CREDS, 0, 0, &buffers[1], 0, NULL,
1342 &buffers[0], &attrs, NULL);
1343 buffers[1].pBuffers[0].cbBuffer = buf_size;
1344 while (status == SEC_I_CONTINUE_NEEDED)
1346 buf = &buffers[0].pBuffers[0];
1347 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
1348 buf->cbBuffer = buf_size;
1350 buf = &buffers[1].pBuffers[0];
1351 ret = receive_data(sock, buf);
1352 if (ret == -1)
1353 return;
1355 buf->BufferType = SECBUFFER_TOKEN;
1356 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1357 ISC_REQ_USE_SUPPLIED_CREDS, 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1358 buffers[1].pBuffers[0].cbBuffer = buf_size;
1360 ok (status == SEC_E_OK, "got %08x\n", status);
1362 buf = &buffers[0].pBuffers[0];
1363 buf->cbBuffer = buf_size;
1364 data_size = receive_data(sock, buf);
1366 buffers[0].pBuffers[0].cbBuffer = data_size;
1367 buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA;
1368 buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY;
1369 status = DecryptMessage(&context, &buffers[0], 0, NULL);
1370 ok(status == SEC_E_OK, "DecryptMessage failed: %08x\n", status);
1371 if (status == SEC_E_OK)
1373 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_STREAM_HEADER, "Expected first buffer to be SECBUFFER_STREAM_HEADER\n");
1374 ok(buffers[0].pBuffers[1].BufferType == SECBUFFER_DATA, "Expected second buffer to be SECBUFFER_DATA\n");
1375 ok(buffers[0].pBuffers[2].BufferType == SECBUFFER_STREAM_TRAILER, "Expected third buffer to be SECBUFFER_STREAM_TRAILER\n");
1377 data = buffers[0].pBuffers[1].pvBuffer;
1378 data[buffers[0].pBuffers[1].cbBuffer] = 0;
1381 done:
1382 DeleteSecurityContext(&context);
1383 FreeCredentialsHandle(&cred_handle);
1385 CertFreeCertificateContext(cert);
1386 CertCloseStore(store, 0);
1388 free_buffers(&buffers[0]);
1389 free_buffers(&buffers[1]);
1391 closesocket(sock);
1394 static void test_application_protocol_negotiation(void)
1396 int ret;
1397 SOCKET sock;
1398 SECURITY_STATUS status;
1399 ULONG attrs;
1400 SCHANNEL_CRED cred;
1401 CredHandle cred_handle;
1402 CtxtHandle context;
1403 SecPkgContext_ApplicationProtocol protocol;
1404 SecBufferDesc buffers[3];
1405 SecBuffer *buf;
1406 unsigned buf_size = 8192;
1407 unsigned char *alpn_buffer;
1408 unsigned int *extension_len;
1409 unsigned short *list_len;
1410 int list_start_index, offset = 0;
1412 if (!pQueryContextAttributesA)
1414 win_skip("Required secur32 functions not available\n");
1415 return;
1418 if ((sock = create_ssl_socket( "test.winehq.org" )) == -1) return;
1420 init_cred(&cred);
1421 cred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
1422 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS|SCH_CRED_MANUAL_CRED_VALIDATION;
1424 status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
1425 &cred, NULL, NULL, &cred_handle, NULL);
1426 ok(status == SEC_E_OK, "got %08x\n", status);
1427 if (status != SEC_E_OK) return;
1429 init_buffers(&buffers[0], 4, buf_size);
1430 init_buffers(&buffers[1], 4, buf_size);
1431 init_buffers(&buffers[2], 1, 128);
1433 alpn_buffer = buffers[2].pBuffers[0].pvBuffer;
1434 extension_len = (unsigned int *)&alpn_buffer[offset];
1435 offset += sizeof(*extension_len);
1436 *(unsigned int *)&alpn_buffer[offset] = SecApplicationProtocolNegotiationExt_ALPN;
1437 offset += sizeof(unsigned int);
1438 list_len = (unsigned short *)&alpn_buffer[offset];
1439 offset += sizeof(*list_len);
1440 list_start_index = offset;
1442 alpn_buffer[offset++] = sizeof("http/1.1") - 1;
1443 memcpy(&alpn_buffer[offset], "http/1.1", sizeof("http/1.1") - 1);
1444 offset += sizeof("http/1.1") - 1;
1445 alpn_buffer[offset++] = sizeof("h2") - 1;
1446 memcpy(&alpn_buffer[offset], "h2", sizeof("h2") - 1);
1447 offset += sizeof("h2") - 1;
1449 *list_len = offset - list_start_index;
1450 *extension_len = *list_len + sizeof(*extension_len) + sizeof(*list_len);
1452 buffers[2].pBuffers[0].BufferType = SECBUFFER_APPLICATION_PROTOCOLS;
1453 buffers[2].pBuffers[0].cbBuffer = offset;
1455 buffers[0].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1456 status = InitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
1457 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, &buffers[2], 0, &context, &buffers[0], &attrs, NULL);
1458 ok(status == SEC_I_CONTINUE_NEEDED, "got %08x\n", status);
1460 buf = &buffers[0].pBuffers[0];
1461 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
1462 buf->cbBuffer = buf_size;
1464 buf = &buffers[1].pBuffers[0];
1465 buf->cbBuffer = buf_size;
1466 ret = receive_data(sock, buf);
1467 if (ret == -1)
1468 return;
1470 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1471 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1472 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM|ISC_REQ_USE_SUPPLIED_CREDS, 0, 0, &buffers[1], 0, NULL,
1473 &buffers[0], &attrs, NULL);
1474 buffers[1].pBuffers[0].cbBuffer = buf_size;
1475 while (status == SEC_I_CONTINUE_NEEDED)
1477 buf = &buffers[0].pBuffers[0];
1478 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
1479 buf->cbBuffer = buf_size;
1481 buf = &buffers[1].pBuffers[0];
1482 ret = receive_data(sock, buf);
1483 if (ret == -1)
1484 return;
1486 buf->BufferType = SECBUFFER_TOKEN;
1487 status = InitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
1488 ISC_REQ_USE_SUPPLIED_CREDS, 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
1489 buffers[1].pBuffers[0].cbBuffer = buf_size;
1492 ok (status == SEC_E_OK || broken(status == SEC_E_ILLEGAL_MESSAGE) /* winxp */, "got %08x\n", status);
1493 if (status != SEC_E_OK)
1495 skip("Handshake failed\n");
1496 return;
1499 memset(&protocol, 0, sizeof(protocol));
1500 status = pQueryContextAttributesA(&context, SECPKG_ATTR_APPLICATION_PROTOCOL, &protocol);
1501 ok(status == SEC_E_OK || broken(status == SEC_E_UNSUPPORTED_FUNCTION) /* win2k8 */, "got %08x\n", status);
1502 if (status == SEC_E_OK)
1504 ok(protocol.ProtoNegoStatus == SecApplicationProtocolNegotiationStatus_Success, "got %u\n", protocol.ProtoNegoStatus);
1505 ok(protocol.ProtoNegoExt == SecApplicationProtocolNegotiationExt_ALPN, "got %u\n", protocol.ProtoNegoExt);
1506 ok(protocol.ProtocolIdSize == 8, "got %u\n", protocol.ProtocolIdSize);
1507 ok(!memcmp(protocol.ProtocolId, "http/1.1", 8), "wrong protocol id\n");
1510 DeleteSecurityContext(&context);
1511 FreeCredentialsHandle(&cred_handle);
1513 free_buffers(&buffers[0]);
1514 free_buffers(&buffers[1]);
1515 free_buffers(&buffers[2]);
1517 closesocket(sock);
1520 static void test_dtls(void)
1522 SECURITY_STATUS status;
1523 TimeStamp exp;
1524 SCHANNEL_CRED cred;
1525 CredHandle cred_handle;
1526 CtxtHandle ctx_handle;
1527 SecBufferDesc buffers[3];
1528 ULONG flags_req, flags_ret, attr;
1530 init_cred( &cred );
1531 cred.grbitEnabledProtocols = SP_PROT_DTLS_CLIENT | SP_PROT_DTLS1_2_CLIENT;
1532 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS;
1534 status = AcquireCredentialsHandleA( NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL,
1535 &cred_handle, &exp );
1536 if (status == SEC_E_ALGORITHM_MISMATCH)
1538 win_skip( "no DTLS support\n" );
1539 return;
1541 ok( status == SEC_E_OK, "got %08x\n", status );
1543 flags_req = ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_EXTENDED_ERROR | ISC_REQ_DATAGRAM | ISC_REQ_USE_SUPPLIED_CREDS |
1544 ISC_REQ_CONFIDENTIALITY | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT;
1546 init_buffers( &buffers[0], 1, 128 );
1547 buffers[0].pBuffers[0].BufferType = SECBUFFER_DTLS_MTU;
1548 *(WORD *)(buffers[0].pBuffers[0].pvBuffer) = 1024;
1549 buffers[0].pBuffers[0].cbBuffer = 2;
1551 init_buffers( &buffers[1], 2, 2048 );
1552 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1553 buffers[1].pBuffers[0].cbBuffer = 1420;
1554 buffers[1].pBuffers[1].BufferType = SECBUFFER_ALERT;
1555 buffers[1].pBuffers[1].cbBuffer = 1024;
1556 buffers[1].pBuffers[1].pvBuffer = HeapAlloc( GetProcessHeap(), 0, 1024 );
1558 attr = 0;
1559 exp.LowPart = exp.HighPart = 0xdeadbeef;
1560 status = InitializeSecurityContextA( &cred_handle, NULL, (SEC_CHAR *)"winetest", flags_req, 0, 16, &buffers[0], 0,
1561 &ctx_handle, &buffers[1], &attr, &exp );
1562 ok( status == SEC_I_CONTINUE_NEEDED, "got %08x\n", status );
1564 flags_ret = ISC_RET_MANUAL_CRED_VALIDATION | ISC_RET_STREAM | ISC_RET_EXTENDED_ERROR | ISC_RET_DATAGRAM |
1565 ISC_RET_USED_SUPPLIED_CREDS | ISC_RET_CONFIDENTIALITY | ISC_RET_SEQUENCE_DETECT | ISC_RET_REPLAY_DETECT;
1566 ok( attr == flags_ret, "got %08x\n", attr );
1567 ok( !exp.LowPart, "got %08x\n", exp.LowPart );
1568 ok( !exp.HighPart, "got %08x\n", exp.HighPart );
1570 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
1571 buffers[1].pBuffers[0].cbBuffer = 1420;
1573 attr = 0;
1574 exp.LowPart = exp.HighPart = 0xdeadbeef;
1575 status = InitializeSecurityContextA( &cred_handle, &ctx_handle, (SEC_CHAR *)"winetest", flags_req, 0, 16, NULL, 0,
1576 &ctx_handle, &buffers[1], &attr, &exp );
1577 ok( status == SEC_E_INSUFFICIENT_MEMORY, "got %08x\n", status );
1579 flags_ret = ISC_RET_CONFIDENTIALITY | ISC_RET_SEQUENCE_DETECT | ISC_RET_REPLAY_DETECT;
1580 todo_wine ok( attr == flags_ret, "got %08x\n", attr );
1581 ok( !exp.LowPart, "got %08x\n", exp.LowPart );
1582 ok( !exp.HighPart, "got %08x\n", exp.HighPart );
1584 free_buffers( &buffers[0] );
1585 free_buffers( &buffers[1] );
1586 DeleteSecurityContext( &ctx_handle );
1587 FreeCredentialsHandle( &cred_handle );
1590 START_TEST(schannel)
1592 WSADATA wsa_data;
1593 pQueryContextAttributesA = (void*)GetProcAddress(GetModuleHandleA("secur32.dll"), "QueryContextAttributesA");
1595 WSAStartup(0x0202, &wsa_data);
1597 test_cread_attrs();
1598 testAcquireSecurityContext();
1599 test_InitializeSecurityContext();
1600 test_communication();
1601 test_application_protocol_negotiation();
1602 test_dtls();