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
24 #define SECURITY_WIN32
30 #include "wine/test.h"
32 static HMODULE secdll, crypt32dll;
34 static ACQUIRE_CREDENTIALS_HANDLE_FN_A pAcquireCredentialsHandleA;
35 static ENUMERATE_SECURITY_PACKAGES_FN_A pEnumerateSecurityPackagesA;
36 static FREE_CONTEXT_BUFFER_FN pFreeContextBuffer;
37 static FREE_CREDENTIALS_HANDLE_FN pFreeCredentialsHandle;
38 static QUERY_CREDENTIALS_ATTRIBUTES_FN_A pQueryCredentialsAttributesA;
39 static INITIALIZE_SECURITY_CONTEXT_FN_A pInitializeSecurityContextA;
40 static QUERY_CONTEXT_ATTRIBUTES_FN_A pQueryContextAttributesA;
41 static DELETE_SECURITY_CONTEXT_FN pDeleteSecurityContext;
42 static DECRYPT_MESSAGE_FN pDecryptMessage;
43 static ENCRYPT_MESSAGE_FN pEncryptMessage;
45 static PCCERT_CONTEXT (WINAPI *pCertCreateCertificateContext)(DWORD,const BYTE*,DWORD);
46 static BOOL (WINAPI *pCertFreeCertificateContext)(PCCERT_CONTEXT);
47 static BOOL (WINAPI *pCertSetCertificateContextProperty)(PCCERT_CONTEXT,DWORD,DWORD,const void*);
48 static PCCERT_CONTEXT (WINAPI *pCertEnumCertificatesInStore)(HCERTSTORE,PCCERT_CONTEXT);
50 static BOOL (WINAPI *pCryptAcquireContextW)(HCRYPTPROV*, LPCWSTR, LPCWSTR, DWORD, DWORD);
51 static BOOL (WINAPI *pCryptDestroyKey)(HCRYPTKEY);
52 static BOOL (WINAPI *pCryptImportKey)(HCRYPTPROV,CONST BYTE*,DWORD,HCRYPTKEY,DWORD,HCRYPTKEY*);
53 static BOOL (WINAPI *pCryptReleaseContext)(HCRYPTPROV,ULONG_PTR);
55 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
56 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
57 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
58 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
59 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
60 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
61 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
62 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
63 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
64 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
65 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e',
67 static BYTE privKey[] = {
68 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
69 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
70 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
71 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
72 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
73 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
74 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
75 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
76 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
77 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
78 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
79 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
80 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
81 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
82 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
83 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
84 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
85 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
86 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
87 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
88 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
89 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
90 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
91 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
93 static const BYTE selfSignedCert[] = {
94 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
95 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
96 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
97 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
98 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
99 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
100 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
101 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
102 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
103 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
104 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
105 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
106 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
107 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
108 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
109 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
110 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
111 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
112 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
113 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
114 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
115 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
116 0xa8, 0x76, 0x57, 0x92, 0x36 };
118 static void InitFunctionPtrs(void)
122 crypt32dll = LoadLibraryA("crypt32.dll");
123 secdll = LoadLibraryA("secur32.dll");
125 secdll = LoadLibraryA("security.dll");
126 advapi32dll = GetModuleHandleA("advapi32.dll");
128 #define GET_PROC(h, func) p ## func = (void*)GetProcAddress(h, #func)
132 GET_PROC(secdll, AcquireCredentialsHandleA);
133 GET_PROC(secdll, EnumerateSecurityPackagesA);
134 GET_PROC(secdll, FreeContextBuffer);
135 GET_PROC(secdll, FreeCredentialsHandle);
136 GET_PROC(secdll, QueryCredentialsAttributesA);
137 GET_PROC(secdll, InitializeSecurityContextA);
138 GET_PROC(secdll, QueryContextAttributesA);
139 GET_PROC(secdll, DeleteSecurityContext);
140 GET_PROC(secdll, DecryptMessage);
141 GET_PROC(secdll, EncryptMessage);
144 GET_PROC(advapi32dll, CryptAcquireContextW);
145 GET_PROC(advapi32dll, CryptDestroyKey);
146 GET_PROC(advapi32dll, CryptImportKey);
147 GET_PROC(advapi32dll, CryptReleaseContext);
149 GET_PROC(crypt32dll, CertFreeCertificateContext);
150 GET_PROC(crypt32dll, CertSetCertificateContextProperty);
151 GET_PROC(crypt32dll, CertCreateCertificateContext);
152 GET_PROC(crypt32dll, CertEnumCertificatesInStore);
157 static void test_strength(PCredHandle handle)
159 SecPkgCred_CipherStrengths strength = {-1,-1};
162 st = pQueryCredentialsAttributesA(handle, SECPKG_ATTR_CIPHER_STRENGTHS, &strength);
163 ok(st == SEC_E_OK, "QueryCredentialsAttributesA failed: %u\n", GetLastError());
164 ok(strength.dwMinimumCipherStrength, "dwMinimumCipherStrength not changed\n");
165 ok(strength.dwMaximumCipherStrength, "dwMaximumCipherStrength not changed\n");
166 trace("strength %d - %d\n", strength.dwMinimumCipherStrength, strength.dwMaximumCipherStrength);
169 static void test_supported_protocols(CredHandle *handle, unsigned exprots)
171 SecPkgCred_SupportedProtocols protocols;
172 SECURITY_STATUS status;
174 status = pQueryCredentialsAttributesA(handle, SECPKG_ATTR_SUPPORTED_PROTOCOLS, &protocols);
175 ok(status == SEC_E_OK, "QueryCredentialsAttributes failed: %08x\n", status);
178 ok(protocols.grbitProtocol == exprots, "protocols.grbitProtocol = %x, expected %x\n", protocols.grbitProtocol, exprots);
180 trace("Supported protocols:\n");
182 #define X(flag, name) do { if(protocols.grbitProtocol & flag) { trace(name "\n"); protocols.grbitProtocol &= ~flag; } }while(0)
183 X(SP_PROT_SSL2_CLIENT, "SSL 2 client");
184 X(SP_PROT_SSL3_CLIENT, "SSL 3 client");
185 X(SP_PROT_TLS1_0_CLIENT, "TLS 1.0 client");
186 X(SP_PROT_TLS1_1_CLIENT, "TLS 1.1 client");
187 X(SP_PROT_TLS1_2_CLIENT, "TLS 1.2 client");
190 if(protocols.grbitProtocol)
191 trace("Unknown flags: %x\n", protocols.grbitProtocol);
194 static void testAcquireSecurityContext(void)
196 BOOL has_schannel = FALSE;
197 SecPkgInfoA *package_info;
202 SCHANNEL_CRED schanCred;
203 PCCERT_CONTEXT certs[2];
205 static CHAR unisp_name_a[] = UNISP_NAME_A;
206 WCHAR ms_def_prov_w[MAX_PATH];
209 CRYPT_KEY_PROV_INFO keyProvInfo;
211 if (!pAcquireCredentialsHandleA || !pCertCreateCertificateContext ||
212 !pEnumerateSecurityPackagesA || !pFreeContextBuffer ||
213 !pFreeCredentialsHandle || !pCryptAcquireContextW)
215 win_skip("Needed functions are not available\n");
219 if (SUCCEEDED(pEnumerateSecurityPackagesA(&i, &package_info)))
223 if (!strcmp(package_info[i].Name, unisp_name_a))
229 pFreeContextBuffer(package_info);
233 skip("Schannel not available\n");
237 lstrcpyW(ms_def_prov_w, MS_DEF_PROV_W);
239 keyProvInfo.pwszContainerName = cspNameW;
240 keyProvInfo.pwszProvName = ms_def_prov_w;
241 keyProvInfo.dwProvType = PROV_RSA_FULL;
242 keyProvInfo.dwFlags = 0;
243 keyProvInfo.cProvParam = 0;
244 keyProvInfo.rgProvParam = NULL;
245 keyProvInfo.dwKeySpec = AT_SIGNATURE;
247 certs[0] = pCertCreateCertificateContext(X509_ASN_ENCODING, bigCert,
249 certs[1] = pCertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert,
250 sizeof(selfSignedCert));
252 SetLastError(0xdeadbeef);
253 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
255 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
257 /* WinMe would crash on some tests */
258 win_skip("CryptAcquireContextW is not implemented\n");
262 st = pAcquireCredentialsHandleA(NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL,
264 ok(st == SEC_E_SECPKG_NOT_FOUND,
265 "Expected SEC_E_SECPKG_NOT_FOUND, got %08x\n", st);
268 /* Crashes on Win2K */
269 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, 0, NULL, NULL, NULL,
271 ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
273 /* Crashes on WinNT */
274 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_BOTH, NULL,
275 NULL, NULL, NULL, NULL, NULL);
276 ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
278 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
279 NULL, NULL, NULL, NULL, NULL, NULL);
280 ok(st == SEC_E_NO_CREDENTIALS, "Expected SEC_E_NO_CREDENTIALS, got %08x\n", st);
283 pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
284 NULL, NULL, NULL, NULL, NULL, NULL);
286 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
287 NULL, NULL, NULL, NULL, &cred, NULL);
288 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
290 st = pQueryCredentialsAttributesA(&cred, SECPKG_ATTR_SUPPORTED_PROTOCOLS, NULL);
291 ok(st == SEC_E_INTERNAL_ERROR, "QueryCredentialsAttributes failed: %08x, expected SEC_E_INTERNAL_ERROR\n", st);
293 test_supported_protocols(&cred, 0);
294 pFreeCredentialsHandle(&cred);
296 memset(&cred, 0, sizeof(cred));
297 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
298 NULL, NULL, NULL, NULL, &cred, &exp);
299 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
300 /* expriy is indeterminate in win2k3 */
301 trace("expiry: %08x%08x\n", exp.HighPart, exp.LowPart);
302 pFreeCredentialsHandle(&cred);
304 /* Bad version in SCHANNEL_CRED */
305 memset(&schanCred, 0, sizeof(schanCred));
306 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
307 NULL, &schanCred, NULL, NULL, NULL, NULL);
308 ok(st == SEC_E_INTERNAL_ERROR ||
309 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */ ||
310 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
311 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
312 NULL, &schanCred, NULL, NULL, NULL, NULL);
313 ok(st == SEC_E_INTERNAL_ERROR ||
314 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */ ||
315 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
317 /* No cert in SCHANNEL_CRED succeeds for outbound.. */
318 schanCred.dwVersion = SCHANNEL_CRED_VERSION;
319 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
320 NULL, &schanCred, NULL, NULL, &cred, NULL);
321 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
322 pFreeCredentialsHandle(&cred);
323 /* but fails for inbound. */
324 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
325 NULL, &schanCred, NULL, NULL, &cred, NULL);
326 ok(st == SEC_E_NO_CREDENTIALS ||
327 st == SEC_E_OK /* Vista/win2k8 */,
328 "Expected SEC_E_NO_CREDENTIALS or SEC_E_OK, got %08x\n", st);
332 /* Crashes with bad paCred pointer */
333 schanCred.cCreds = 1;
334 pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
335 NULL, &schanCred, NULL, NULL, NULL, NULL);
338 /* Bogus cert in SCHANNEL_CRED. Windows fails with
339 * SEC_E_UNKNOWN_CREDENTIALS, but I'll accept SEC_E_NO_CREDENTIALS too.
341 schanCred.cCreds = 1;
342 schanCred.paCred = &certs[0];
343 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
344 NULL, &schanCred, NULL, NULL, NULL, NULL);
345 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
346 st == SEC_E_NO_CREDENTIALS ||
347 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
348 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
349 NULL, &schanCred, NULL, NULL, NULL, NULL);
350 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
351 st == SEC_E_NO_CREDENTIALS ||
352 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
354 /* Good cert, but missing private key. Windows fails with
355 * SEC_E_NO_CREDENTIALS, but I'll accept SEC_E_UNKNOWN_CREDENTIALS too.
357 schanCred.cCreds = 1;
358 schanCred.paCred = &certs[1];
359 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
360 NULL, &schanCred, NULL, NULL, &cred, NULL);
361 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS ||
362 st == SEC_E_INTERNAL_ERROR, /* win2k */
363 "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
364 "or SEC_E_INTERNAL_ERROR, got %08x\n", st);
365 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
366 NULL, &schanCred, NULL, NULL, NULL, NULL);
367 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_NO_CREDENTIALS ||
368 st == SEC_E_INTERNAL_ERROR, /* win2k */
369 "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
370 "or SEC_E_INTERNAL_ERROR, got %08x\n", st);
372 /* Good cert, with CRYPT_KEY_PROV_INFO set before it's had a key loaded. */
373 if (pCertSetCertificateContextProperty)
375 ret = pCertSetCertificateContextProperty(certs[1],
376 CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo);
377 schanCred.dwVersion = SCH_CRED_V3;
378 ok(ret, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
379 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
380 NULL, &schanCred, NULL, NULL, &cred, NULL);
381 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INTERNAL_ERROR /* WinNT */,
382 "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st);
383 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
384 NULL, &schanCred, NULL, NULL, &cred, NULL);
385 ok(st == SEC_E_UNKNOWN_CREDENTIALS || st == SEC_E_INTERNAL_ERROR /* WinNT */,
386 "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st);
389 ret = pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
391 ok(ret, "CryptAcquireContextW failed: %08x\n", GetLastError());
395 ret = pCryptImportKey(csp, privKey, sizeof(privKey), 0, 0, &key);
396 ok(ret, "CryptImportKey failed: %08x\n", GetLastError());
405 pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
406 NULL, &schanCred, NULL, NULL, NULL, NULL);
408 /* Crashes on WinNT */
409 /* Good cert with private key, bogus version */
410 schanCred.dwVersion = SCH_CRED_V1;
411 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
412 NULL, &schanCred, NULL, NULL, &cred, NULL);
413 ok(st == SEC_E_INTERNAL_ERROR ||
414 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
415 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
416 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
417 NULL, &schanCred, NULL, NULL, &cred, NULL);
418 ok(st == SEC_E_INTERNAL_ERROR ||
419 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
420 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
421 schanCred.dwVersion = SCH_CRED_V2;
422 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
423 NULL, &schanCred, NULL, NULL, &cred, NULL);
424 ok(st == SEC_E_INTERNAL_ERROR ||
425 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
426 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
427 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
428 NULL, &schanCred, NULL, NULL, &cred, NULL);
429 ok(st == SEC_E_INTERNAL_ERROR ||
430 st == SEC_E_UNKNOWN_CREDENTIALS /* Vista/win2k8 */,
431 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
434 /* Succeeds on V3 or higher */
435 schanCred.dwVersion = SCH_CRED_V3;
436 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
437 NULL, &schanCred, NULL, NULL, &cred, NULL);
438 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
439 pFreeCredentialsHandle(&cred);
440 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
441 NULL, &schanCred, NULL, NULL, &cred, NULL);
443 st == SEC_E_UNKNOWN_CREDENTIALS, /* win2k3 */
444 "AcquireCredentialsHandleA failed: %08x\n", st);
445 pFreeCredentialsHandle(&cred);
446 schanCred.dwVersion = SCHANNEL_CRED_VERSION;
447 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
448 NULL, &schanCred, NULL, NULL, &cred, NULL);
449 ok(st == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", st);
450 pFreeCredentialsHandle(&cred);
451 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
452 NULL, &schanCred, NULL, NULL, &cred, NULL);
454 st == SEC_E_UNKNOWN_CREDENTIALS, /* win2k3 */
455 "AcquireCredentialsHandleA failed: %08x\n", st);
456 if (st == SEC_E_OK) test_strength(&cred);
457 pFreeCredentialsHandle(&cred);
459 /* How about more than one cert? */
460 schanCred.cCreds = 2;
461 schanCred.paCred = certs;
462 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
463 NULL, &schanCred, NULL, NULL, &cred, NULL);
464 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
465 st == SEC_E_NO_CREDENTIALS /* Vista/win2k8 */ ||
466 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
467 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
468 NULL, &schanCred, NULL, NULL, &cred, NULL);
469 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
470 st == SEC_E_NO_CREDENTIALS ||
471 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
475 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
476 NULL, &schanCred, NULL, NULL, &cred, NULL);
477 ok(st == SEC_E_UNKNOWN_CREDENTIALS ||
478 st == SEC_E_NO_CREDENTIALS ||
479 st == SEC_E_INVALID_TOKEN /* WinNT */, "st = %08x\n", st);
480 st = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_INBOUND,
481 NULL, &schanCred, NULL, NULL, &cred, NULL);
482 ok(st == SEC_E_UNKNOWN_CREDENTIALS,
483 "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st);
484 /* FIXME: what about two valid certs? */
486 if (pCryptDestroyKey)
487 pCryptDestroyKey(key);
490 if (pCryptReleaseContext)
491 pCryptReleaseContext(csp, 0);
492 pCryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL,
495 if (pCertFreeCertificateContext)
497 pCertFreeCertificateContext(certs[0]);
498 pCertFreeCertificateContext(certs[1]);
502 static void test_remote_cert(PCCERT_CONTEXT remote_cert)
504 PCCERT_CONTEXT iter = NULL;
505 BOOL incl_remote = FALSE;
506 unsigned cert_cnt = 0;
508 ok(remote_cert->hCertStore != NULL, "hCertStore == NULL\n");
510 while((iter = pCertEnumCertificatesInStore(remote_cert->hCertStore, iter))) {
511 if(iter == remote_cert)
516 ok(cert_cnt == 2, "cert_cnt = %u\n", cert_cnt);
517 ok(incl_remote, "context does not contain cert itself\n");
520 static const char http_request[] = "HEAD /test.html HTTP/1.1\r\nHost: www.codeweavers.com\r\nConnection: close\r\n\r\n";
522 static void init_cred(SCHANNEL_CRED *cred)
524 cred->dwVersion = SCHANNEL_CRED_VERSION;
527 cred->hRootStore = NULL;
529 cred->aphMappers = NULL;
530 cred->cSupportedAlgs = 0;
531 cred->palgSupportedAlgs = NULL;
532 cred->grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
533 cred->dwMinimumCipherStrength = 0;
534 cred->dwMaximumCipherStrength = 0;
535 cred->dwSessionLifespan = 0;
539 static void init_buffers(SecBufferDesc *desc, unsigned count, unsigned size)
541 desc->ulVersion = SECBUFFER_VERSION;
542 desc->cBuffers = count;
543 desc->pBuffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count*sizeof(SecBuffer));
545 desc->pBuffers[0].cbBuffer = size;
546 desc->pBuffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, size);
549 static void reset_buffers(SecBufferDesc *desc)
553 for (i = 0; i < desc->cBuffers; ++i)
555 desc->pBuffers[i].BufferType = SECBUFFER_EMPTY;
558 desc->pBuffers[i].cbBuffer = 0;
559 desc->pBuffers[i].pvBuffer = NULL;
564 static void free_buffers(SecBufferDesc *desc)
566 HeapFree(GetProcessHeap(), 0, desc->pBuffers[0].pvBuffer);
567 HeapFree(GetProcessHeap(), 0, desc->pBuffers);
570 static int receive_data(SOCKET sock, SecBuffer *buf)
572 unsigned received = 0;
576 unsigned char *data = buf->pvBuffer;
577 unsigned expected = 0;
580 ret = recv(sock, (char *)data+received, buf->cbBuffer-received, 0);
583 skip("recv failed\n");
588 skip("connection closed\n");
593 while (expected < received)
595 unsigned frame_size = 5 + ((data[3]<<8) | data[4]);
596 expected += frame_size;
600 if (expected == received)
604 buf->cbBuffer = received;
609 static void test_communication(void)
615 struct hostent *host;
616 struct sockaddr_in addr;
618 SECURITY_STATUS status;
622 CredHandle cred_handle;
624 SecPkgContext_StreamSizes sizes;
625 SecPkgContext_ConnectionInfo conn_info;
628 SecBufferDesc buffers[2];
630 unsigned buf_size = 4000;
634 if (!pAcquireCredentialsHandleA || !pFreeCredentialsHandle ||
635 !pInitializeSecurityContextA || !pDeleteSecurityContext ||
636 !pQueryContextAttributesA || !pDecryptMessage || !pEncryptMessage)
638 skip("Required secur32 functions not available\n");
642 /* Create a socket and connect to www.codeweavers.com */
643 ret = WSAStartup(0x0202, &wsa_data);
646 skip("Can't init winsock 2.2\n");
650 host = gethostbyname("www.codeweavers.com");
653 skip("Can't resolve www.codeweavers.com\n");
657 addr.sin_family = host->h_addrtype;
658 addr.sin_addr = *(struct in_addr *)host->h_addr_list[0];
659 addr.sin_port = htons(443);
660 sock = socket(host->h_addrtype, SOCK_STREAM, 0);
661 if (sock == SOCKET_ERROR)
663 skip("Can't create socket\n");
667 ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
668 if (ret == SOCKET_ERROR)
670 skip("Can't connect to www.codeweavers.com\n");
674 /* Create client credentials */
676 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS|SCH_CRED_MANUAL_CRED_VALIDATION;
678 status = pAcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL,
679 &cred, NULL, NULL, &cred_handle, NULL);
680 ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", status);
681 if (status != SEC_E_OK) return;
683 test_supported_protocols(&cred_handle, SP_PROT_SSL3_CLIENT);
685 /* Initialize the connection */
686 init_buffers(&buffers[0], 4, buf_size);
687 init_buffers(&buffers[1], 4, buf_size);
689 buffers[0].pBuffers[0].BufferType = SECBUFFER_TOKEN;
690 status = pInitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
691 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
692 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL);
693 ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status);
695 buffers[1].cBuffers = 1;
696 buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN;
697 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
698 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
699 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
700 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
702 buffers[0].pBuffers[0].cbBuffer = buf_size;
704 status = pInitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost",
705 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
706 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL);
707 ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status);
709 buf = &buffers[0].pBuffers[0];
710 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
711 buf->cbBuffer = buf_size;
713 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
714 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
715 0, 0, NULL, 0, NULL, &buffers[0], &attrs, NULL);
716 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status);
717 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
718 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
720 buffers[1].cBuffers = 4;
721 buffers[1].pBuffers[0].cbBuffer = 0;
723 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
724 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
725 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
726 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status);
727 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
728 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
730 buf = &buffers[1].pBuffers[0];
731 buf->cbBuffer = buf_size;
732 ret = receive_data(sock, buf);
736 buffers[1].pBuffers[0].cbBuffer = 4;
737 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
738 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
739 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
740 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status);
741 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
742 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
744 buffers[1].pBuffers[0].cbBuffer = 5;
745 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
746 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
747 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
748 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status);
749 ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n");
750 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n");
752 buffers[1].pBuffers[0].cbBuffer = ret;
753 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
754 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
755 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
756 buffers[1].pBuffers[0].cbBuffer = buf_size;
757 while (status == SEC_I_CONTINUE_NEEDED)
759 buf = &buffers[0].pBuffers[0];
760 send(sock, buf->pvBuffer, buf->cbBuffer, 0);
761 buf->cbBuffer = buf_size;
763 buf = &buffers[1].pBuffers[0];
764 ret = receive_data(sock, buf);
768 buf->BufferType = SECBUFFER_TOKEN;
770 status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost",
771 ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM,
772 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL);
773 buffers[1].pBuffers[0].cbBuffer = buf_size;
776 ok(status == SEC_E_OK || broken(status == SEC_E_INVALID_TOKEN) /* WinNT */,
777 "InitializeSecurityContext failed: %08x\n", status);
778 if(status != SEC_E_OK) {
779 win_skip("Handshake failed\n");
783 status = pQueryContextAttributesA(&context, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (void*)&cert);
784 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_REMOTE_CERT_CONTEXT) failed: %08x\n", status);
785 if(status == SEC_E_OK) {
786 test_remote_cert(cert);
787 pCertFreeCertificateContext(cert);
790 status = pQueryContextAttributesA(&context, SECPKG_ATTR_CONNECTION_INFO, (void*)&conn_info);
791 ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_CONNECTION_INFO) failed: %08x\n", status);
792 if(status == SEC_E_OK) {
793 ok(conn_info.dwCipherStrength == 128, "conn_info.dwCipherStrength = %d\n", conn_info.dwCipherStrength);
794 ok(conn_info.dwHashStrength >= 128, "conn_info.dwHashStrength = %d\n", conn_info.dwHashStrength);
797 pQueryContextAttributesA(&context, SECPKG_ATTR_STREAM_SIZES, &sizes);
799 reset_buffers(&buffers[0]);
801 /* Send a simple request so we get data for testing DecryptMessage */
802 buf = &buffers[0].pBuffers[0];
803 data = buf->pvBuffer;
804 buf->BufferType = SECBUFFER_STREAM_HEADER;
805 buf->cbBuffer = sizes.cbHeader;
807 buf->BufferType = SECBUFFER_DATA;
808 buf->pvBuffer = data + sizes.cbHeader;
809 buf->cbBuffer = sizeof(http_request) - 1;
810 memcpy(buf->pvBuffer, http_request, sizeof(http_request) - 1);
812 buf->BufferType = SECBUFFER_STREAM_TRAILER;
813 buf->pvBuffer = data + sizes.cbHeader + sizeof(http_request) -1;
814 buf->cbBuffer = sizes.cbTrailer;
816 status = pEncryptMessage(&context, 0, &buffers[0], 0);
817 ok(status == SEC_E_OK, "EncryptMessage failed: %08x\n", status);
818 if (status != SEC_E_OK)
821 buf = &buffers[0].pBuffers[0];
822 send(sock, buf->pvBuffer, buffers[0].pBuffers[0].cbBuffer + buffers[0].pBuffers[1].cbBuffer + buffers[0].pBuffers[2].cbBuffer, 0);
824 reset_buffers(&buffers[0]);
825 buf->cbBuffer = buf_size;
826 data_size = receive_data(sock, buf);
828 /* Too few buffers */
829 --buffers[0].cBuffers;
830 status = pDecryptMessage(&context, &buffers[0], 0, NULL);
831 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
834 ++buffers[0].cBuffers;
835 status = pDecryptMessage(&context, &buffers[0], 0, NULL);
836 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
838 /* Two data buffers */
839 buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA;
840 buffers[0].pBuffers[1].BufferType = SECBUFFER_DATA;
841 status = pDecryptMessage(&context, &buffers[0], 0, NULL);
842 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
844 /* Too few empty buffers */
845 buffers[0].pBuffers[1].BufferType = SECBUFFER_EXTRA;
846 status = pDecryptMessage(&context, &buffers[0], 0, NULL);
847 ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status);
849 /* Incomplete data */
850 buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY;
851 buffers[0].pBuffers[0].cbBuffer = (data[3]<<8) | data[4];
852 status = pDecryptMessage(&context, &buffers[0], 0, NULL);
853 ok(status == SEC_E_INCOMPLETE_MESSAGE, "Expected SEC_E_INCOMPLETE_MESSAGE, got %08x\n", status);
854 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_MISSING, "Expected first buffer to be SECBUFFER_MISSING\n");
855 ok(buffers[0].pBuffers[0].cbBuffer == 5, "Expected first buffer to be a five bytes\n");
857 buffers[0].pBuffers[0].cbBuffer = data_size;
858 buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA;
859 buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY;
860 status = pDecryptMessage(&context, &buffers[0], 0, NULL);
861 ok(status == SEC_E_OK, "DecryptMessage failed: %08x\n", status);
862 if (status == SEC_E_OK)
864 ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_STREAM_HEADER, "Expected first buffer to be SECBUFFER_STREAM_HEADER\n");
865 ok(buffers[0].pBuffers[1].BufferType == SECBUFFER_DATA, "Expected second buffer to be SECBUFFER_DATA\n");
866 ok(buffers[0].pBuffers[2].BufferType == SECBUFFER_STREAM_TRAILER, "Expected third buffer to be SECBUFFER_STREAM_TRAILER\n");
868 data = buffers[0].pBuffers[1].pvBuffer;
869 data[buffers[0].pBuffers[1].cbBuffer] = 0;
872 pDeleteSecurityContext(&context);
873 pFreeCredentialsHandle(&cred_handle);
875 free_buffers(&buffers[0]);
876 free_buffers(&buffers[1]);
885 testAcquireSecurityContext();
886 test_communication();
891 FreeLibrary(crypt32dll);