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
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, PVOID pBuffer)
38 case SECPKG_ATTR_SUPPORTED_ALGS:
41 /* FIXME: get from CryptoAPI */
42 FIXME("%d: stub\n", ulAttribute);
43 ret = SEC_E_UNSUPPORTED_FUNCTION;
46 ret = SEC_E_INTERNAL_ERROR;
48 case SECPKG_ATTR_CIPHER_STRENGTHS:
51 /* FIXME: get from CryptoAPI */
52 FIXME("%d: stub\n", ulAttribute);
53 ret = SEC_E_UNSUPPORTED_FUNCTION;
56 ret = SEC_E_INTERNAL_ERROR;
58 case SECPKG_ATTR_SUPPORTED_PROTOCOLS:
61 /* FIXME: get from OpenSSL? */
62 FIXME("%d: stub\n", ulAttribute);
63 ret = SEC_E_UNSUPPORTED_FUNCTION;
66 ret = SEC_E_INTERNAL_ERROR;
69 ret = SEC_E_UNSUPPORTED_FUNCTION;
74 static SECURITY_STATUS SEC_ENTRY schan_QueryCredentialsAttributesA(
75 PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
79 TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);
83 case SECPKG_CRED_ATTR_NAMES:
84 FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
85 ret = SEC_E_UNSUPPORTED_FUNCTION;
88 ret = schan_QueryCredentialsAttributes(phCredential, ulAttribute,
94 static SECURITY_STATUS SEC_ENTRY schan_QueryCredentialsAttributesW(
95 PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
99 TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);
103 case SECPKG_CRED_ATTR_NAMES:
104 FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
105 ret = SEC_E_UNSUPPORTED_FUNCTION;
108 ret = schan_QueryCredentialsAttributes(phCredential, ulAttribute,
114 static SECURITY_STATUS schan_CheckCreds(PSCHANNEL_CRED schanCred)
118 switch (schanCred->dwVersion)
121 case SCHANNEL_CRED_VERSION:
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;
137 ret = CryptAcquireCertificatePrivateKey(schanCred->paCred[0],
138 0, /* FIXME: what flags to use? */ NULL,
139 &csp, &keySpec, &freeCSP);
144 CryptReleaseContext(csp, 0);
147 st = SEC_E_UNKNOWN_CREDENTIALS;
152 static SECURITY_STATUS schan_AcquireClientCredentials(PSCHANNEL_CRED schanCred,
153 PCredHandle phCredential, PTimeStamp ptsExpiry)
155 SECURITY_STATUS st = SEC_E_OK;
159 st = schan_CheckCreds(schanCred);
160 if (st == SEC_E_NO_CREDENTIALS)
164 /* For now, the only thing I'm interested in is the direction of the
165 * connection, so just store it.
169 phCredential->dwUpper = SECPKG_CRED_OUTBOUND;
170 /* Outbound credentials have no expiry */
173 ptsExpiry->LowPart = 0;
174 ptsExpiry->HighPart = 0;
180 static SECURITY_STATUS schan_AcquireServerCredentials(PSCHANNEL_CRED schanCred,
181 PCredHandle phCredential, PTimeStamp ptsExpiry)
185 if (!schanCred) return SEC_E_NO_CREDENTIALS;
187 st = schan_CheckCreds(schanCred);
190 phCredential->dwUpper = SECPKG_CRED_INBOUND;
191 /* FIXME: get expiry from cert */
196 static SECURITY_STATUS schan_AcquireCredentialsHandle(ULONG fCredentialUse,
197 PSCHANNEL_CRED schanCred, PCredHandle phCredential, PTimeStamp ptsExpiry)
201 if (fCredentialUse == SECPKG_CRED_OUTBOUND)
202 ret = schan_AcquireClientCredentials(schanCred, phCredential,
205 ret = schan_AcquireServerCredentials(schanCred, phCredential,
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);
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)
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);
258 ret = SEC_E_UNSUPPORTED_FUNCTION;
262 ret = SEC_E_INVALID_HANDLE;
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)
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);
284 ret = SEC_E_UNSUPPORTED_FUNCTION;
288 ret = SEC_E_INVALID_HANDLE;
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 */
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 */
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,
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 |
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,