Commit 0a8adeba authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

secur32: Add support for SCH_CREDENTIALS.

parent bf86dfbc
......@@ -31,6 +31,7 @@
#include "winnls.h"
#include "lmcons.h"
#include "sspi.h"
#define SCHANNEL_USE_BLACKLISTS
#include "schannel.h"
#include "wine/unixlib.h"
......@@ -333,46 +334,74 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryCredentialsAttributesW(
return ret;
}
static SECURITY_STATUS get_cert(const SCHANNEL_CRED *cred, CERT_CONTEXT const **cert)
static SECURITY_STATUS get_cert(const void *credentials, CERT_CONTEXT const **cert)
{
SECURITY_STATUS status;
DWORD i;
TRACE("dwVersion = %lu\n", cred->dwVersion);
TRACE("cCreds = %lu\n", cred->cCreds);
TRACE("paCred = %p\n", cred->paCred);
TRACE("hRootStore = %p\n", cred->hRootStore);
TRACE("cMappers = %lu\n", cred->cMappers);
TRACE("cSupportedAlgs = %lu:\n", cred->cSupportedAlgs);
for (i = 0; i < cred->cSupportedAlgs; i++) TRACE("%08x\n", cred->palgSupportedAlgs[i]);
TRACE("grbitEnabledProtocols = %08lx\n", cred->grbitEnabledProtocols);
TRACE("dwMinimumCipherStrength = %lu\n", cred->dwMinimumCipherStrength);
TRACE("dwMaximumCipherStrength = %lu\n", cred->dwMaximumCipherStrength);
TRACE("dwSessionLifespan = %lu\n", cred->dwSessionLifespan);
TRACE("dwFlags = %08lx\n", cred->dwFlags);
TRACE("dwCredFormat = %lu\n", cred->dwCredFormat);
const SCHANNEL_CRED *cred_old;
const SCH_CREDENTIALS *cred = credentials;
PCCERT_CONTEXT *cert_list;
DWORD i, cert_count;
switch (cred->dwVersion)
{
case SCH_CRED_V3:
case SCHANNEL_CRED_VERSION:
cred_old = credentials;
TRACE("dwVersion = %lu\n", cred_old->dwVersion);
TRACE("cCreds = %lu\n", cred_old->cCreds);
TRACE("paCred = %p\n", cred_old->paCred);
TRACE("hRootStore = %p\n", cred_old->hRootStore);
TRACE("cMappers = %lu\n", cred_old->cMappers);
TRACE("cSupportedAlgs = %lu:\n", cred_old->cSupportedAlgs);
for (i = 0; i < cred_old->cSupportedAlgs; i++) TRACE("%08x\n", cred_old->palgSupportedAlgs[i]);
TRACE("grbitEnabledProtocols = %08lx\n", cred_old->grbitEnabledProtocols);
TRACE("dwMinimumCipherStrength = %lu\n", cred_old->dwMinimumCipherStrength);
TRACE("dwMaximumCipherStrength = %lu\n", cred_old->dwMaximumCipherStrength);
TRACE("dwSessionLifespan = %lu\n", cred_old->dwSessionLifespan);
TRACE("dwFlags = %08lx\n", cred_old->dwFlags);
TRACE("dwCredFormat = %lu\n", cred_old->dwCredFormat);
cert_list = cred_old->paCred;
cert_count = cred_old->cCreds;
break;
case SCH_CREDENTIALS_VERSION:
TRACE("dwVersion = %lu\n", cred->dwVersion);
TRACE("dwCredFormat = %lu\n", cred->dwCredFormat);
TRACE("cCreds = %lu\n", cred->cCreds);
TRACE("paCred = %p\n", cred->paCred);
TRACE("hRootStore = %p\n", cred->hRootStore);
TRACE("cMappers = %lu\n", cred->cMappers);
TRACE("dwSessionLifespan = %lu\n", cred->dwSessionLifespan);
TRACE("dwFlags = %08lx\n", cred->dwFlags);
TRACE("cTlsParameters = %lu:\n", cred->cTlsParameters);
for (i = 0; i < cred->cTlsParameters; i++)
{
TRACE(" cAlpnIds %lu\n", cred->pTlsParameters[i].cAlpnIds);
TRACE(" grbitDisabledProtocols %08lx\n", cred->pTlsParameters[i].grbitDisabledProtocols);
TRACE(" cDisabledCrypto %lu\n", cred->pTlsParameters[i].cDisabledCrypto);
TRACE(" dwFlags %08lx\n", cred->pTlsParameters[i].dwFlags);
}
cert_list = cred->paCred;
cert_count = cred->cCreds;
break;
default:
FIXME("unhandled version %lu\n", cred->dwVersion);
return SEC_E_INTERNAL_ERROR;
}
if (!cred->cCreds) status = SEC_E_NO_CREDENTIALS;
else if (cred->cCreds > 1) status = SEC_E_UNKNOWN_CREDENTIALS;
if (!cert_count) status = SEC_E_NO_CREDENTIALS;
else if (cert_count > 1) status = SEC_E_UNKNOWN_CREDENTIALS;
else
{
DWORD spec;
HCRYPTPROV prov;
BOOL free;
if (CryptAcquireCertificatePrivateKey(cred->paCred[0], CRYPT_ACQUIRE_CACHE_FLAG, NULL, &prov, &spec, &free))
if (CryptAcquireCertificatePrivateKey(cert_list[0], CRYPT_ACQUIRE_CACHE_FLAG, NULL, &prov, &spec, &free))
{
if (free) CryptReleaseContext(prov, 0);
*cert = cred->paCred[0];
*cert = cert_list[0];
status = SEC_E_OK;
}
else status = SEC_E_UNKNOWN_CREDENTIALS;
......@@ -381,6 +410,28 @@ static SECURITY_STATUS get_cert(const SCHANNEL_CRED *cred, CERT_CONTEXT const **
return status;
}
static DWORD get_enabled_protocols(const void *credentials)
{
const SCHANNEL_CRED *cred_old;
const SCH_CREDENTIALS *cred = credentials;
switch (cred->dwVersion)
{
case SCH_CRED_V3:
case SCHANNEL_CRED_VERSION:
cred_old = credentials;
return cred_old->grbitEnabledProtocols;
case SCH_CREDENTIALS_VERSION:
if (cred->cTlsParameters) FIXME("handle TLS parameters\n");
return 0;
default:
FIXME("unhandled version %lu\n", cred->dwVersion);
return 0;
}
}
static WCHAR *get_key_container_path(const CERT_CONTEXT *ctx)
{
CERT_KEY_CONTEXT keyctx;
......@@ -486,11 +537,11 @@ static BYTE *get_key_blob(const CERT_CONTEXT *ctx, DWORD *size)
return ret;
}
static SECURITY_STATUS schan_AcquireClientCredentials(const SCHANNEL_CRED *schanCred,
static SECURITY_STATUS schan_AcquireClientCredentials(const void *schanCred,
PCredHandle phCredential, PTimeStamp ptsExpiry)
{
struct schan_credentials *creds;
unsigned enabled_protocols;
DWORD enabled_protocols, cred_enabled_protocols;
ULONG_PTR handle;
SECURITY_STATUS status = SEC_E_OK;
const CERT_CONTEXT *cert = NULL;
......@@ -509,15 +560,16 @@ static SECURITY_STATUS schan_AcquireClientCredentials(const SCHANNEL_CRED *schan
if (status != SEC_E_OK && status != SEC_E_NO_CREDENTIALS)
return status;
if ((schanCred->grbitEnabledProtocols & tls_protocols) &&
(schanCred->grbitEnabledProtocols & dtls_protocols)) return SEC_E_ALGORITHM_MISMATCH;
cred_enabled_protocols = get_enabled_protocols(schanCred);
if ((cred_enabled_protocols & tls_protocols) &&
(cred_enabled_protocols & dtls_protocols)) return SEC_E_ALGORITHM_MISMATCH;
status = SEC_E_OK;
}
read_config();
if(schanCred && schanCred->grbitEnabledProtocols)
enabled_protocols = schanCred->grbitEnabledProtocols & config_enabled_protocols;
if(schanCred && cred_enabled_protocols)
enabled_protocols = cred_enabled_protocols & config_enabled_protocols;
else
enabled_protocols = config_enabled_protocols & ~config_default_disabled_protocols;
if(!enabled_protocols) {
......
......@@ -25,6 +25,7 @@
#include <stdio.h>
#define SECURITY_WIN32
#include <security.h>
#define SCHANNEL_USE_BLACKLISTS
#include <schannel.h>
#include "wine/test.h"
......@@ -272,6 +273,7 @@ static void testAcquireSecurityContext(void)
SecPkgCredentials_NamesA names;
TimeStamp exp;
SCHANNEL_CRED schanCred;
SCH_CREDENTIALS schCred;
PCCERT_CONTEXT certs[2];
HCRYPTPROV csp;
WCHAR ms_def_prov_w[MAX_PATH];
......@@ -279,7 +281,6 @@ static void testAcquireSecurityContext(void)
HCRYPTKEY key;
CRYPT_KEY_PROV_INFO keyProvInfo;
if (SUCCEEDED(EnumerateSecurityPackagesA(&i, &package_info)))
{
while(i--)
......@@ -545,6 +546,14 @@ static void testAcquireSecurityContext(void)
CryptDestroyKey(key);
}
memset(&schCred, 0, sizeof(schCred));
schCred.dwVersion = SCH_CREDENTIALS_VERSION;
st = AcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND,
NULL, &schCred, NULL, NULL, &cred, NULL);
ok(st == SEC_E_OK || broken(st == SEC_E_UNKNOWN_CREDENTIALS) /* <= win10v1570 */,
"AcquireCredentialsHandleA failed: %08lx\n", st);
FreeCredentialsHandle(&cred);
CryptReleaseContext(csp, 0);
CryptAcquireContextW(&csp, cspNameW, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
......
......@@ -80,6 +80,7 @@ static const WCHAR SCHANNEL_NAME_W[] = { 'S','c','h','a','n','n','e','l',0 };
#define SCH_CRED_VERSION 2
#define SCH_CRED_V3 3
#define SCHANNEL_CRED_VERSION 4
#define SCH_CREDENTIALS_VERSION 5
#define SCHANNEL_RENEGOTIATE 0
#define SCHANNEL_SHUTDOWN 1
......@@ -216,6 +217,54 @@ typedef struct _SCHANNEL_CRED
DWORD dwCredFormat;
} SCHANNEL_CRED, *PSCHANNEL_CRED;
#ifdef SCHANNEL_USE_BLACKLISTS
typedef enum _eTlsAlgorithmUsage
{
TlsParametersCngAlgUsageKeyExchange,
TlsParametersCngAlgUsageSignature,
TlsParametersCngAlgUsageCipher,
TlsParametersCngAlgUsageDigest,
TlsParametersCngAlgUsageCertSig,
} eTlsAlgorithmUsage;
typedef struct _CRYPTO_SETTINGS
{
eTlsAlgorithmUsage eAlgorithmUsage;
UNICODE_STRING strCngAlgId;
DWORD cChainingModes;
PUNICODE_STRING rgstrChainingModes;
DWORD dwMinBitLength;
DWORD dwMaxBitLength;
} CRYPTO_SETTINGS, *PCRYPTO_SETTINGS;
typedef struct _TLS_PARAMETERS
{
DWORD cAlpnIds;
PUNICODE_STRING rgstrAlpnIds;
DWORD grbitDisabledProtocols;
DWORD cDisabledCrypto;
PCRYPTO_SETTINGS pDisabledCrypto;
DWORD dwFlags;
} TLS_PARAMETERS, *PTLS_PARAMETERS;
typedef struct _SCH_CREDENTIALS
{
DWORD dwVersion;
DWORD dwCredFormat;
DWORD cCreds;
PCCERT_CONTEXT *paCred;
HCERTSTORE hRootStore;
DWORD cMappers;
struct _HMAPPER **aphMappers;
DWORD dwSessionLifespan;
DWORD dwFlags;
DWORD cTlsParameters;
PTLS_PARAMETERS pTlsParameters;
} SCH_CREDENTIALS, *PSCH_CREDENTIALS;
#endif
typedef struct _SecPkgCred_SupportedAlgs
{
DWORD cSupportedAlgs;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment