ReactOS  0.4.14-dev-583-g2a1ba2c
schannel.c
Go to the documentation of this file.
1 /*
2  * Schannel tests
3  *
4  * Copyright 2006 Juan Lang
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
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>
29 
30 #include "wine/test.h"
31 
33 
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 };
71 
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 };
96 
98 
99 static const char *algid_to_str(ALG_ID alg)
100 {
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);
123  X(CALG_KEA_KEYX);
125  X(CALG_SKIPJACK);
126  X(CALG_TEK);
136  X(CALG_RC5);
137  X(CALG_HMAC);
138  X(CALG_TLS1PRF);
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
151  }
152 
153  sprintf(buf, "%x", alg);
154  return buf;
155 }
156 
157 static void init_cred(SCHANNEL_CRED *cred)
158 {
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;
172 }
173 
175 {
176  SecPkgCred_CipherStrengths strength = {-1,-1};
177  SECURITY_STATUS st;
178 
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);
184 }
185 
186 static void test_supported_protocols(CredHandle *handle, unsigned exprots)
187 {
190 
192  ok(status == SEC_E_OK, "QueryCredentialsAttributes failed: %08x\n", status);
193 
194  if(exprots)
195  ok(protocols.grbitProtocol == exprots, "protocols.grbitProtocol = %x, expected %x\n", protocols.grbitProtocol, exprots);
196 
197  trace("Supported protocols:\n");
198 
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 #undef X
207 
208  if(protocols.grbitProtocol)
209  trace("Unknown flags: %x\n", protocols.grbitProtocol);
210 }
211 
213 {
216  unsigned i;
217 
219  todo_wine ok(status == SEC_E_OK, "QueryCredentialsAttributes failed: %08x\n", status);
220  if(status != SEC_E_OK)
221  return;
222 
223  trace("Supported algorithms (%d):\n", algs.cSupportedAlgs);
224  for(i=0; i < algs.cSupportedAlgs; i++)
225  trace(" %s\n", algid_to_str(algs.palgSupportedAlgs[i]));
226 
228 }
229 
230 static void test_cread_attrs(void)
231 {
232  SCHANNEL_CRED schannel_cred;
234  CredHandle cred;
235 
237  NULL, NULL, NULL, NULL, &cred, NULL);
238  ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %x\n", status);
239 
240  test_supported_protocols(&cred, 0);
241  test_supported_algs(&cred);
242 
244  ok(status == SEC_E_INTERNAL_ERROR, "QueryCredentialsAttributes failed: %08x, expected SEC_E_INTERNAL_ERROR\n", status);
245 
247  ok(status == SEC_E_INTERNAL_ERROR, "QueryCredentialsAttributes failed: %08x, expected SEC_E_INTERNAL_ERROR\n", status);
248 
249  FreeCredentialsHandle(&cred);
250 
251  init_cred(&schannel_cred);
254  NULL, &schannel_cred, NULL, NULL, &cred, NULL);
255  ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %x\n", status);
256 
258  test_supported_algs(&cred);
259 
260  FreeCredentialsHandle(&cred);
261 }
262 
263 static void testAcquireSecurityContext(void)
264 {
265  BOOL has_schannel = FALSE;
266  SecPkgInfoA *package_info;
267  ULONG i;
268  SECURITY_STATUS st;
269  CredHandle cred;
271  TimeStamp exp;
272  SCHANNEL_CRED schanCred;
273  PCCERT_CONTEXT certs[2];
274  HCRYPTPROV csp;
275  WCHAR ms_def_prov_w[MAX_PATH];
276  BOOL ret;
277  HCRYPTKEY key;
278  CRYPT_KEY_PROV_INFO keyProvInfo;
279 
280 
281  if (SUCCEEDED(EnumerateSecurityPackagesA(&i, &package_info)))
282  {
283  while(i--)
284  {
285  if (!strcmp(package_info[i].Name, unisp_name_a))
286  {
287  has_schannel = TRUE;
288  break;
289  }
290  }
291  FreeContextBuffer(package_info);
292  }
293  if (!has_schannel)
294  {
295  skip("Schannel not available\n");
296  return;
297  }
298 
299  lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
300 
301  keyProvInfo.pwszContainerName = cspNameW;
302  keyProvInfo.pwszProvName = ms_def_prov_w;
303  keyProvInfo.dwProvType = PROV_RSA_FULL;
304  keyProvInfo.dwFlags = 0;
305  keyProvInfo.cProvParam = 0;
306  keyProvInfo.rgProvParam = NULL;
307  keyProvInfo.dwKeySpec = AT_SIGNATURE;
308 
311 
312  SetLastError(0xdeadbeef);
316  {
317  /* WinMe would crash on some tests */
318  win_skip("CryptAcquireContextW is not implemented\n");
319  return;
320  }
321 
323  NULL);
325  "Expected SEC_E_SECPKG_NOT_FOUND, got %08x\n", st);
326  if (0)
327  {
328  /* Crashes on Win2K */
330  NULL, NULL, NULL);
331  ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
332 
333  /* Crashes on WinNT */
335  NULL, NULL, NULL, NULL, NULL);
336  ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
337 
339  NULL, NULL, NULL, NULL, NULL, NULL);
340  ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
341 
342  /* Crashes */
344  NULL, NULL, NULL, NULL, NULL, NULL);
345  }
347  NULL, NULL, NULL, NULL, &cred, NULL);
348  ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
349  if(st == SEC_E_OK)
350  FreeCredentialsHandle(&cred);
351  memset(&cred, 0, sizeof(cred));
353  NULL, NULL, NULL, NULL, &cred, &exp);
354  ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
355  /* expriy is indeterminate in win2k3 */
356  trace("expiry: %08x%08x\n", exp.HighPart, exp.LowPart);
357 
359  ok(st == SEC_E_NO_CREDENTIALS || st == SEC_E_UNSUPPORTED_FUNCTION /* before Vista */, "expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
360 
361  FreeCredentialsHandle(&cred);
362 
363  /* Bad version in SCHANNEL_CRED */
364  memset(&schanCred, 0, sizeof(schanCred));
366  NULL, &schanCred, NULL, NULL, NULL, NULL);
367  ok(st == SEC_E_INTERNAL_ERROR ||
368  st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */ ||
369  st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
371  NULL, &schanCred, NULL, NULL, NULL, NULL);
372  ok(st == SEC_E_INTERNAL_ERROR ||
373  st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */ ||
374  st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
375 
376  /* No cert in SCHANNEL_CRED succeeds for outbound.. */
377  schanCred.dwVersion = SCHANNEL_CRED_VERSION;
379  NULL, &schanCred, NULL, NULL, &cred, NULL);
380  ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
381  FreeCredentialsHandle(&cred);
382  /* but fails for inbound. */
384  NULL, &schanCred, NULL, NULL, &cred, NULL);
385  ok(st == SEC_E_NO_CREDENTIALS ||
386  st == SEC_E_OK /* Vista/win2k8 */,
387  "Expected SEC_E_NO_CREDENTIALS or SEC_E_OK, got %08x\n", st);
388 
389  if (0)
390  {
391  /* Crashes with bad paCred pointer */
392  schanCred.cCreds = 1;
394  NULL, &schanCred, NULL, NULL, NULL, NULL);
395  }
396 
397  /* Bogus cert in SCHANNEL_CRED. Windows fails with
398  * SEC_E_UNKNOWN_CREDENTIALS, but I'll accept SEC_E_NO_CREDENTIALS too.
399  */
400  schanCred.cCreds = 1;
401  schanCred.paCred = &certs[0];
403  NULL, &schanCred, NULL, NULL, NULL, NULL);
405  st == SEC_E_NO_CREDENTIALS ||
406  st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
408  NULL, &schanCred, NULL, NULL, NULL, NULL);
410  st == SEC_E_NO_CREDENTIALS ||
411  st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
412 
413  /* Good cert, but missing private key. Windows fails with
414  * SEC_E_NO_CREDENTIALS, but I'll accept SEC_E_UNKNOWN_CREDENTIALS too.
415  */
416  schanCred.cCreds = 1;
417  schanCred.paCred = &certs[1];
419  NULL, &schanCred, NULL, NULL, &cred, NULL);
421  st == SEC_E_INTERNAL_ERROR, /* win2k */
422  "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
423  "or SEC_E_INTERNAL_ERROR, got %08x\n", st);
425  NULL, &schanCred, NULL, NULL, NULL, NULL);
427  st == SEC_E_INTERNAL_ERROR, /* win2k */
428  "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
429  "or SEC_E_INTERNAL_ERROR, got %08x\n", st);
430 
431  /* Good cert, with CRYPT_KEY_PROV_INFO set before it's had a key loaded. */
433  CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo);
434  schanCred.dwVersion = SCH_CRED_V3;
435  ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
437  NULL, &schanCred, NULL, NULL, &cred, NULL);
438  ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INTERNAL_ERROR /* WinNT */ ||
439  st == SEC_E_INSUFFICIENT_MEMORY /* win10 */,
440  "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st);
442  NULL, &schanCred, NULL, NULL, &cred, NULL);
443  ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INTERNAL_ERROR /* WinNT */ ||
444  st == SEC_E_INSUFFICIENT_MEMORY /* win10 */,
445  "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st);
446 
449  ok(ret, "CryptAcquireContextW failed: %08x\n", GetLastError());
450  ret = 0;
451 
452  ret = CryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
453  ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
454  if (ret)
455  {
456  PCCERT_CONTEXT tmp;
457 
458  if (0)
459  {
460  /* Crashes */
462  NULL, &schanCred, NULL, NULL, NULL, NULL);
463 
464  /* Crashes on WinNT */
465  /* Good cert with private key, bogus version */
466  schanCred.dwVersion = SCH_CRED_V1;
468  NULL, &schanCred, NULL, NULL, &cred, NULL);
469  ok(st == SEC_E_INTERNAL_ERROR ||
470  st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
471  "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
473  NULL, &schanCred, NULL, NULL, &cred, NULL);
474  ok(st == SEC_E_INTERNAL_ERROR ||
475  st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
476  "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
477  schanCred.dwVersion = SCH_CRED_V2;
479  NULL, &schanCred, NULL, NULL, &cred, NULL);
480  ok(st == SEC_E_INTERNAL_ERROR ||
481  st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
482  "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
484  NULL, &schanCred, NULL, NULL, &cred, NULL);
485  ok(st == SEC_E_INTERNAL_ERROR ||
486  st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
487  "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
488  }
489 
490  /* Succeeds on V3 or higher */
491  schanCred.dwVersion = SCH_CRED_V3;
493  NULL, &schanCred, NULL, NULL, &cred, NULL);
494  ok(st == SEC_E_OK || st == SEC_E_INSUFFICIENT_MEMORY /* win10 */,
495  "AcquireCredentialsHandleA failed: %08x\n", st);
496  FreeCredentialsHandle(&cred);
498  NULL, &schanCred, NULL, NULL, &cred, NULL);
499  ok(st == SEC_E_OK || st == SEC_E_UNKNOWN_CREDENTIALS /* win2k3 */ ||
500  st == SEC_E_INSUFFICIENT_MEMORY /* win10 */,
501  "AcquireCredentialsHandleA failed: %08x\n", st);
502  FreeCredentialsHandle(&cred);
503  schanCred.dwVersion = SCHANNEL_CRED_VERSION;
505  NULL, &schanCred, NULL, NULL, &cred, NULL);
506  ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
507  FreeCredentialsHandle(&cred);
509  NULL, &schanCred, NULL, NULL, &cred, NULL);
510  ok(st == SEC_E_OK ||
511  st == SEC_E_UNKNOWN_CREDENTIALS, /* win2k3 */
512  "AcquireCredentialsHandleA failed: %08x\n", st);
513  if (st == SEC_E_OK) test_strength(&cred);
514  FreeCredentialsHandle(&cred);
515 
516  /* How about more than one cert? */
517  schanCred.cCreds = 2;
518  schanCred.paCred = certs;
520  NULL, &schanCred, NULL, NULL, &cred, NULL);
522  st == SEC_E_NO_CREDENTIALS /* Vista/win2k8 */ ||
523  st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
525  NULL, &schanCred, NULL, NULL, &cred, NULL);
527  st == SEC_E_NO_CREDENTIALS ||
528  st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
529  tmp = certs[0];
530  certs[0] = certs[1];
531  certs[1] = tmp;
533  NULL, &schanCred, NULL, NULL, &cred, NULL);
535  st == SEC_E_NO_CREDENTIALS ||
536  st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
538  NULL, &schanCred, NULL, NULL, &cred, NULL);
540  "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
541  /* FIXME: what about two valid certs? */
542 
544  }
545 
546  CryptReleaseContext(csp, 0);
548 
549  CertFreeCertificateContext(certs[0]);
550  CertFreeCertificateContext(certs[1]);
551 }
552 
553 static void test_remote_cert(PCCERT_CONTEXT remote_cert)
554 {
555  PCCERT_CONTEXT iter = NULL;
556  BOOL incl_remote = FALSE;
557  unsigned cert_cnt = 0;
558 
559  ok(remote_cert->hCertStore != NULL, "hCertStore == NULL\n");
560 
561  while((iter = CertEnumCertificatesInStore(remote_cert->hCertStore, iter))) {
562  if(iter == remote_cert)
563  incl_remote = TRUE;
564  cert_cnt++;
565  }
566 
567  ok(cert_cnt == 4, "cert_cnt = %u\n", cert_cnt);
568  ok(incl_remote, "context does not contain cert itself\n");
569 }
570 
571 static const char http_request[] = "HEAD /test.html HTTP/1.1\r\nHost: test.winehq.org\r\nConnection: close\r\n\r\n";
572 
573 static void init_buffers(SecBufferDesc *desc, unsigned count, unsigned size)
574 {
575  desc->ulVersion = SECBUFFER_VERSION;
576  desc->cBuffers = count;
577  desc->pBuffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count*sizeof(SecBuffer));
578 
579  desc->pBuffers[0].cbBuffer = size;
580  desc->pBuffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, size);
581 }
582 
584 {
585  unsigned i;
586 
587  for (i = 0; i < desc->cBuffers; ++i)
588  {
589  desc->pBuffers[i].BufferType = SECBUFFER_EMPTY;
590  if (i > 0)
591  {
592  desc->pBuffers[i].cbBuffer = 0;
593  desc->pBuffers[i].pvBuffer = NULL;
594  }
595  }
596 }
597 
599 {
600  HeapFree(GetProcessHeap(), 0, desc->pBuffers[0].pvBuffer);
601  HeapFree(GetProcessHeap(), 0, desc->pBuffers);
602 }
603 
605 {
606  unsigned received = 0;
607 
608  while (1)
609  {
610  unsigned char *data = buf->pvBuffer;
611  unsigned expected = 0;
612  int ret;
613 
614  ret = recv(sock, (char *)data+received, buf->cbBuffer-received, 0);
615  if (ret == -1)
616  {
617  skip("recv failed\n");
618  return -1;
619  }
620  else if(ret == 0)
621  {
622  skip("connection closed\n");
623  return -1;
624  }
625  received += ret;
626 
627  while (expected < received)
628  {
629  unsigned frame_size = 5 + ((data[3]<<8) | data[4]);
630  expected += frame_size;
631  data += frame_size;
632  }
633 
634  if (expected == received)
635  break;
636  }
637 
638  buf->cbBuffer = received;
639 
640  return received;
641 }
642 
644 {
645  SCHANNEL_CRED cred;
651  SecBufferDesc out_buffers = {SECBUFFER_VERSION, 1, &out_buffer};
652  SecBufferDesc in_buffers = {SECBUFFER_VERSION, 1, &in_buffer};
653  ULONG attrs;
654 
655  init_cred(&cred);
659  &cred, NULL, NULL, &cred_handle, NULL);
660  ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", status);
661  if (status != SEC_E_OK) return;
662 
665  0, 0, &in_buffers, 0, &context, &out_buffers, &attrs, NULL);
666  ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status);
667 
668  FreeContextBuffer(out_buffer.pvBuffer);
671 }
672 
673 static void test_communication(void)
674 {
675  int ret;
676 
677  WSADATA wsa_data;
678  SOCKET sock;
679  struct hostent *host;
680  struct sockaddr_in addr;
681 
683  ULONG attrs;
684 
685  SCHANNEL_CRED cred;
691  SecPkgContext_KeyInfoA key_info;
694 
696  SecBuffer *buf;
697  unsigned buf_size = 8192;
698  unsigned char *data;
699  unsigned data_size;
700 
702  {
703  win_skip("Required secur32 functions not available\n");
704  return;
705  }
706 
707  /* Create a socket and connect to test.winehq.org */
708  ret = WSAStartup(0x0202, &wsa_data);
709  if (ret)
710  {
711  skip("Can't init winsock 2.2\n");
712  return;
713  }
714 
715  host = gethostbyname("test.winehq.org");
716  if (!host)
717  {
718  skip("Can't resolve test.winehq.org\n");
719  return;
720  }
721 
722  addr.sin_family = host->h_addrtype;
723  addr.sin_addr = *(struct in_addr *)host->h_addr_list[0];
724  addr.sin_port = htons(443);
725  sock = socket(host->h_addrtype, SOCK_STREAM, 0);
726  if (sock == SOCKET_ERROR)
727  {
728  skip("Can't create socket\n");
729  return;
730  }
731 
732  ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
733  if (ret == SOCKET_ERROR)
734  {
735  skip("Can't connect to test.winehq.org\n");
736  return;
737  }
738 
739  /* Create client credentials */
740  init_cred(&cred);
743 
745  &cred, NULL, NULL, &cred_handle, NULL);
746  ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", status);
747  if (status != SEC_E_OK) return;
748 
749  /* Initialize the connection */
750  init_buffers(&buffers[0], 4, buf_size);
751  init_buffers(&buffers[1], 4, buf_size);
752 
753  buffers[0].pBuffers[0].BufferType = SECBUFFER_TOKEN;
756  0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL);
757  ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status);
758 
759  buffers[1].cBuffers = 1;
760  buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
761  buffers[0].pBuffers[0].cbBuffer = 1;
762  memset(buffers[1].pBuffers[0].pvBuffer, 0xfa, buf_size);
765  0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
766 todo_wine
767  ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
768 todo_wine
769  ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
770 
771  buffers[1].cBuffers = 1;
772  buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
773  buffers[0].pBuffers[0].cbBuffer = 1;
774  memset(buffers[1].pBuffers[0].pvBuffer, 0, buf_size);
777  0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
778  ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
779  ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
780 
781  buffers[0].pBuffers[0].cbBuffer = 0;
784  0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
785 todo_wine
787  "Expected SEC_E_INSUFFICIENT_MEMORY or SEC_E_INVALID_TOKEN, got %08x\n", status);
788  ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
789 
792  0, 0, NULL, 0, &context, NULL, &attrs, NULL);
793 todo_wine
794  ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
795 
796  buffers[0].pBuffers[0].cbBuffer = buf_size;
799  0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL);
800  ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status);
801 
802  buf = &buffers[0].pBuffers[0];
803  send(sock, buf->pvBuffer, buf->cbBuffer, 0);
804  buf->cbBuffer = buf_size;
805 
808  0, 0, NULL, 0, NULL, &buffers[0], &attrs, NULL);
809  ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status);
810  ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
811  ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
812 
813  buffers[1].cBuffers = 1;
814  buffers[1].pBuffers[0].cbBuffer = 0;
815 
818  0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
819  ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status);
820  ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
821  ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
822 
823  buf = &buffers[1].pBuffers[0];
824  buf->cbBuffer = buf_size;
825  ret = receive_data(sock, buf);
826  if (ret == -1)
827  return;
828 
829  buffers[1].pBuffers[0].cbBuffer = 4;
832  0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
834  "Got unexpected status %#x.\n", status);
835  ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
836  ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
837 
838  buffers[1].pBuffers[0].cbBuffer = 5;
841  0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
843  "Got unexpected status %#x.\n", status);
844  ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
845  ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
846 
847  buffers[1].pBuffers[0].cbBuffer = ret;
850  0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
851  buffers[1].pBuffers[0].cbBuffer = buf_size;
852  while (status == SEC_I_CONTINUE_NEEDED)
853  {
854  buf = &buffers[0].pBuffers[0];
855  send(sock, buf->pvBuffer, buf->cbBuffer, 0);
856  buf->cbBuffer = buf_size;
857 
858  buf = &buffers[1].pBuffers[0];
859  ret = receive_data(sock, buf);
860  if (ret == -1)
861  return;
862 
863  buf->BufferType = SECBUFFER_TOKEN;
864 
867  0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
868  buffers[1].pBuffers[0].cbBuffer = buf_size;
869  }
870 
871  ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n");
872  ok(status == SEC_E_OK || broken(status == SEC_E_ILLEGAL_MESSAGE) /* winxp */,
873  "InitializeSecurityContext failed: %08x\n", status);
874  if(status != SEC_E_OK) {
875  skip("Handshake failed\n");
876  return;
877  }
879  "got %08x\n", attrs);
880 
882  ok(status == SEC_E_NO_CREDENTIALS || status == SEC_E_UNSUPPORTED_FUNCTION /* before Vista */, "expected SEC_E_NO_CREDENTIALS, got %08x\n", status);
883 
885  ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_REMOTE_CERT_CONTEXT) failed: %08x\n", status);
886  if(status == SEC_E_OK) {
887  SecPkgContext_Bindings bindings = {0xdeadbeef, (void*)0xdeadbeef};
888 
890 
893  "QueryContextAttributesW(SECPKG_ATTR_ENDPOINT_BINDINGS) failed: %08x\n", status);
894  if(status == SEC_E_OK) {
895  static const char prefix[] = "tls-server-end-point:";
896  const char *p;
897  BYTE hash[64];
898  DWORD hash_size;
899 
900  ok(bindings.BindingsLength == sizeof(*bindings.Bindings) + sizeof(prefix)-1 + 32 /* hash size */,
901  "bindings.BindingsLength = %u\n", bindings.BindingsLength);
902  ok(!bindings.Bindings->dwInitiatorAddrType, "dwInitiatorAddrType = %x\n", bindings.Bindings->dwInitiatorAddrType);
903  ok(!bindings.Bindings->cbInitiatorLength, "cbInitiatorLength = %x\n", bindings.Bindings->cbInitiatorLength);
904  ok(!bindings.Bindings->dwInitiatorOffset, "dwInitiatorOffset = %x\n", bindings.Bindings->dwInitiatorOffset);
905  ok(!bindings.Bindings->dwAcceptorAddrType, "dwAcceptorAddrType = %x\n", bindings.Bindings->dwAcceptorAddrType);
906  ok(!bindings.Bindings->cbAcceptorLength, "cbAcceptorLength = %x\n", bindings.Bindings->cbAcceptorLength);
907  ok(!bindings.Bindings->dwAcceptorOffset, "dwAcceptorOffset = %x\n", bindings.Bindings->dwAcceptorOffset);
908  ok(sizeof(*bindings.Bindings) + bindings.Bindings->cbApplicationDataLength == bindings.BindingsLength,
909  "cbApplicationDataLength = %x\n", bindings.Bindings->cbApplicationDataLength);
910  ok(bindings.Bindings->dwApplicationDataOffset == sizeof(*bindings.Bindings),
911  "dwApplicationDataOffset = %x\n", bindings.Bindings->dwApplicationDataOffset);
912  p = (const char*)(bindings.Bindings+1);
913  ok(!memcmp(p, prefix, sizeof(prefix)-1), "missing prefix\n");
914  p += sizeof(prefix)-1;
915 
916  hash_size = sizeof(hash);
917  ret = CryptHashCertificate(0, CALG_SHA_256, 0, cert->pbCertEncoded, cert->cbCertEncoded, hash, &hash_size);
918  if(ret) {
919  ok(hash_size == 32, "hash_size = %u\n", hash_size);
920  ok(!memcmp(hash, p, hash_size), "unexpected hash part\n");
921  }else {
922  win_skip("SHA 256 hash not supported.\n");
923  }
924 
925  FreeContextBuffer(bindings.Bindings);
926  }else {
927  win_skip("SECPKG_ATTR_ENDPOINT_BINDINGS not supported\n");
928  }
929 
931  }
932 
934  ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_CONNECTION_INFO) failed: %08x\n", status);
935  if(status == SEC_E_OK) {
936  ok(conn_info.dwCipherStrength >= 128, "conn_info.dwCipherStrength = %d\n", conn_info.dwCipherStrength);
937  ok(conn_info.dwHashStrength >= 128, "conn_info.dwHashStrength = %d\n", conn_info.dwHashStrength);
938  }
939 
941  ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_KEY_INFO) failed: %08x\n", status);
942  if(status == SEC_E_OK) {
943  ok(broken(key_info.SignatureAlgorithm == 0 /* WinXP,2003 */) ||
944  key_info.SignatureAlgorithm == CALG_RSA_SIGN,
945  "key_info.SignatureAlgorithm = %04x\n", key_info.SignatureAlgorithm);
946  ok(broken(key_info.SignatureAlgorithm == 0 /* WinXP,2003 */) ||
947  !strcmp(key_info.sSignatureAlgorithmName, "RSA"),
948  "key_info.sSignatureAlgorithmName = %s\n", key_info.sSignatureAlgorithmName);
949  ok(key_info.KeySize >= 128, "key_info.KeySize = %d\n", key_info.KeySize);
950  }
951 
953  ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_STREAM_SIZES) failed: %08x\n", status);
954 
956  ok(status == SEC_E_UNSUPPORTED_FUNCTION, "QueryContextAttributesA returned %08x\n", status);
957 
958  reset_buffers(&buffers[0]);
959 
960  /* Send a simple request so we get data for testing DecryptMessage */
961  buf = &buffers[0].pBuffers[0];
962  data = buf->pvBuffer;
963  buf->BufferType = SECBUFFER_STREAM_HEADER;
964  buf->cbBuffer = sizes.cbHeader;
965  ++buf;
966  buf->BufferType = SECBUFFER_DATA;
967  buf->pvBuffer = data + sizes.cbHeader;
968  buf->cbBuffer = sizeof(http_request) - 1;
969  memcpy(buf->pvBuffer, http_request, sizeof(http_request) - 1);
970  ++buf;
971  buf->BufferType = SECBUFFER_STREAM_TRAILER;
972  buf->pvBuffer = data + sizes.cbHeader + sizeof(http_request) -1;
973  buf->cbBuffer = sizes.cbTrailer;
974 
975  status = EncryptMessage(&context, 0, &buffers[0], 0);
976  ok(status == SEC_E_OK, "EncryptMessage failed: %08x\n", status);
977  if (status != SEC_E_OK)
978  return;
979 
980  buf = &buffers[0].pBuffers[0];
981  send(sock, buf->pvBuffer, buffers[0].pBuffers[0].cbBuffer + buffers[0].pBuffers[1].cbBuffer + buffers[0].pBuffers[2].cbBuffer, 0);
982 
983  reset_buffers(&buffers[0]);
984  buf->cbBuffer = buf_size;
985  data_size = receive_data(sock, buf);
986 
987  /* Too few buffers */
988  --buffers[0].cBuffers;
990  ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
991 
992  /* No data buffer */
993  ++buffers[0].cBuffers;
995  ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
996 
997  /* Two data buffers */
998  buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA;
999  buffers[0].pBuffers[1].BufferType = SECBUFFER_DATA;
1000  status = DecryptMessage(&context, &buffers[0], 0, NULL);
1001  ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
1002 
1003  /* Too few empty buffers */
1004  buffers[0].pBuffers[1].BufferType = SECBUFFER_EXTRA;
1005  status = DecryptMessage(&context, &buffers[0], 0, NULL);
1006  ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
1007 
1008  /* Incomplete data */
1009  buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY;
1010  buffers[0].pBuffers[0].cbBuffer = (data[3]<<8) | data[4];
1011  status = DecryptMessage(&context, &buffers[0], 0, NULL);
1012  ok(status == SEC_E_INCOMPLETE_MESSAGE, "Expected SEC_E_INCOMPLETE_MESSAGE, got %08x\n", status);
1013  ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_MISSING, "Expected first buffer to be SECBUFFER_MISSING\n");
1014  ok(buffers[0].pBuffers[0].cbBuffer == 5, "Expected first buffer to be a five bytes\n");
1015 
1016  buffers[0].pBuffers[0].cbBuffer = data_size;
1017  buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA;
1018  buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY;
1019  status = DecryptMessage(&context, &buffers[0], 0, NULL);
1020  ok(status == SEC_E_OK, "DecryptMessage failed: %08x\n", status);
1021  if (status == SEC_E_OK)
1022  {
1023  ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_STREAM_HEADER, "Expected first buffer to be SECBUFFER_STREAM_HEADER\n");
1024  ok(buffers[0].pBuffers[1].BufferType == SECBUFFER_DATA, "Expected second buffer to be SECBUFFER_DATA\n");
1025  ok(buffers[0].pBuffers[2].BufferType == SECBUFFER_STREAM_TRAILER, "Expected third buffer to be SECBUFFER_STREAM_TRAILER\n");
1026 
1027  data = buffers[0].pBuffers[1].pvBuffer;
1028  data[buffers[0].pBuffers[1].cbBuffer] = 0;
1029  }
1030 
1033 
1034  free_buffers(&buffers[0]);
1035  free_buffers(&buffers[1]);
1036 
1037  closesocket(sock);
1038 }
1039 
1040 START_TEST(schannel)
1041 {
1042  pQueryContextAttributesA = (void*)GetProcAddress(GetModuleHandleA("secur32.dll"), "QueryContextAttributesA");
1043 
1044  test_cread_attrs();
1048 }
#define SEC_E_SECPKG_NOT_FOUND
Definition: winerror.h:2914
#define CALG_SCHANNEL_MASTER_HASH
Definition: wincrypt.h:1844
static void test_strength(PCredHandle handle)
Definition: schannel.c:174
#define SEC_E_INTERNAL_ERROR
Definition: winerror.h:2913
#define CALG_AES_192
Definition: wincrypt.h:1834
#define SOCKET_ERROR
Definition: winsock.h:333
#define SCH_CRED_V3
Definition: schannel.h:21
#define CALG_SSL3_SHAMD5
Definition: wincrypt.h:1809
LPWSTR pwszContainerName
Definition: wincrypt.h:209
START_TEST(schannel)
Definition: schannel.c:1040
#define CALG_RC2
Definition: wincrypt.h:1829
#define SP_PROT_SSL3_CLIENT
Definition: schannel.h:30
#define SECPKG_ATTR_SUPPORTED_PROTOCOLS
Definition: schannel.h:74
#define SECPKG_ATTR_KEY_INFO
Definition: sspi.h:513
#define CRYPT_NEWKEYSET
Definition: wincrypt.h:2070
static void test_remote_cert(PCCERT_CONTEXT remote_cert)
Definition: schannel.c:553
#define TRUE
Definition: types.h:120
#define CALG_3DES
Definition: wincrypt.h:1830
#define CALG_TEK
Definition: wincrypt.h:1841
#define SCH_CRED_V1
Definition: schannel.h:18
#define SECPKG_CRED_OUTBOUND
Definition: sspi.h:278
static void init_buffers(SecBufferDesc *desc, unsigned count, unsigned size)
Definition: schannel.c:573
ULONG dwInitiatorOffset
Definition: sspi.h:224
static SOCKET sock
Definition: syslog.c:45
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define SCH_CRED_NO_DEFAULT_CREDS
Definition: schannel.h:57
unsigned int ALG_ID
Definition: wincrypt.h:45
#define SECBUFFER_STREAM_HEADER
Definition: sspi.h:153
static void test_communication(void)
Definition: schannel.c:673
ULONG cbApplicationDataLength
Definition: sspi.h:228
#define CALG_DSS_SIGN
Definition: wincrypt.h:1817
Definition: http.c:7098
#define UNISP_NAME_A
Definition: sspi.h:37
SECURITY_STATUS WINAPI FreeContextBuffer(PVOID pv)
Definition: sspi.c:699
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define SP_PROT_TLS1_0_CLIENT
Definition: schannel.h:32
#define ISC_RET_CONFIDENTIALITY
Definition: sspi.h:376
#define CALG_SHA_384
Definition: wincrypt.h:1814
#define ISC_REQ_STREAM
Definition: sspi.h:364
#define SP_PROT_TLS1_CLIENT
Definition: schannel.h:31
#define SP_PROT_TLS1_1_CLIENT
Definition: schannel.h:33
GLuint GLuint GLsizei count
Definition: gl.h:1545
DWORD dwVersion
Definition: schannel.h:88
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
static void testAcquireSecurityContext(void)
Definition: schannel.c:263
char CHAR
Definition: xmlstorage.h:175
static WCHAR cspNameW[]
Definition: schannel.c:44
static const BYTE bigCert[]
Definition: schannel.c:34
char * host
Definition: whois.c:55
#define closesocket
Definition: precomp.h:57
#define SECPKG_ATTR_REMOTE_CERT_CONTEXT
Definition: schannel.h:69
SECURITY_STATUS WINAPI EnumerateSecurityPackagesA(PULONG pcPackages, PSecPkgInfoA *ppPackageInfo)
Definition: sspi.c:855
r received
Definition: btrfs.c:2864
#define CALG_ECMQV
Definition: wincrypt.h:1827
static SecHandle cred_handle
#define CALG_RSA_SIGN
Definition: wincrypt.h:1816
HCERTSTORE hCertStore
Definition: wincrypt.h:483
#define CALG_RC4
Definition: wincrypt.h:1837
#define SECBUFFER_DATA
Definition: sspi.h:147
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
SECURITY_STATUS WINAPI FreeCredentialsHandle(PCredHandle phCredential)
Definition: wrapper.c:151
#define ISC_RET_USED_SUPPLIED_CREDS
Definition: sspi.h:379
const GLuint * buffers
Definition: glext.h:5916
ULONG SignatureAlgorithm
Definition: sspi.h:593
#define SECPKG_CRED_ATTR_NAMES
Definition: sspi.h:233
DWORD cSupportedAlgs
Definition: schannel.h:94
#define SEC_E_UNSUPPORTED_FUNCTION
Definition: winerror.h:2911
INT WSAAPI connect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: sockctrl.c:23
static void free_buffers(SecBufferDesc *desc)
Definition: schannel.c:598
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID out_buffer
Definition: file.c:100
#define SECBUFFER_EXTRA
Definition: sspi.h:151
#define CALG_TLS1_MASTER
Definition: wincrypt.h:1849
#define SP_PROT_TLS1_2_CLIENT
Definition: schannel.h:34
struct _test_info info[]
Definition: SetCursorPos.c:19
ULONG cbInitiatorLength
Definition: sspi.h:223
BOOL WINAPI CryptAcquireContextW(HCRYPTPROV *phProv, LPCWSTR pszContainer, LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
Definition: crypt.c:358
#define SECPKG_ATTR_ENDPOINT_BINDINGS
Definition: sspi.h:533
PCCERT_CONTEXT * paCred
Definition: schannel.h:90
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static unsigned char * in_buffer
Definition: iccvid.c:87
GLuint GLuint * names
Definition: glext.h:11545
#define X509_ASN_ENCODING
Definition: wincrypt.h:2297
#define CALG_NO_SIGN
Definition: wincrypt.h:1818
#define ISC_REQ_USE_SUPPLIED_CREDS
Definition: sspi.h:356
#define CALG_HASH_REPLACE_OWF
Definition: wincrypt.h:1812
#define CALG_3DES_112
Definition: wincrypt.h:1831
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ALG_ID * palgSupportedAlgs
Definition: schannel.h:95
SECURITY_STATUS WINAPI QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
Definition: wrapper.c:177
#define CALG_SCHANNEL_ENC_KEY
Definition: wincrypt.h:1846
#define CALG_SEAL
Definition: wincrypt.h:1838
#define CALG_MD2
Definition: wincrypt.h:1803
#define SEC_E_INSUFFICIENT_MEMORY
Definition: winerror.h:2909
ULONG dwInitiatorAddrType
Definition: sspi.h:222
int hash
Definition: main.c:58
#define CALG_AES_256
Definition: wincrypt.h:1835
unsigned int BOOL
Definition: ntddk_ex.h:94
#define SCH_CRED_V2
Definition: schannel.h:19
static const WCHAR desc[]
Definition: protectdata.c:36
#define CALG_SSL2_MASTER
Definition: wincrypt.h:1848
#define CALG_TLS1PRF
Definition: wincrypt.h:1811
#define SECBUFFER_MISSING
Definition: sspi.h:150
#define SCHANNEL_CRED_VERSION
Definition: schannel.h:22
#define SECPKG_CRED_INBOUND
Definition: sspi.h:277
DWORD cMappers
Definition: schannel.h:92
DWORD dwSessionLifespan
Definition: schannel.h:99
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
smooth NULL
Definition: ftsmooth.c:416
#define SEC_E_ILLEGAL_MESSAGE
Definition: winerror.h:2943
static const char http_request[]
Definition: schannel.c:571
#define CALG_DES
Definition: wincrypt.h:1828
#define CALG_RSA_KEYX
Definition: wincrypt.h:1824
#define CALG_SKIPJACK
Definition: wincrypt.h:1840
DWORD grbitEnabledProtocols
Definition: schannel.h:96
#define SECPKG_ATTR_NEGOTIATION_INFO
Definition: sspi.h:520
#define X(x)
BOOL WINAPI CryptDestroyKey(HCRYPTKEY hKey)
Definition: crypt.c:935
#define SECBUFFER_EMPTY
Definition: sspi.h:146
static void reset_buffers(SecBufferDesc *desc)
Definition: schannel.c:583
#define SEC_I_CONTINUE_NEEDED
Definition: winerror.h:2927
static BYTE cert[]
Definition: msg.c:1437
LONG SECURITY_STATUS
Definition: sspi.h:34
static void test_supported_algs(CredHandle *handle)
Definition: schannel.c:212
static void test_supported_protocols(CredHandle *handle, unsigned exprots)
Definition: schannel.c:186
#define CALG_HUGHES_MD5
Definition: wincrypt.h:1823
HCERTSTORE hRootStore
Definition: schannel.h:91
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
#define CALG_ECDSA
Definition: wincrypt.h:1850
#define SP_PROT_SSL2_CLIENT
Definition: schannel.h:29
GLsizeiptr size
Definition: glext.h:5919
#define CALG_DH_SF
Definition: wincrypt.h:1819
#define GetProcessHeap()
Definition: compat.h:403
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
SECURITY_STATUS WINAPI AcquireCredentialsHandleA(SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse, PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
Definition: wrapper.c:59
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
Definition: tcpip.h:125
#define MAX_PATH
Definition: compat.h:26
SECURITY_STATUS WINAPI InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
Definition: wrapper.c:237
unsigned long DWORD
Definition: ntddk_ex.h:95
PCRYPT_KEY_PROV_PARAM rgProvParam
Definition: wincrypt.h:214
#define CALG_SHA_256
Definition: wincrypt.h:1813
#define SetLastError(x)
Definition: compat.h:417
#define CALG_CYLINK_MEK
Definition: wincrypt.h:1842
static const BYTE selfSignedCert[]
Definition: schannel.c:72
#define CALG_SSL3_MASTER
Definition: wincrypt.h:1843
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static const WCHAR MS_DEF_PROV_W[]
Definition: wincrypt.h:1868
#define CALG_AGREEDKEY_ANY
Definition: wincrypt.h:1821
ULONG dwApplicationDataOffset
Definition: sspi.h:229
#define SECPKG_ATTR_STREAM_SIZES
Definition: sspi.h:512
#define SECBUFFER_STREAM_TRAILER
Definition: sspi.h:152
static const struct @527 sizes[]
struct _HMAPPER ** aphMappers
Definition: schannel.h:93
int ret
GLenum const GLvoid * addr
Definition: glext.h:9621
#define ISC_REQ_ALLOCATE_MEMORY
Definition: sspi.h:357
#define todo_wine
Definition: test.h:163
PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded)
Definition: cert.c:316
HKEY key
Definition: reg.c:42
SECURITY_STATUS WINAPI QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
Definition: wrapper.c:505
#define SECBUFFER_TOKEN
Definition: sspi.h:148
#define SEC_E_INVALID_TOKEN
Definition: winerror.h:2917
#define ISC_RET_STREAM
Definition: sspi.h:387
#define SECPKG_ATTR_CONNECTION_INFO
Definition: schannel.h:76
#define SECPKG_ATTR_CIPHER_STRENGTHS
Definition: schannel.h:73
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
unsigned char BYTE
Definition: mem.h:68
#define CALG_MD5
Definition: wincrypt.h:1805
#define ISC_RET_SEQUENCE_DETECT
Definition: sspi.h:375
#define SEC_E_OK
Definition: winerror.h:2356
DWORD dwFlags
Definition: schannel.h:100
#define CALG_PCT1_MASTER
Definition: wincrypt.h:1847
#define CALG_HMAC
Definition: wincrypt.h:1810
#define broken(x)
Definition: _sntprintf.h:21
PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrev)
Definition: store.c:928
#define CALG_AES_128
Definition: wincrypt.h:1833
#define ISC_RET_REPLAY_DETECT
Definition: sspi.h:374
#define CALG_RC5
Definition: wincrypt.h:1839
ULONG cbAcceptorLength
Definition: sspi.h:226
SEC_CHANNEL_BINDINGS * Bindings
Definition: sspi.h:750
#define CALG_MD4
Definition: wincrypt.h:1804
#define CALG_SCHANNEL_MAC_KEY
Definition: wincrypt.h:1845
#define CALG_SHA_512
Definition: wincrypt.h:1815
#define lstrcpyW
Definition: compat.h:414
#define SECPKG_CRED_BOTH
Definition: sspi.h:279
#define SECBUFFER_VERSION
Definition: sspi.h:174
#define CALG_MAC
Definition: wincrypt.h:1808
ULONG_PTR HCRYPTPROV
Definition: wincrypt.h:46
#define CERT_KEY_PROV_INFO_PROP_ID
Definition: wincrypt.h:2686
struct protocol * protocols
Definition: dispatch.c:52
#define SP_PROT_TLS1_3_CLIENT
Definition: schannel.h:35
ULONG dwAcceptorAddrType
Definition: sspi.h:225
#define ok(value,...)
Definition: atltest.h:57
static void init_cred(SCHANNEL_CRED *cred)
Definition: schannel.c:157
#define CALG_SHA1
Definition: wincrypt.h:1807
#define SECPKG_ATTR_SUPPORTED_ALGS
Definition: schannel.h:72
CHAR SEC_CHAR
Definition: sspi.h:30
DWORD exp
Definition: msg.c:16038
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
SECURITY_STATUS WINAPI DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
Definition: wrapper.c:1036
ULONG_PTR HCRYPTKEY
Definition: wincrypt.h:49
SEC_CHAR * sSignatureAlgorithmName
Definition: sspi.h:590
#define CALG_DESX
Definition: wincrypt.h:1832
#define SCH_CRED_MANUAL_CRED_VALIDATION
Definition: schannel.h:56
DWORD dwMaximumCipherStrength
Definition: schannel.h:98
Definition: tcpcore.h:1455
#define skip(...)
Definition: atltest.h:64
BOOL WINAPI CryptReleaseContext(HCRYPTPROV hProv, ULONG_PTR dwFlags)
Definition: crypt.c:651
DWORD cCreds
Definition: schannel.h:89
#define CRYPT_DELETEKEYSET
Definition: wincrypt.h:2071
static CHAR unisp_name_a[]
Definition: schannel.c:97
#define CALG_AES
Definition: wincrypt.h:1836
#define AT_SIGNATURE
Definition: wincrypt.h:2036
unsigned int ULONG
Definition: retypes.h:1
static BYTE privKey[]
Definition: schannel.c:46
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static int receive_data(SOCKET sock, SecBuffer *buf)
Definition: schannel.c:604
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
#define ISC_REQ_CONFIDENTIALITY
Definition: sspi.h:353
#define GetProcAddress(x, y)
Definition: compat.h:418
DWORD dwMinimumCipherStrength
Definition: schannel.h:97
#define SEC_E_NO_CREDENTIALS
Definition: winerror.h:2923
BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash)
Definition: cert.c:2187
#define SEC_E_UNKNOWN_CREDENTIALS
Definition: winerror.h:2922
SECURITY_STATUS(SEC_ENTRY * QUERY_CONTEXT_ATTRIBUTES_FN_A)(PCtxtHandle, ULONG, void *)
Definition: sspi.h:501
UINT_PTR SOCKET
Definition: winsock.h:47
static void test_cread_attrs(void)
Definition: schannel.c:230
#define CALG_KEA_KEYX
Definition: wincrypt.h:1822
#define SOCK_STREAM
Definition: tcpip.h:118
GLfloat GLfloat p
Definition: glext.h:8902
static void test_InitializeSecurityContext(void)
Definition: schannel.c:643
#define htons(x)
Definition: module.h:213
Definition: _hash_fun.h:40
#define memset(x, y, z)
Definition: compat.h:39
static SERVICE_STATUS status
Definition: service.c:31
BOOL WINAPI CryptImportKey(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
Definition: crypt.c:1855
#define CALG_ECDH
Definition: wincrypt.h:1825
#define win_skip
Definition: test.h:150
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
BOOL WINAPI CertSetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, DWORD dwFlags, const void *pvData)
Definition: cert.c:799
#define HeapFree(x, y, z)
Definition: compat.h:402
#define SEC_E_INCOMPLETE_MESSAGE
Definition: winerror.h:2934
SECURITY_STATUS WINAPI EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
Definition: wrapper.c:1006
#define PROV_RSA_FULL
Definition: wincrypt.h:2039
BOOL expected
Definition: store.c:2063
static QUERY_CONTEXT_ATTRIBUTES_FN_A pQueryContextAttributesA
Definition: schannel.c:32
#define SUCCEEDED(hr)
Definition: intsafe.h:57
SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:450
Definition: path.c:41
static const char * algid_to_str(ALG_ID alg)
Definition: schannel.c:99
#define CALG_DH_EPHEM
Definition: wincrypt.h:1820
ULONG dwAcceptorOffset
Definition: sspi.h:227
Definition: ps.c:97