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
25 #define SECURITY_WIN32
29 #include "wine/test.h"
31 static HMODULE secdll
, crypt32dll
;
33 static ACQUIRE_CREDENTIALS_HANDLE_FN_A pAcquireCredentialsHandleA
;
34 static ENUMERATE_SECURITY_PACKAGES_FN_A pEnumerateSecurityPackagesA
;
35 static FREE_CONTEXT_BUFFER_FN pFreeContextBuffer
;
36 static FREE_CREDENTIALS_HANDLE_FN pFreeCredentialsHandle
;
37 static QUERY_CREDENTIALS_ATTRIBUTES_FN_A pQueryCredentialsAttributesA
;
38 static INITIALIZE_SECURITY_CONTEXT_FN_A pInitializeSecurityContextA
;
39 static QUERY_CONTEXT_ATTRIBUTES_FN_A pQueryContextAttributesA
;
40 static DELETE_SECURITY_CONTEXT_FN pDeleteSecurityContext
;
41 static DECRYPT_MESSAGE_FN pDecryptMessage
;
42 static ENCRYPT_MESSAGE_FN pEncryptMessage
;
44 static PCCERT_CONTEXT (WINAPI
*pCertCreateCertificateContext
)(DWORD
,const BYTE
*,DWORD
);
45 static BOOL (WINAPI
*pCertFreeCertificateContext
)(PCCERT_CONTEXT
);
46 static BOOL (WINAPI
*pCertSetCertificateContextProperty
)(PCCERT_CONTEXT
,DWORD
,DWORD
,const void*);
47 static PCCERT_CONTEXT (WINAPI
*pCertEnumCertificatesInStore
)(HCERTSTORE
,PCCERT_CONTEXT
);
49 static BOOL (WINAPI
*pCryptAcquireContextW
)(HCRYPTPROV
*, LPCWSTR
, LPCWSTR
, DWORD
, DWORD
);
50 static BOOL (WINAPI
*pCryptDestroyKey
)(HCRYPTKEY
);
51 static BOOL (WINAPI
*pCryptImportKey
)(HCRYPTPROV
,const BYTE
*,DWORD
,HCRYPTKEY
,DWORD
,HCRYPTKEY
*);
52 static BOOL (WINAPI
*pCryptReleaseContext
)(HCRYPTPROV
,ULONG_PTR
);
54 static const BYTE bigCert
[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
55 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
56 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
57 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
58 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
59 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
60 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
61 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
62 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
63 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
64 static WCHAR cspNameW
[] = { 'W','i','n','e','C','r','y','p','t','T','e',
66 static BYTE privKey
[] = {
67 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32, 0x00,
68 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x79, 0x10, 0x1c, 0xd0, 0x6b, 0x10,
69 0x18, 0x30, 0x94, 0x61, 0xdc, 0x0e, 0xcb, 0x96, 0x4e, 0x21, 0x3f, 0x79, 0xcd,
70 0xa9, 0x17, 0x62, 0xbc, 0xbb, 0x61, 0x4c, 0xe0, 0x75, 0x38, 0x6c, 0xf3, 0xde,
71 0x60, 0x86, 0x03, 0x97, 0x65, 0xeb, 0x1e, 0x6b, 0xdb, 0x53, 0x85, 0xad, 0x68,
72 0x21, 0xf1, 0x5d, 0xe7, 0x1f, 0xe6, 0x53, 0xb4, 0xbb, 0x59, 0x3e, 0x14, 0x27,
73 0xb1, 0x83, 0xa7, 0x3a, 0x54, 0xe2, 0x8f, 0x65, 0x8e, 0x6a, 0x4a, 0xcf, 0x3b,
74 0x1f, 0x65, 0xff, 0xfe, 0xf1, 0x31, 0x3a, 0x37, 0x7a, 0x8b, 0xcb, 0xc6, 0xd4,
75 0x98, 0x50, 0x36, 0x67, 0xe4, 0xa1, 0xe8, 0x7e, 0x8a, 0xc5, 0x23, 0xf2, 0x77,
76 0xf5, 0x37, 0x61, 0x49, 0x72, 0x59, 0xe8, 0x3d, 0xf7, 0x60, 0xb2, 0x77, 0xca,
77 0x78, 0x54, 0x6d, 0x65, 0x9e, 0x03, 0x97, 0x1b, 0x61, 0xbd, 0x0c, 0xd8, 0x06,
78 0x63, 0xe2, 0xc5, 0x48, 0xef, 0xb3, 0xe2, 0x6e, 0x98, 0x7d, 0xbd, 0x4e, 0x72,
79 0x91, 0xdb, 0x31, 0x57, 0xe3, 0x65, 0x3a, 0x49, 0xca, 0xec, 0xd2, 0x02, 0x4e,
80 0x22, 0x7e, 0x72, 0x8e, 0xf9, 0x79, 0x84, 0x82, 0xdf, 0x7b, 0x92, 0x2d, 0xaf,
81 0xc9, 0xe4, 0x33, 0xef, 0x89, 0x5c, 0x66, 0x99, 0xd8, 0x80, 0x81, 0x47, 0x2b,
82 0xb1, 0x66, 0x02, 0x84, 0x59, 0x7b, 0xc3, 0xbe, 0x98, 0x45, 0x4a, 0x3d, 0xdd,
83 0xea, 0x2b, 0xdf, 0x4e, 0xb4, 0x24, 0x6b, 0xec, 0xe7, 0xd9, 0x0c, 0x45, 0xb8,
84 0xbe, 0xca, 0x69, 0x37, 0x92, 0x4c, 0x38, 0x6b, 0x96, 0x6d, 0xcd, 0x86, 0x67,
85 0x5c, 0xea, 0x54, 0x94, 0xa4, 0xca, 0xa4, 0x02, 0xa5, 0x21, 0x4d, 0xae, 0x40,
86 0x8f, 0x9d, 0x51, 0x83, 0xf2, 0x3f, 0x33, 0xc1, 0x72, 0xb4, 0x1d, 0x94, 0x6e,
87 0x7d, 0xe4, 0x27, 0x3f, 0xea, 0xff, 0xe5, 0x9b, 0xa7, 0x5e, 0x55, 0x8e, 0x0d,
88 0x69, 0x1c, 0x7a, 0xff, 0x81, 0x9d, 0x53, 0x52, 0x97, 0x9a, 0x76, 0x79, 0xda,
89 0x93, 0x32, 0x16, 0xec, 0x69, 0x51, 0x1a, 0x4e, 0xc3, 0xf1, 0x72, 0x80, 0x78,
90 0x5e, 0x66, 0x4a, 0x8d, 0x85, 0x2f, 0x3f, 0xb2, 0xa7 };
92 static const BYTE selfSignedCert
[] = {
93 0x30, 0x82, 0x01, 0x1f, 0x30, 0x81, 0xce, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
94 0x10, 0xeb, 0x0d, 0x57, 0x2a, 0x9c, 0x09, 0xba, 0xa4, 0x4a, 0xb7, 0x25, 0x49,
95 0xd9, 0x3e, 0xb5, 0x73, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d,
96 0x05, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
97 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30,
98 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x36, 0x32, 0x39, 0x30, 0x35, 0x30, 0x30,
99 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x32, 0x39, 0x31, 0x31,
100 0x30, 0x30, 0x34, 0x36, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
101 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e,
102 0x67, 0x00, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
103 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
104 0x00, 0xe2, 0x54, 0x3a, 0xa7, 0x83, 0xb1, 0x27, 0x14, 0x3e, 0x59, 0xbb, 0xb4,
105 0x53, 0xe6, 0x1f, 0xe7, 0x5d, 0xf1, 0x21, 0x68, 0xad, 0x85, 0x53, 0xdb, 0x6b,
106 0x1e, 0xeb, 0x65, 0x97, 0x03, 0x86, 0x60, 0xde, 0xf3, 0x6c, 0x38, 0x75, 0xe0,
107 0x4c, 0x61, 0xbb, 0xbc, 0x62, 0x17, 0xa9, 0xcd, 0x79, 0x3f, 0x21, 0x4e, 0x96,
108 0xcb, 0x0e, 0xdc, 0x61, 0x94, 0x30, 0x18, 0x10, 0x6b, 0xd0, 0x1c, 0x10, 0x79,
109 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
110 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x25, 0x90, 0x53, 0x34, 0xd9, 0x56, 0x41,
111 0x5e, 0xdb, 0x7e, 0x01, 0x36, 0xec, 0x27, 0x61, 0x5e, 0xb7, 0x4d, 0x90, 0x66,
112 0xa2, 0xe1, 0x9d, 0x58, 0x76, 0xd4, 0x9c, 0xba, 0x2c, 0x84, 0xc6, 0x83, 0x7a,
113 0x22, 0x0d, 0x03, 0x69, 0x32, 0x1a, 0x6d, 0xcb, 0x0c, 0x15, 0xb3, 0x6b, 0xc7,
114 0x0a, 0x8c, 0xb4, 0x5c, 0x34, 0x78, 0xe0, 0x3c, 0x9c, 0xe9, 0xf3, 0x30, 0x9f,
115 0xa8, 0x76, 0x57, 0x92, 0x36 };
117 static void InitFunctionPtrs(void)
121 crypt32dll
= LoadLibraryA("crypt32.dll");
122 secdll
= LoadLibraryA("secur32.dll");
124 secdll
= LoadLibraryA("security.dll");
125 advapi32dll
= LoadLibraryA("advapi32.dll");
127 #define GET_PROC(h, func) p ## func = (void*)GetProcAddress(h, #func)
131 GET_PROC(secdll
, AcquireCredentialsHandleA
);
132 GET_PROC(secdll
, EnumerateSecurityPackagesA
);
133 GET_PROC(secdll
, FreeContextBuffer
);
134 GET_PROC(secdll
, FreeCredentialsHandle
);
135 GET_PROC(secdll
, QueryCredentialsAttributesA
);
136 GET_PROC(secdll
, InitializeSecurityContextA
);
137 GET_PROC(secdll
, QueryContextAttributesA
);
138 GET_PROC(secdll
, DeleteSecurityContext
);
139 GET_PROC(secdll
, DecryptMessage
);
140 GET_PROC(secdll
, EncryptMessage
);
143 GET_PROC(advapi32dll
, CryptAcquireContextW
);
144 GET_PROC(advapi32dll
, CryptDestroyKey
);
145 GET_PROC(advapi32dll
, CryptImportKey
);
146 GET_PROC(advapi32dll
, CryptReleaseContext
);
148 GET_PROC(crypt32dll
, CertFreeCertificateContext
);
149 GET_PROC(crypt32dll
, CertSetCertificateContextProperty
);
150 GET_PROC(crypt32dll
, CertCreateCertificateContext
);
151 GET_PROC(crypt32dll
, CertEnumCertificatesInStore
);
156 static void test_strength(PCredHandle handle
)
158 SecPkgCred_CipherStrengths strength
= {-1,-1};
161 st
= pQueryCredentialsAttributesA(handle
, SECPKG_ATTR_CIPHER_STRENGTHS
, &strength
);
162 ok(st
== SEC_E_OK
, "QueryCredentialsAttributesA failed: %u\n", GetLastError());
163 ok(strength
.dwMinimumCipherStrength
, "dwMinimumCipherStrength not changed\n");
164 ok(strength
.dwMaximumCipherStrength
, "dwMaximumCipherStrength not changed\n");
165 trace("strength %d - %d\n", strength
.dwMinimumCipherStrength
, strength
.dwMaximumCipherStrength
);
168 static void test_supported_protocols(CredHandle
*handle
, unsigned exprots
)
170 SecPkgCred_SupportedProtocols protocols
;
171 SECURITY_STATUS status
;
173 status
= pQueryCredentialsAttributesA(handle
, SECPKG_ATTR_SUPPORTED_PROTOCOLS
, &protocols
);
174 ok(status
== SEC_E_OK
, "QueryCredentialsAttributes failed: %08x\n", status
);
177 ok(protocols
.grbitProtocol
== exprots
, "protocols.grbitProtocol = %x, expected %x\n", protocols
.grbitProtocol
, exprots
);
179 trace("Supported protocols:\n");
181 #define X(flag, name) do { if(protocols.grbitProtocol & flag) { trace(name "\n"); protocols.grbitProtocol &= ~flag; } }while(0)
182 X(SP_PROT_SSL2_CLIENT
, "SSL 2 client");
183 X(SP_PROT_SSL3_CLIENT
, "SSL 3 client");
184 X(SP_PROT_TLS1_0_CLIENT
, "TLS 1.0 client");
185 X(SP_PROT_TLS1_1_CLIENT
, "TLS 1.1 client");
186 X(SP_PROT_TLS1_2_CLIENT
, "TLS 1.2 client");
189 if(protocols
.grbitProtocol
)
190 trace("Unknown flags: %x\n", protocols
.grbitProtocol
);
193 static void testAcquireSecurityContext(void)
195 BOOL has_schannel
= FALSE
;
196 SecPkgInfoA
*package_info
;
200 SecPkgCredentials_NamesA names
;
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
);
303 st
= pQueryCredentialsAttributesA(&cred
, SECPKG_CRED_ATTR_NAMES
, &names
);
304 ok(st
== SEC_E_NO_CREDENTIALS
|| st
== SEC_E_UNSUPPORTED_FUNCTION
/* before Vista */, "expected SEC_E_NO_CREDENTIALS, got %08x\n", st
);
306 pFreeCredentialsHandle(&cred
);
308 /* Bad version in SCHANNEL_CRED */
309 memset(&schanCred
, 0, sizeof(schanCred
));
310 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_OUTBOUND
,
311 NULL
, &schanCred
, NULL
, NULL
, NULL
, NULL
);
312 ok(st
== SEC_E_INTERNAL_ERROR
||
313 st
== SEC_E_UNKNOWN_CREDENTIALS
/* Vista/win2k8 */ ||
314 st
== SEC_E_INVALID_TOKEN
/* WinNT */, "st = %08x\n", st
);
315 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_INBOUND
,
316 NULL
, &schanCred
, NULL
, NULL
, NULL
, NULL
);
317 ok(st
== SEC_E_INTERNAL_ERROR
||
318 st
== SEC_E_UNKNOWN_CREDENTIALS
/* Vista/win2k8 */ ||
319 st
== SEC_E_INVALID_TOKEN
/* WinNT */, "st = %08x\n", st
);
321 /* No cert in SCHANNEL_CRED succeeds for outbound.. */
322 schanCred
.dwVersion
= SCHANNEL_CRED_VERSION
;
323 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_OUTBOUND
,
324 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
325 ok(st
== SEC_E_OK
, "AcquireCredentialsHandleA failed: %08x\n", st
);
326 pFreeCredentialsHandle(&cred
);
327 /* but fails for inbound. */
328 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_INBOUND
,
329 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
330 ok(st
== SEC_E_NO_CREDENTIALS
||
331 st
== SEC_E_OK
/* Vista/win2k8 */,
332 "Expected SEC_E_NO_CREDENTIALS or SEC_E_OK, got %08x\n", st
);
336 /* Crashes with bad paCred pointer */
337 schanCred
.cCreds
= 1;
338 pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_OUTBOUND
,
339 NULL
, &schanCred
, NULL
, NULL
, NULL
, NULL
);
342 /* Bogus cert in SCHANNEL_CRED. Windows fails with
343 * SEC_E_UNKNOWN_CREDENTIALS, but I'll accept SEC_E_NO_CREDENTIALS too.
345 schanCred
.cCreds
= 1;
346 schanCred
.paCred
= &certs
[0];
347 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_OUTBOUND
,
348 NULL
, &schanCred
, NULL
, NULL
, NULL
, NULL
);
349 ok(st
== SEC_E_UNKNOWN_CREDENTIALS
||
350 st
== SEC_E_NO_CREDENTIALS
||
351 st
== SEC_E_INVALID_TOKEN
/* WinNT */, "st = %08x\n", st
);
352 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_INBOUND
,
353 NULL
, &schanCred
, NULL
, NULL
, NULL
, NULL
);
354 ok(st
== SEC_E_UNKNOWN_CREDENTIALS
||
355 st
== SEC_E_NO_CREDENTIALS
||
356 st
== SEC_E_INVALID_TOKEN
/* WinNT */, "st = %08x\n", st
);
358 /* Good cert, but missing private key. Windows fails with
359 * SEC_E_NO_CREDENTIALS, but I'll accept SEC_E_UNKNOWN_CREDENTIALS too.
361 schanCred
.cCreds
= 1;
362 schanCred
.paCred
= &certs
[1];
363 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_OUTBOUND
,
364 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
365 ok(st
== SEC_E_UNKNOWN_CREDENTIALS
|| st
== SEC_E_NO_CREDENTIALS
||
366 st
== SEC_E_INTERNAL_ERROR
, /* win2k */
367 "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
368 "or SEC_E_INTERNAL_ERROR, got %08x\n", st
);
369 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_INBOUND
,
370 NULL
, &schanCred
, NULL
, NULL
, NULL
, NULL
);
371 ok(st
== SEC_E_UNKNOWN_CREDENTIALS
|| st
== SEC_E_NO_CREDENTIALS
||
372 st
== SEC_E_INTERNAL_ERROR
, /* win2k */
373 "Expected SEC_E_UNKNOWN_CREDENTIALS, SEC_E_NO_CREDENTIALS "
374 "or SEC_E_INTERNAL_ERROR, got %08x\n", st
);
376 /* Good cert, with CRYPT_KEY_PROV_INFO set before it's had a key loaded. */
377 if (pCertSetCertificateContextProperty
)
379 ret
= pCertSetCertificateContextProperty(certs
[1],
380 CERT_KEY_PROV_INFO_PROP_ID
, 0, &keyProvInfo
);
381 schanCred
.dwVersion
= SCH_CRED_V3
;
382 ok(ret
, "CertSetCertificateContextProperty failed: %08x\n", GetLastError());
383 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_OUTBOUND
,
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
);
387 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_INBOUND
,
388 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
389 ok(st
== SEC_E_UNKNOWN_CREDENTIALS
|| st
== SEC_E_INTERNAL_ERROR
/* WinNT */,
390 "Expected SEC_E_UNKNOWN_CREDENTIALS or SEC_E_INTERNAL_ERROR, got %08x\n", st
);
393 ret
= pCryptAcquireContextW(&csp
, cspNameW
, MS_DEF_PROV_W
, PROV_RSA_FULL
,
395 ok(ret
, "CryptAcquireContextW failed: %08x\n", GetLastError());
399 ret
= pCryptImportKey(csp
, privKey
, sizeof(privKey
), 0, 0, &key
);
400 ok(ret
, "CryptImportKey failed: %08x\n", GetLastError());
409 pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_INBOUND
,
410 NULL
, &schanCred
, NULL
, NULL
, NULL
, NULL
);
412 /* Crashes on WinNT */
413 /* Good cert with private key, bogus version */
414 schanCred
.dwVersion
= SCH_CRED_V1
;
415 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_OUTBOUND
,
416 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
417 ok(st
== SEC_E_INTERNAL_ERROR
||
418 st
== SEC_E_UNKNOWN_CREDENTIALS
/* Vista/win2k8 */,
419 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st
);
420 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_INBOUND
,
421 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
422 ok(st
== SEC_E_INTERNAL_ERROR
||
423 st
== SEC_E_UNKNOWN_CREDENTIALS
/* Vista/win2k8 */,
424 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st
);
425 schanCred
.dwVersion
= SCH_CRED_V2
;
426 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_OUTBOUND
,
427 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
428 ok(st
== SEC_E_INTERNAL_ERROR
||
429 st
== SEC_E_UNKNOWN_CREDENTIALS
/* Vista/win2k8 */,
430 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st
);
431 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_INBOUND
,
432 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
433 ok(st
== SEC_E_INTERNAL_ERROR
||
434 st
== SEC_E_UNKNOWN_CREDENTIALS
/* Vista/win2k8 */,
435 "Expected SEC_E_INTERNAL_ERROR or SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st
);
438 /* Succeeds on V3 or higher */
439 schanCred
.dwVersion
= SCH_CRED_V3
;
440 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_OUTBOUND
,
441 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
442 ok(st
== SEC_E_OK
, "AcquireCredentialsHandleA failed: %08x\n", st
);
443 pFreeCredentialsHandle(&cred
);
444 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_INBOUND
,
445 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
447 st
== SEC_E_UNKNOWN_CREDENTIALS
, /* win2k3 */
448 "AcquireCredentialsHandleA failed: %08x\n", st
);
449 pFreeCredentialsHandle(&cred
);
450 schanCred
.dwVersion
= SCHANNEL_CRED_VERSION
;
451 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_OUTBOUND
,
452 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
453 ok(st
== SEC_E_OK
, "AcquireCredentialsHandleA failed: %08x\n", st
);
454 pFreeCredentialsHandle(&cred
);
455 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_INBOUND
,
456 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
458 st
== SEC_E_UNKNOWN_CREDENTIALS
, /* win2k3 */
459 "AcquireCredentialsHandleA failed: %08x\n", st
);
460 if (st
== SEC_E_OK
) test_strength(&cred
);
461 pFreeCredentialsHandle(&cred
);
463 /* How about more than one cert? */
464 schanCred
.cCreds
= 2;
465 schanCred
.paCred
= certs
;
466 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_OUTBOUND
,
467 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
468 ok(st
== SEC_E_UNKNOWN_CREDENTIALS
||
469 st
== SEC_E_NO_CREDENTIALS
/* Vista/win2k8 */ ||
470 st
== SEC_E_INVALID_TOKEN
/* WinNT */, "st = %08x\n", st
);
471 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_INBOUND
,
472 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
473 ok(st
== SEC_E_UNKNOWN_CREDENTIALS
||
474 st
== SEC_E_NO_CREDENTIALS
||
475 st
== SEC_E_INVALID_TOKEN
/* WinNT */, "st = %08x\n", st
);
479 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_OUTBOUND
,
480 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
481 ok(st
== SEC_E_UNKNOWN_CREDENTIALS
||
482 st
== SEC_E_NO_CREDENTIALS
||
483 st
== SEC_E_INVALID_TOKEN
/* WinNT */, "st = %08x\n", st
);
484 st
= pAcquireCredentialsHandleA(NULL
, unisp_name_a
, SECPKG_CRED_INBOUND
,
485 NULL
, &schanCred
, NULL
, NULL
, &cred
, NULL
);
486 ok(st
== SEC_E_UNKNOWN_CREDENTIALS
,
487 "Expected SEC_E_UNKNOWN_CREDENTIALS, got %08x\n", st
);
488 /* FIXME: what about two valid certs? */
490 if (pCryptDestroyKey
)
491 pCryptDestroyKey(key
);
494 if (pCryptReleaseContext
)
495 pCryptReleaseContext(csp
, 0);
496 pCryptAcquireContextW(&csp
, cspNameW
, MS_DEF_PROV_W
, PROV_RSA_FULL
,
499 if (pCertFreeCertificateContext
)
501 pCertFreeCertificateContext(certs
[0]);
502 pCertFreeCertificateContext(certs
[1]);
506 static void test_remote_cert(PCCERT_CONTEXT remote_cert
)
508 PCCERT_CONTEXT iter
= NULL
;
509 BOOL incl_remote
= FALSE
;
510 unsigned cert_cnt
= 0;
512 ok(remote_cert
->hCertStore
!= NULL
, "hCertStore == NULL\n");
514 while((iter
= pCertEnumCertificatesInStore(remote_cert
->hCertStore
, iter
))) {
515 if(iter
== remote_cert
)
520 ok(cert_cnt
== 3, "cert_cnt = %u\n", cert_cnt
);
521 ok(incl_remote
, "context does not contain cert itself\n");
524 static const char http_request
[] = "HEAD /test.html HTTP/1.1\r\nHost: www.winehq.org\r\nConnection: close\r\n\r\n";
526 static void init_cred(SCHANNEL_CRED
*cred
)
528 cred
->dwVersion
= SCHANNEL_CRED_VERSION
;
531 cred
->hRootStore
= NULL
;
533 cred
->aphMappers
= NULL
;
534 cred
->cSupportedAlgs
= 0;
535 cred
->palgSupportedAlgs
= NULL
;
536 cred
->grbitEnabledProtocols
= SP_PROT_SSL3_CLIENT
;
537 cred
->dwMinimumCipherStrength
= 0;
538 cred
->dwMaximumCipherStrength
= 0;
539 cred
->dwSessionLifespan
= 0;
543 static void init_buffers(SecBufferDesc
*desc
, unsigned count
, unsigned size
)
545 desc
->ulVersion
= SECBUFFER_VERSION
;
546 desc
->cBuffers
= count
;
547 desc
->pBuffers
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, count
*sizeof(SecBuffer
));
549 desc
->pBuffers
[0].cbBuffer
= size
;
550 desc
->pBuffers
[0].pvBuffer
= HeapAlloc(GetProcessHeap(), 0, size
);
553 static void reset_buffers(SecBufferDesc
*desc
)
557 for (i
= 0; i
< desc
->cBuffers
; ++i
)
559 desc
->pBuffers
[i
].BufferType
= SECBUFFER_EMPTY
;
562 desc
->pBuffers
[i
].cbBuffer
= 0;
563 desc
->pBuffers
[i
].pvBuffer
= NULL
;
568 static void free_buffers(SecBufferDesc
*desc
)
570 HeapFree(GetProcessHeap(), 0, desc
->pBuffers
[0].pvBuffer
);
571 HeapFree(GetProcessHeap(), 0, desc
->pBuffers
);
574 static int receive_data(SOCKET sock
, SecBuffer
*buf
)
576 unsigned received
= 0;
580 unsigned char *data
= buf
->pvBuffer
;
581 unsigned expected
= 0;
584 ret
= recv(sock
, (char *)data
+received
, buf
->cbBuffer
-received
, 0);
587 skip("recv failed\n");
592 skip("connection closed\n");
597 while (expected
< received
)
599 unsigned frame_size
= 5 + ((data
[3]<<8) | data
[4]);
600 expected
+= frame_size
;
604 if (expected
== received
)
608 buf
->cbBuffer
= received
;
613 static void test_communication(void)
619 struct hostent
*host
;
620 struct sockaddr_in addr
;
622 SECURITY_STATUS status
;
626 CredHandle cred_handle
;
628 SecPkgCredentials_NamesA names
;
629 SecPkgContext_StreamSizes sizes
;
630 SecPkgContext_ConnectionInfo conn_info
;
633 SecBufferDesc buffers
[2];
635 unsigned buf_size
= 4000;
639 if (!pAcquireCredentialsHandleA
|| !pFreeCredentialsHandle
||
640 !pInitializeSecurityContextA
|| !pDeleteSecurityContext
||
641 !pQueryContextAttributesA
|| !pDecryptMessage
|| !pEncryptMessage
)
643 skip("Required secur32 functions not available\n");
647 /* Create a socket and connect to www.winehq.org */
648 ret
= WSAStartup(0x0202, &wsa_data
);
651 skip("Can't init winsock 2.2\n");
655 host
= gethostbyname("www.winehq.org");
658 skip("Can't resolve www.winehq.org\n");
662 addr
.sin_family
= host
->h_addrtype
;
663 addr
.sin_addr
= *(struct in_addr
*)host
->h_addr_list
[0];
664 addr
.sin_port
= htons(443);
665 sock
= socket(host
->h_addrtype
, SOCK_STREAM
, 0);
666 if (sock
== SOCKET_ERROR
)
668 skip("Can't create socket\n");
672 ret
= connect(sock
, (struct sockaddr
*)&addr
, sizeof(addr
));
673 if (ret
== SOCKET_ERROR
)
675 skip("Can't connect to www.winehq.org\n");
679 /* Create client credentials */
681 cred
.dwFlags
= SCH_CRED_NO_DEFAULT_CREDS
|SCH_CRED_MANUAL_CRED_VALIDATION
;
683 status
= pAcquireCredentialsHandleA(NULL
, (SEC_CHAR
*)UNISP_NAME_A
, SECPKG_CRED_OUTBOUND
, NULL
,
684 &cred
, NULL
, NULL
, &cred_handle
, NULL
);
685 ok(status
== SEC_E_OK
, "AcquireCredentialsHandleA failed: %08x\n", status
);
686 if (status
!= SEC_E_OK
) return;
688 test_supported_protocols(&cred_handle
, SP_PROT_SSL3_CLIENT
);
690 /* Initialize the connection */
691 init_buffers(&buffers
[0], 4, buf_size
);
692 init_buffers(&buffers
[1], 4, buf_size
);
694 buffers
[0].pBuffers
[0].BufferType
= SECBUFFER_TOKEN
;
695 status
= pInitializeSecurityContextA(&cred_handle
, NULL
, (SEC_CHAR
*)"localhost",
696 ISC_REQ_CONFIDENTIALITY
|ISC_REQ_STREAM
,
697 0, 0, NULL
, 0, &context
, &buffers
[0], &attrs
, NULL
);
698 ok(status
== SEC_I_CONTINUE_NEEDED
, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status
);
700 buffers
[1].cBuffers
= 1;
701 buffers
[1].pBuffers
[0].BufferType
= SECBUFFER_TOKEN
;
702 buffers
[0].pBuffers
[0].cbBuffer
= 1;
703 status
= pInitializeSecurityContextA(&cred_handle
, &context
, (SEC_CHAR
*)"localhost",
704 ISC_REQ_CONFIDENTIALITY
|ISC_REQ_STREAM
,
705 0, 0, &buffers
[1], 0, NULL
, &buffers
[0], &attrs
, NULL
);
706 ok(status
== SEC_E_INVALID_TOKEN
, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status
);
708 ok(buffers
[0].pBuffers
[0].cbBuffer
== 0, "Output buffer size was not set to 0.\n");
710 status
= pInitializeSecurityContextA(&cred_handle
, &context
, (SEC_CHAR
*)"localhost",
711 ISC_REQ_CONFIDENTIALITY
|ISC_REQ_STREAM
,
712 0, 0, &buffers
[1], 0, NULL
, &buffers
[0], &attrs
, NULL
);
714 ok(status
== SEC_E_INSUFFICIENT_MEMORY
|| status
== SEC_E_INVALID_TOKEN
,
715 "Expected SEC_E_INSUFFICIENT_MEMORY or SEC_E_INVALID_TOKEN, got %08x\n", status
);
717 buffers
[0].pBuffers
[0].cbBuffer
= buf_size
;
719 status
= pInitializeSecurityContextA(&cred_handle
, NULL
, (SEC_CHAR
*)"localhost",
720 ISC_REQ_CONFIDENTIALITY
|ISC_REQ_STREAM
,
721 0, 0, NULL
, 0, &context
, &buffers
[0], &attrs
, NULL
);
722 ok(status
== SEC_I_CONTINUE_NEEDED
, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status
);
724 buf
= &buffers
[0].pBuffers
[0];
725 send(sock
, buf
->pvBuffer
, buf
->cbBuffer
, 0);
726 buf
->cbBuffer
= buf_size
;
728 status
= pInitializeSecurityContextA(&cred_handle
, &context
, (SEC_CHAR
*)"localhost",
729 ISC_REQ_CONFIDENTIALITY
|ISC_REQ_STREAM
,
730 0, 0, NULL
, 0, NULL
, &buffers
[0], &attrs
, NULL
);
731 ok(status
== SEC_E_INCOMPLETE_MESSAGE
, "Got unexpected status %#x.\n", status
);
732 ok(buffers
[0].pBuffers
[0].cbBuffer
== buf_size
, "Output buffer size changed.\n");
733 ok(buffers
[0].pBuffers
[0].BufferType
== SECBUFFER_TOKEN
, "Output buffer type changed.\n");
735 buffers
[1].cBuffers
= 4;
736 buffers
[1].pBuffers
[0].cbBuffer
= 0;
738 status
= pInitializeSecurityContextA(&cred_handle
, &context
, (SEC_CHAR
*)"localhost",
739 ISC_REQ_CONFIDENTIALITY
|ISC_REQ_STREAM
,
740 0, 0, &buffers
[1], 0, NULL
, &buffers
[0], &attrs
, NULL
);
741 ok(status
== SEC_E_INCOMPLETE_MESSAGE
, "Got unexpected status %#x.\n", status
);
742 ok(buffers
[0].pBuffers
[0].cbBuffer
== buf_size
, "Output buffer size changed.\n");
743 ok(buffers
[0].pBuffers
[0].BufferType
== SECBUFFER_TOKEN
, "Output buffer type changed.\n");
745 buf
= &buffers
[1].pBuffers
[0];
746 buf
->cbBuffer
= buf_size
;
747 ret
= receive_data(sock
, buf
);
751 buffers
[1].pBuffers
[0].cbBuffer
= 4;
752 status
= pInitializeSecurityContextA(&cred_handle
, &context
, (SEC_CHAR
*)"localhost",
753 ISC_REQ_CONFIDENTIALITY
|ISC_REQ_STREAM
,
754 0, 0, &buffers
[1], 0, NULL
, &buffers
[0], &attrs
, NULL
);
755 ok(status
== SEC_E_INCOMPLETE_MESSAGE
, "Got unexpected status %#x.\n", status
);
756 ok(buffers
[0].pBuffers
[0].cbBuffer
== buf_size
, "Output buffer size changed.\n");
757 ok(buffers
[0].pBuffers
[0].BufferType
== SECBUFFER_TOKEN
, "Output buffer type changed.\n");
759 buffers
[1].pBuffers
[0].cbBuffer
= 5;
760 status
= pInitializeSecurityContextA(&cred_handle
, &context
, (SEC_CHAR
*)"localhost",
761 ISC_REQ_CONFIDENTIALITY
|ISC_REQ_STREAM
,
762 0, 0, &buffers
[1], 0, NULL
, &buffers
[0], &attrs
, NULL
);
763 ok(status
== SEC_E_INCOMPLETE_MESSAGE
, "Got unexpected status %#x.\n", status
);
764 ok(buffers
[0].pBuffers
[0].cbBuffer
== buf_size
, "Output buffer size changed.\n");
765 ok(buffers
[0].pBuffers
[0].BufferType
== SECBUFFER_TOKEN
, "Output buffer type changed.\n");
767 buffers
[1].pBuffers
[0].cbBuffer
= ret
;
768 status
= pInitializeSecurityContextA(&cred_handle
, &context
, (SEC_CHAR
*)"localhost",
769 ISC_REQ_CONFIDENTIALITY
|ISC_REQ_STREAM
,
770 0, 0, &buffers
[1], 0, NULL
, &buffers
[0], &attrs
, NULL
);
771 buffers
[1].pBuffers
[0].cbBuffer
= buf_size
;
772 while (status
== SEC_I_CONTINUE_NEEDED
)
774 buf
= &buffers
[0].pBuffers
[0];
775 send(sock
, buf
->pvBuffer
, buf
->cbBuffer
, 0);
776 buf
->cbBuffer
= buf_size
;
778 buf
= &buffers
[1].pBuffers
[0];
779 ret
= receive_data(sock
, buf
);
783 buf
->BufferType
= SECBUFFER_TOKEN
;
785 status
= pInitializeSecurityContextA(&cred_handle
, &context
, (SEC_CHAR
*)"localhost",
786 ISC_REQ_CONFIDENTIALITY
|ISC_REQ_STREAM
,
787 0, 0, &buffers
[1], 0, NULL
, &buffers
[0], &attrs
, NULL
);
788 buffers
[1].pBuffers
[0].cbBuffer
= buf_size
;
791 ok(status
== SEC_E_OK
|| broken(status
== SEC_E_INVALID_TOKEN
) /* WinNT */,
792 "InitializeSecurityContext failed: %08x\n", status
);
793 if(status
!= SEC_E_OK
) {
794 win_skip("Handshake failed\n");
798 status
= pQueryCredentialsAttributesA(&cred_handle
, SECPKG_CRED_ATTR_NAMES
, &names
);
799 ok(status
== SEC_E_NO_CREDENTIALS
|| status
== SEC_E_UNSUPPORTED_FUNCTION
/* before Vista */, "expected SEC_E_NO_CREDENTIALS, got %08x\n", status
);
801 status
= pQueryContextAttributesA(&context
, SECPKG_ATTR_REMOTE_CERT_CONTEXT
, (void*)&cert
);
802 ok(status
== SEC_E_OK
, "QueryContextAttributesW(SECPKG_ATTR_REMOTE_CERT_CONTEXT) failed: %08x\n", status
);
803 if(status
== SEC_E_OK
) {
804 test_remote_cert(cert
);
805 pCertFreeCertificateContext(cert
);
808 status
= pQueryContextAttributesA(&context
, SECPKG_ATTR_CONNECTION_INFO
, (void*)&conn_info
);
809 ok(status
== SEC_E_OK
, "QueryContextAttributesW(SECPKG_ATTR_CONNECTION_INFO) failed: %08x\n", status
);
810 if(status
== SEC_E_OK
) {
811 ok(conn_info
.dwCipherStrength
== 128 || conn_info
.dwCipherStrength
== 168,
812 "conn_info.dwCipherStrength = %d\n", conn_info
.dwCipherStrength
);
813 ok(conn_info
.dwHashStrength
>= 128, "conn_info.dwHashStrength = %d\n", conn_info
.dwHashStrength
);
816 status
= pQueryContextAttributesA(&context
, SECPKG_ATTR_STREAM_SIZES
, &sizes
);
817 ok(status
== SEC_E_OK
, "QueryContextAttributesW(SECPKG_ATTR_STREAM_SIZES) failed: %08x\n", status
);
819 reset_buffers(&buffers
[0]);
821 /* Send a simple request so we get data for testing DecryptMessage */
822 buf
= &buffers
[0].pBuffers
[0];
823 data
= buf
->pvBuffer
;
824 buf
->BufferType
= SECBUFFER_STREAM_HEADER
;
825 buf
->cbBuffer
= sizes
.cbHeader
;
827 buf
->BufferType
= SECBUFFER_DATA
;
828 buf
->pvBuffer
= data
+ sizes
.cbHeader
;
829 buf
->cbBuffer
= sizeof(http_request
) - 1;
830 memcpy(buf
->pvBuffer
, http_request
, sizeof(http_request
) - 1);
832 buf
->BufferType
= SECBUFFER_STREAM_TRAILER
;
833 buf
->pvBuffer
= data
+ sizes
.cbHeader
+ sizeof(http_request
) -1;
834 buf
->cbBuffer
= sizes
.cbTrailer
;
836 status
= pEncryptMessage(&context
, 0, &buffers
[0], 0);
837 ok(status
== SEC_E_OK
, "EncryptMessage failed: %08x\n", status
);
838 if (status
!= SEC_E_OK
)
841 buf
= &buffers
[0].pBuffers
[0];
842 send(sock
, buf
->pvBuffer
, buffers
[0].pBuffers
[0].cbBuffer
+ buffers
[0].pBuffers
[1].cbBuffer
+ buffers
[0].pBuffers
[2].cbBuffer
, 0);
844 reset_buffers(&buffers
[0]);
845 buf
->cbBuffer
= buf_size
;
846 data_size
= receive_data(sock
, buf
);
848 /* Too few buffers */
849 --buffers
[0].cBuffers
;
850 status
= pDecryptMessage(&context
, &buffers
[0], 0, NULL
);
851 ok(status
== SEC_E_INVALID_TOKEN
, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status
);
854 ++buffers
[0].cBuffers
;
855 status
= pDecryptMessage(&context
, &buffers
[0], 0, NULL
);
856 ok(status
== SEC_E_INVALID_TOKEN
, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status
);
858 /* Two data buffers */
859 buffers
[0].pBuffers
[0].BufferType
= SECBUFFER_DATA
;
860 buffers
[0].pBuffers
[1].BufferType
= SECBUFFER_DATA
;
861 status
= pDecryptMessage(&context
, &buffers
[0], 0, NULL
);
862 ok(status
== SEC_E_INVALID_TOKEN
, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status
);
864 /* Too few empty buffers */
865 buffers
[0].pBuffers
[1].BufferType
= SECBUFFER_EXTRA
;
866 status
= pDecryptMessage(&context
, &buffers
[0], 0, NULL
);
867 ok(status
== SEC_E_INVALID_TOKEN
, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status
);
869 /* Incomplete data */
870 buffers
[0].pBuffers
[1].BufferType
= SECBUFFER_EMPTY
;
871 buffers
[0].pBuffers
[0].cbBuffer
= (data
[3]<<8) | data
[4];
872 status
= pDecryptMessage(&context
, &buffers
[0], 0, NULL
);
873 ok(status
== SEC_E_INCOMPLETE_MESSAGE
, "Expected SEC_E_INCOMPLETE_MESSAGE, got %08x\n", status
);
874 ok(buffers
[0].pBuffers
[0].BufferType
== SECBUFFER_MISSING
, "Expected first buffer to be SECBUFFER_MISSING\n");
875 ok(buffers
[0].pBuffers
[0].cbBuffer
== 5, "Expected first buffer to be a five bytes\n");
877 buffers
[0].pBuffers
[0].cbBuffer
= data_size
;
878 buffers
[0].pBuffers
[0].BufferType
= SECBUFFER_DATA
;
879 buffers
[0].pBuffers
[1].BufferType
= SECBUFFER_EMPTY
;
880 status
= pDecryptMessage(&context
, &buffers
[0], 0, NULL
);
881 ok(status
== SEC_E_OK
, "DecryptMessage failed: %08x\n", status
);
882 if (status
== SEC_E_OK
)
884 ok(buffers
[0].pBuffers
[0].BufferType
== SECBUFFER_STREAM_HEADER
, "Expected first buffer to be SECBUFFER_STREAM_HEADER\n");
885 ok(buffers
[0].pBuffers
[1].BufferType
== SECBUFFER_DATA
, "Expected second buffer to be SECBUFFER_DATA\n");
886 ok(buffers
[0].pBuffers
[2].BufferType
== SECBUFFER_STREAM_TRAILER
, "Expected third buffer to be SECBUFFER_STREAM_TRAILER\n");
888 data
= buffers
[0].pBuffers
[1].pvBuffer
;
889 data
[buffers
[0].pBuffers
[1].cbBuffer
] = 0;
892 pDeleteSecurityContext(&context
);
893 pFreeCredentialsHandle(&cred_handle
);
895 free_buffers(&buffers
[0]);
896 free_buffers(&buffers
[1]);
905 testAcquireSecurityContext();
906 test_communication();
911 FreeLibrary(crypt32dll
);