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
, const VOID
*pBuffer
)
38 case SECPKG_ATTR_SUPPORTED_ALGS
:
41 /* FIXME: get from CryptoAPI */
42 FIXME("SECPKG_ATTR_SUPPORTED_ALGS: stub\n");
43 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
46 ret
= SEC_E_INTERNAL_ERROR
;
48 case SECPKG_ATTR_CIPHER_STRENGTHS
:
51 SecPkgCred_CipherStrengths
*r
= (SecPkgCred_CipherStrengths
*)pBuffer
;
53 /* FIXME: get from CryptoAPI */
54 FIXME("SECPKG_ATTR_CIPHER_STRENGTHS: semi-stub\n");
55 r
->dwMinimumCipherStrength
= 40;
56 r
->dwMaximumCipherStrength
= 168;
60 ret
= SEC_E_INTERNAL_ERROR
;
62 case SECPKG_ATTR_SUPPORTED_PROTOCOLS
:
65 /* FIXME: get from OpenSSL? */
66 FIXME("SECPKG_ATTR_SUPPORTED_PROTOCOLS: stub\n");
67 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
70 ret
= SEC_E_INTERNAL_ERROR
;
73 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
78 static SECURITY_STATUS SEC_ENTRY
schan_QueryCredentialsAttributesA(
79 PCredHandle phCredential
, ULONG ulAttribute
, PVOID pBuffer
)
83 TRACE("(%p, %d, %p)\n", phCredential
, ulAttribute
, pBuffer
);
87 case SECPKG_CRED_ATTR_NAMES
:
88 FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
89 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
92 ret
= schan_QueryCredentialsAttributes(phCredential
, ulAttribute
,
98 static SECURITY_STATUS SEC_ENTRY
schan_QueryCredentialsAttributesW(
99 PCredHandle phCredential
, ULONG ulAttribute
, PVOID pBuffer
)
103 TRACE("(%p, %d, %p)\n", phCredential
, ulAttribute
, pBuffer
);
107 case SECPKG_CRED_ATTR_NAMES
:
108 FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
109 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
112 ret
= schan_QueryCredentialsAttributes(phCredential
, ulAttribute
,
118 static SECURITY_STATUS
schan_CheckCreds(const SCHANNEL_CRED
*schanCred
)
122 switch (schanCred
->dwVersion
)
125 case SCHANNEL_CRED_VERSION
:
128 return SEC_E_INTERNAL_ERROR
;
131 if (schanCred
->cCreds
== 0)
132 st
= SEC_E_NO_CREDENTIALS
;
133 else if (schanCred
->cCreds
> 1)
134 st
= SEC_E_UNKNOWN_CREDENTIALS
;
141 ret
= CryptAcquireCertificatePrivateKey(schanCred
->paCred
[0],
142 0, /* FIXME: what flags to use? */ NULL
,
143 &csp
, &keySpec
, &freeCSP
);
148 CryptReleaseContext(csp
, 0);
151 st
= SEC_E_UNKNOWN_CREDENTIALS
;
156 static SECURITY_STATUS
schan_AcquireClientCredentials(const SCHANNEL_CRED
*schanCred
,
157 PCredHandle phCredential
, PTimeStamp ptsExpiry
)
159 SECURITY_STATUS st
= SEC_E_OK
;
163 st
= schan_CheckCreds(schanCred
);
164 if (st
== SEC_E_NO_CREDENTIALS
)
168 /* For now, the only thing I'm interested in is the direction of the
169 * connection, so just store it.
173 phCredential
->dwUpper
= SECPKG_CRED_OUTBOUND
;
174 /* Outbound credentials have no expiry */
177 ptsExpiry
->LowPart
= 0;
178 ptsExpiry
->HighPart
= 0;
184 static SECURITY_STATUS
schan_AcquireServerCredentials(const SCHANNEL_CRED
*schanCred
,
185 PCredHandle phCredential
, PTimeStamp ptsExpiry
)
189 if (!schanCred
) return SEC_E_NO_CREDENTIALS
;
191 st
= schan_CheckCreds(schanCred
);
194 phCredential
->dwUpper
= SECPKG_CRED_INBOUND
;
195 /* FIXME: get expiry from cert */
200 static SECURITY_STATUS
schan_AcquireCredentialsHandle(ULONG fCredentialUse
,
201 const SCHANNEL_CRED
*schanCred
, PCredHandle phCredential
, PTimeStamp ptsExpiry
)
205 if (fCredentialUse
== SECPKG_CRED_OUTBOUND
)
206 ret
= schan_AcquireClientCredentials(schanCred
, phCredential
,
209 ret
= schan_AcquireServerCredentials(schanCred
, phCredential
,
214 static SECURITY_STATUS SEC_ENTRY
schan_AcquireCredentialsHandleA(
215 SEC_CHAR
*pszPrincipal
, SEC_CHAR
*pszPackage
, ULONG fCredentialUse
,
216 PLUID pLogonID
, PVOID pAuthData
, SEC_GET_KEY_FN pGetKeyFn
,
217 PVOID pGetKeyArgument
, PCredHandle phCredential
, PTimeStamp ptsExpiry
)
219 TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p)\n",
220 debugstr_a(pszPrincipal
), debugstr_a(pszPackage
), fCredentialUse
,
221 pLogonID
, pAuthData
, pGetKeyFn
, pGetKeyArgument
, phCredential
, ptsExpiry
);
222 return schan_AcquireCredentialsHandle(fCredentialUse
,
223 (PSCHANNEL_CRED
)pAuthData
, phCredential
, ptsExpiry
);
226 static SECURITY_STATUS SEC_ENTRY
schan_AcquireCredentialsHandleW(
227 SEC_WCHAR
*pszPrincipal
, SEC_WCHAR
*pszPackage
, ULONG fCredentialUse
,
228 PLUID pLogonID
, PVOID pAuthData
, SEC_GET_KEY_FN pGetKeyFn
,
229 PVOID pGetKeyArgument
, PCredHandle phCredential
, PTimeStamp ptsExpiry
)
231 TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p)\n",
232 debugstr_w(pszPrincipal
), debugstr_w(pszPackage
), fCredentialUse
,
233 pLogonID
, pAuthData
, pGetKeyFn
, pGetKeyArgument
, phCredential
, ptsExpiry
);
234 return schan_AcquireCredentialsHandle(fCredentialUse
,
235 (PSCHANNEL_CRED
)pAuthData
, phCredential
, ptsExpiry
);
238 static SECURITY_STATUS SEC_ENTRY
schan_FreeCredentialsHandle(
239 PCredHandle phCredential
)
241 FIXME("(%p): stub\n", phCredential
);
245 /***********************************************************************
246 * InitializeSecurityContextA
248 static SECURITY_STATUS SEC_ENTRY
schan_InitializeSecurityContextA(
249 PCredHandle phCredential
, PCtxtHandle phContext
, SEC_CHAR
*pszTargetName
,
250 ULONG fContextReq
, ULONG Reserved1
, ULONG TargetDataRep
,
251 PSecBufferDesc pInput
, ULONG Reserved2
, PCtxtHandle phNewContext
,
252 PSecBufferDesc pOutput
, ULONG
*pfContextAttr
, PTimeStamp ptsExpiry
)
256 TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential
, phContext
,
257 debugstr_a(pszTargetName
), fContextReq
, Reserved1
, TargetDataRep
, pInput
,
258 Reserved1
, phNewContext
, pOutput
, pfContextAttr
, ptsExpiry
);
262 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
266 ret
= SEC_E_INVALID_HANDLE
;
271 /***********************************************************************
272 * InitializeSecurityContextW
274 static SECURITY_STATUS SEC_ENTRY
schan_InitializeSecurityContextW(
275 PCredHandle phCredential
, PCtxtHandle phContext
, SEC_WCHAR
*pszTargetName
,
276 ULONG fContextReq
, ULONG Reserved1
, ULONG TargetDataRep
,
277 PSecBufferDesc pInput
,ULONG Reserved2
, PCtxtHandle phNewContext
,
278 PSecBufferDesc pOutput
, ULONG
*pfContextAttr
, PTimeStamp ptsExpiry
)
282 TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential
, phContext
,
283 debugstr_w(pszTargetName
), fContextReq
, Reserved1
, TargetDataRep
, pInput
,
284 Reserved1
, phNewContext
, pOutput
, pfContextAttr
, ptsExpiry
);
288 ret
= SEC_E_UNSUPPORTED_FUNCTION
;
292 ret
= SEC_E_INVALID_HANDLE
;
297 static const SecurityFunctionTableA schanTableA
= {
299 NULL
, /* EnumerateSecurityPackagesA */
300 schan_QueryCredentialsAttributesA
,
301 schan_AcquireCredentialsHandleA
,
302 schan_FreeCredentialsHandle
,
303 NULL
, /* Reserved2 */
304 schan_InitializeSecurityContextA
,
305 NULL
, /* AcceptSecurityContext */
306 NULL
, /* CompleteAuthToken */
307 NULL
, /* DeleteSecurityContext */
308 NULL
, /* ApplyControlToken */
309 NULL
, /* QueryContextAttributesA */
310 NULL
, /* ImpersonateSecurityContext */
311 NULL
, /* RevertSecurityContext */
312 NULL
, /* MakeSignature */
313 NULL
, /* VerifySignature */
315 NULL
, /* QuerySecurityPackageInfoA */
316 NULL
, /* Reserved3 */
317 NULL
, /* Reserved4 */
318 NULL
, /* ExportSecurityContext */
319 NULL
, /* ImportSecurityContextA */
320 NULL
, /* AddCredentialsA */
321 NULL
, /* Reserved8 */
322 NULL
, /* QuerySecurityContextToken */
323 NULL
, /* EncryptMessage */
324 NULL
, /* DecryptMessage */
325 NULL
, /* SetContextAttributesA */
328 static const SecurityFunctionTableW schanTableW
= {
330 NULL
, /* EnumerateSecurityPackagesW */
331 schan_QueryCredentialsAttributesW
,
332 schan_AcquireCredentialsHandleW
,
333 schan_FreeCredentialsHandle
,
334 NULL
, /* Reserved2 */
335 schan_InitializeSecurityContextW
,
336 NULL
, /* AcceptSecurityContext */
337 NULL
, /* CompleteAuthToken */
338 NULL
, /* DeleteSecurityContext */
339 NULL
, /* ApplyControlToken */
340 NULL
, /* QueryContextAttributesW */
341 NULL
, /* ImpersonateSecurityContext */
342 NULL
, /* RevertSecurityContext */
343 NULL
, /* MakeSignature */
344 NULL
, /* VerifySignature */
346 NULL
, /* QuerySecurityPackageInfoW */
347 NULL
, /* Reserved3 */
348 NULL
, /* Reserved4 */
349 NULL
, /* ExportSecurityContext */
350 NULL
, /* ImportSecurityContextW */
351 NULL
, /* AddCredentialsW */
352 NULL
, /* Reserved8 */
353 NULL
, /* QuerySecurityContextToken */
354 NULL
, /* EncryptMessage */
355 NULL
, /* DecryptMessage */
356 NULL
, /* SetContextAttributesW */
359 static const WCHAR schannelComment
[] = { 'S','c','h','a','n','n','e','l',' ',
360 'S','e','c','u','r','i','t','y',' ','P','a','c','k','a','g','e',0 };
361 static const WCHAR schannelDllName
[] = { 's','c','h','a','n','n','e','l','.','d','l','l',0 };
363 void SECUR32_initSchannelSP(void)
365 SecureProvider
*provider
= SECUR32_addProvider(&schanTableA
, &schanTableW
,
370 /* This is what Windows reports. This shouldn't break any applications
371 * even though the functions are missing, because the wrapper will
372 * return SEC_E_UNSUPPORTED_FUNCTION if our function is NULL.
374 static const long caps
=
375 SECPKG_FLAG_INTEGRITY
|
376 SECPKG_FLAG_PRIVACY
|
377 SECPKG_FLAG_CONNECTION
|
378 SECPKG_FLAG_MULTI_REQUIRED
|
379 SECPKG_FLAG_EXTENDED_ERROR
|
380 SECPKG_FLAG_IMPERSONATION
|
381 SECPKG_FLAG_ACCEPT_WIN32_NAME
|
383 static const short version
= 1;
384 static const long maxToken
= 16384;
385 SEC_WCHAR
*uniSPName
= (SEC_WCHAR
*)UNISP_NAME_W
,
386 *schannel
= (SEC_WCHAR
*)SCHANNEL_NAME_W
;
388 const SecPkgInfoW info
[] = {
389 { caps
, version
, UNISP_RPC_ID
, maxToken
, uniSPName
, uniSPName
},
390 { caps
, version
, UNISP_RPC_ID
, maxToken
, schannel
,
391 (SEC_WCHAR
*)schannelComment
},
394 SECUR32_addPackages(provider
, sizeof(info
) / sizeof(info
[0]), NULL
,