push 92ef5b88da02911741c0a2f56030fd2e20189321
[wine/hacks.git] / dlls / secur32 / schannel.c
blobb74e54ca1853d23fb9ba7dc3fde0d05c19ff3c41
1 /* Copyright (C) 2005 Juan Lang
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 * This file implements the schannel provider, or, the SSL/TLS implementations.
18 * FIXME: It should be rather obvious that this file is empty of any
19 * implementation.
21 #include <stdarg.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "sspi.h"
25 #include "schannel.h"
26 #include "secur32_priv.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
31 static SECURITY_STATUS schan_QueryCredentialsAttributes(
32 PCredHandle phCredential, ULONG ulAttribute, const VOID *pBuffer)
34 SECURITY_STATUS ret;
36 switch (ulAttribute)
38 case SECPKG_ATTR_SUPPORTED_ALGS:
39 if (pBuffer)
41 /* FIXME: get from CryptoAPI */
42 FIXME("%d: stub\n", ulAttribute);
43 ret = SEC_E_UNSUPPORTED_FUNCTION;
45 else
46 ret = SEC_E_INTERNAL_ERROR;
47 break;
48 case SECPKG_ATTR_CIPHER_STRENGTHS:
49 if (pBuffer)
51 /* FIXME: get from CryptoAPI */
52 FIXME("%d: stub\n", ulAttribute);
53 ret = SEC_E_UNSUPPORTED_FUNCTION;
55 else
56 ret = SEC_E_INTERNAL_ERROR;
57 break;
58 case SECPKG_ATTR_SUPPORTED_PROTOCOLS:
59 if (pBuffer)
61 /* FIXME: get from OpenSSL? */
62 FIXME("%d: stub\n", ulAttribute);
63 ret = SEC_E_UNSUPPORTED_FUNCTION;
65 else
66 ret = SEC_E_INTERNAL_ERROR;
67 break;
68 default:
69 ret = SEC_E_UNSUPPORTED_FUNCTION;
71 return ret;
74 static SECURITY_STATUS SEC_ENTRY schan_QueryCredentialsAttributesA(
75 PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
77 SECURITY_STATUS ret;
79 TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);
81 switch (ulAttribute)
83 case SECPKG_CRED_ATTR_NAMES:
84 FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
85 ret = SEC_E_UNSUPPORTED_FUNCTION;
86 break;
87 default:
88 ret = schan_QueryCredentialsAttributes(phCredential, ulAttribute,
89 pBuffer);
91 return ret;
94 static SECURITY_STATUS SEC_ENTRY schan_QueryCredentialsAttributesW(
95 PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
97 SECURITY_STATUS ret;
99 TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);
101 switch (ulAttribute)
103 case SECPKG_CRED_ATTR_NAMES:
104 FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
105 ret = SEC_E_UNSUPPORTED_FUNCTION;
106 break;
107 default:
108 ret = schan_QueryCredentialsAttributes(phCredential, ulAttribute,
109 pBuffer);
111 return ret;
114 static SECURITY_STATUS schan_CheckCreds(const SCHANNEL_CRED *schanCred)
116 SECURITY_STATUS st;
118 switch (schanCred->dwVersion)
120 case SCH_CRED_V3:
121 case SCHANNEL_CRED_VERSION:
122 break;
123 default:
124 return SEC_E_INTERNAL_ERROR;
127 if (schanCred->cCreds == 0)
128 st = SEC_E_NO_CREDENTIALS;
129 else if (schanCred->cCreds > 1)
130 st = SEC_E_UNKNOWN_CREDENTIALS;
131 else
133 DWORD keySpec;
134 HCRYPTPROV csp;
135 BOOL ret, freeCSP;
137 ret = CryptAcquireCertificatePrivateKey(schanCred->paCred[0],
138 0, /* FIXME: what flags to use? */ NULL,
139 &csp, &keySpec, &freeCSP);
140 if (ret)
142 st = SEC_E_OK;
143 if (freeCSP)
144 CryptReleaseContext(csp, 0);
146 else
147 st = SEC_E_UNKNOWN_CREDENTIALS;
149 return st;
152 static SECURITY_STATUS schan_AcquireClientCredentials(const SCHANNEL_CRED *schanCred,
153 PCredHandle phCredential, PTimeStamp ptsExpiry)
155 SECURITY_STATUS st = SEC_E_OK;
157 if (schanCred)
159 st = schan_CheckCreds(schanCred);
160 if (st == SEC_E_NO_CREDENTIALS)
161 st = SEC_E_OK;
164 /* For now, the only thing I'm interested in is the direction of the
165 * connection, so just store it.
167 if (st == SEC_E_OK)
169 phCredential->dwUpper = SECPKG_CRED_OUTBOUND;
170 /* Outbound credentials have no expiry */
171 if (ptsExpiry)
173 ptsExpiry->LowPart = 0;
174 ptsExpiry->HighPart = 0;
177 return st;
180 static SECURITY_STATUS schan_AcquireServerCredentials(const SCHANNEL_CRED *schanCred,
181 PCredHandle phCredential, PTimeStamp ptsExpiry)
183 SECURITY_STATUS st;
185 if (!schanCred) return SEC_E_NO_CREDENTIALS;
187 st = schan_CheckCreds(schanCred);
188 if (st == SEC_E_OK)
190 phCredential->dwUpper = SECPKG_CRED_INBOUND;
191 /* FIXME: get expiry from cert */
193 return st;
196 static SECURITY_STATUS schan_AcquireCredentialsHandle(ULONG fCredentialUse,
197 const SCHANNEL_CRED *schanCred, PCredHandle phCredential, PTimeStamp ptsExpiry)
199 SECURITY_STATUS ret;
201 if (fCredentialUse == SECPKG_CRED_OUTBOUND)
202 ret = schan_AcquireClientCredentials(schanCred, phCredential,
203 ptsExpiry);
204 else
205 ret = schan_AcquireServerCredentials(schanCred, phCredential,
206 ptsExpiry);
207 return ret;
210 static SECURITY_STATUS SEC_ENTRY schan_AcquireCredentialsHandleA(
211 SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
212 PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
213 PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
215 TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p)\n",
216 debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
217 pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
218 return schan_AcquireCredentialsHandle(fCredentialUse,
219 (PSCHANNEL_CRED)pAuthData, phCredential, ptsExpiry);
222 static SECURITY_STATUS SEC_ENTRY schan_AcquireCredentialsHandleW(
223 SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
224 PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
225 PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
227 TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p)\n",
228 debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
229 pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
230 return schan_AcquireCredentialsHandle(fCredentialUse,
231 (PSCHANNEL_CRED)pAuthData, phCredential, ptsExpiry);
234 static SECURITY_STATUS SEC_ENTRY schan_FreeCredentialsHandle(
235 PCredHandle phCredential)
237 FIXME("(%p): stub\n", phCredential);
238 return SEC_E_OK;
241 /***********************************************************************
242 * InitializeSecurityContextA
244 static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextA(
245 PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName,
246 ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
247 PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
248 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
250 SECURITY_STATUS ret;
252 TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
253 debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
254 Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
255 if(phCredential)
257 FIXME("stub\n");
258 ret = SEC_E_UNSUPPORTED_FUNCTION;
260 else
262 ret = SEC_E_INVALID_HANDLE;
264 return ret;
267 /***********************************************************************
268 * InitializeSecurityContextW
270 static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
271 PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName,
272 ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
273 PSecBufferDesc pInput,ULONG Reserved2, PCtxtHandle phNewContext,
274 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
276 SECURITY_STATUS ret;
278 TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
279 debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
280 Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
281 if (phCredential)
283 FIXME("stub\n");
284 ret = SEC_E_UNSUPPORTED_FUNCTION;
286 else
288 ret = SEC_E_INVALID_HANDLE;
290 return ret;
293 static const SecurityFunctionTableA schanTableA = {
295 NULL, /* EnumerateSecurityPackagesA */
296 schan_QueryCredentialsAttributesA,
297 schan_AcquireCredentialsHandleA,
298 schan_FreeCredentialsHandle,
299 NULL, /* Reserved2 */
300 schan_InitializeSecurityContextA,
301 NULL, /* AcceptSecurityContext */
302 NULL, /* CompleteAuthToken */
303 NULL, /* DeleteSecurityContext */
304 NULL, /* ApplyControlToken */
305 NULL, /* QueryContextAttributesA */
306 NULL, /* ImpersonateSecurityContext */
307 NULL, /* RevertSecurityContext */
308 NULL, /* MakeSignature */
309 NULL, /* VerifySignature */
310 FreeContextBuffer,
311 NULL, /* QuerySecurityPackageInfoA */
312 NULL, /* Reserved3 */
313 NULL, /* Reserved4 */
314 NULL, /* ExportSecurityContext */
315 NULL, /* ImportSecurityContextA */
316 NULL, /* AddCredentialsA */
317 NULL, /* Reserved8 */
318 NULL, /* QuerySecurityContextToken */
319 NULL, /* EncryptMessage */
320 NULL, /* DecryptMessage */
321 NULL, /* SetContextAttributesA */
324 static const SecurityFunctionTableW schanTableW = {
326 NULL, /* EnumerateSecurityPackagesW */
327 schan_QueryCredentialsAttributesW,
328 schan_AcquireCredentialsHandleW,
329 schan_FreeCredentialsHandle,
330 NULL, /* Reserved2 */
331 schan_InitializeSecurityContextW,
332 NULL, /* AcceptSecurityContext */
333 NULL, /* CompleteAuthToken */
334 NULL, /* DeleteSecurityContext */
335 NULL, /* ApplyControlToken */
336 NULL, /* QueryContextAttributesW */
337 NULL, /* ImpersonateSecurityContext */
338 NULL, /* RevertSecurityContext */
339 NULL, /* MakeSignature */
340 NULL, /* VerifySignature */
341 FreeContextBuffer,
342 NULL, /* QuerySecurityPackageInfoW */
343 NULL, /* Reserved3 */
344 NULL, /* Reserved4 */
345 NULL, /* ExportSecurityContext */
346 NULL, /* ImportSecurityContextW */
347 NULL, /* AddCredentialsW */
348 NULL, /* Reserved8 */
349 NULL, /* QuerySecurityContextToken */
350 NULL, /* EncryptMessage */
351 NULL, /* DecryptMessage */
352 NULL, /* SetContextAttributesW */
355 static const WCHAR schannelComment[] = { 'S','c','h','a','n','n','e','l',' ',
356 'S','e','c','u','r','i','t','y',' ','P','a','c','k','a','g','e',0 };
358 void SECUR32_initSchannelSP(void)
360 SecureProvider *provider = SECUR32_addProvider(&schanTableA, &schanTableW,
361 NULL);
363 if (provider)
365 /* This is what Windows reports. This shouldn't break any applications
366 * even though the functions are missing, because the wrapper will
367 * return SEC_E_UNSUPPORTED_FUNCTION if our function is NULL.
369 static const long caps =
370 SECPKG_FLAG_INTEGRITY |
371 SECPKG_FLAG_PRIVACY |
372 SECPKG_FLAG_CONNECTION |
373 SECPKG_FLAG_MULTI_REQUIRED |
374 SECPKG_FLAG_EXTENDED_ERROR |
375 SECPKG_FLAG_IMPERSONATION |
376 SECPKG_FLAG_ACCEPT_WIN32_NAME |
377 SECPKG_FLAG_STREAM;
378 static const short version = 1;
379 static const long maxToken = 16384;
380 SEC_WCHAR *uniSPName = (SEC_WCHAR *)UNISP_NAME_W,
381 *schannel = (SEC_WCHAR *)SCHANNEL_NAME_W;
383 const SecPkgInfoW info[] = {
384 { caps, version, UNISP_RPC_ID, maxToken, uniSPName, uniSPName },
385 { caps, version, UNISP_RPC_ID, maxToken, schannel,
386 (SEC_WCHAR *)schannelComment },
389 SECUR32_addPackages(provider, sizeof(info) / sizeof(info[0]), NULL,
390 info);