Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
disable TLS resume with CipherSuitePolicy
  • Loading branch information
wfurt committed Aug 16, 2021
commit 9aed0c8681778898460c43fa7a6825351b12d956
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ private static bool DisableTlsResume
}

// This essentially wraps SSL_CTX* aka SSL_CTX_new + setting
internal static SafeSslContextHandle AllocateSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions, SslProtocols protocols)
internal static SafeSslContextHandle AllocateSslContext(SafeFreeSslCredentials credential, SslAuthenticationOptions sslAuthenticationOptions)
{
SafeX509Handle? certHandle = credential.CertHandle;
SafeEvpPKeyHandle? certKeyHandle = credential.CertKeyHandle;

SslProtocols protocols = sslAuthenticationOptions.EnabledSslProtocols;

// Always use SSLv23_method, regardless of protocols. It supports negotiating to the highest
// mutually supported version and can thus handle any of the set protocols, and we then use
Expand All @@ -93,9 +93,47 @@ internal static SafeSslContextHandle AllocateSslContext(SafeFreeSslCredentials c
throw CreateSslException(SR.net_allocate_ssl_context_failed);
}

if (!Interop.Ssl.Tls13Supported)
{
if (protocols != SslProtocols.None &&
CipherSuitesPolicyPal.WantsTls13(protocols))
{
protocols = protocols & (~SslProtocols.Tls13);
}
}
else if (CipherSuitesPolicyPal.WantsTls13(protocols) &&
CipherSuitesPolicyPal.ShouldOptOutOfTls13(sslAuthenticationOptions.CipherSuitesPolicy, sslAuthenticationOptions.EncryptionPolicy))
{
if (protocols == SslProtocols.None)
{
// we are using default settings but cipher suites policy says that TLS 1.3
// is not compatible with our settings (i.e. we requested no encryption or disabled
// all TLS 1.3 cipher suites)
protocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;
}
else
{
// user explicitly asks for TLS 1.3 but their policy is not compatible with TLS 1.3
throw new SslException(
SR.Format(SR.net_ssl_encryptionpolicy_notsupported, sslAuthenticationOptions.EncryptionPolicy));
}
}

if (CipherSuitesPolicyPal.ShouldOptOutOfLowerThanTls13(sslAuthenticationOptions.CipherSuitesPolicy, sslAuthenticationOptions.EncryptionPolicy))
{
if (!CipherSuitesPolicyPal.WantsTls13(protocols))
{
// We cannot provide neither TLS 1.3 or non TLS 1.3, user disabled all cipher suites
throw new SslException(
SR.Format(SR.net_ssl_encryptionpolicy_notsupported, sslAuthenticationOptions.EncryptionPolicy));
}

protocols = SslProtocols.Tls13;
}

// Configure allowed protocols. It's ok to use DangerousGetHandle here without AddRef/Release as we just
// create the handle, it's rooted by the using, no one else has a reference to it, etc.
Ssl.SetProtocolOptions(innerContext, protocols);
Ssl.SslCtxSetProtocolOptions(innerContext, protocols);

if (sslAuthenticationOptions.EncryptionPolicy != EncryptionPolicy.RequireEncryption)
{
Expand All @@ -106,6 +144,29 @@ internal static SafeSslContextHandle AllocateSslContext(SafeFreeSslCredentials c
}
}

byte[]? cipherList =
CipherSuitesPolicyPal.GetOpenSslCipherList(sslAuthenticationOptions.CipherSuitesPolicy, protocols, sslAuthenticationOptions.EncryptionPolicy);

Debug.Assert(cipherList == null || (cipherList.Length >= 1 && cipherList[cipherList.Length - 1] == 0));

byte[]? cipherSuites =
CipherSuitesPolicyPal.GetOpenSslCipherSuites(sslAuthenticationOptions.CipherSuitesPolicy, protocols, sslAuthenticationOptions.EncryptionPolicy);

Debug.Assert(cipherSuites == null || (cipherSuites.Length >= 1 && cipherSuites[cipherSuites.Length - 1] == 0));

unsafe
{
fixed (byte* cipherListStr = cipherList)
fixed (byte* cipherSuitesStr = cipherSuites)
{
if (!Ssl.SslCtxSetCiphers(innerContext, cipherListStr, cipherSuitesStr))
{
Crypto.ErrClearError();
throw new PlatformNotSupportedException(SR.Format(SR.net_ssl_encryptionpolicy_notsupported, sslAuthenticationOptions.EncryptionPolicy));
}
}
}

// The logic in SafeSslHandle.Disconnect is simple because we are doing a quiet
// shutdown (we aren't negotiating for session close to enable later session
// restoration).
Expand Down Expand Up @@ -150,6 +211,7 @@ internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credentia
SafeSslContextHandle? innerContext = null;
SslProtocols protocols = sslAuthenticationOptions.EnabledSslProtocols;
bool cacheSslContext = !DisableTlsResume && sslAuthenticationOptions.EncryptionPolicy == EncryptionPolicy.RequireEncryption &&
sslAuthenticationOptions.CipherSuitesPolicy == null &&
(!sslAuthenticationOptions.IsServer ||
(sslAuthenticationOptions.ApplicationProtocols != null && sslAuthenticationOptions.ApplicationProtocols.Count != 0));

Expand Down Expand Up @@ -199,7 +261,7 @@ internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credentia
if (sslCtx == null)
{
// We did not get SslContext from cache
sslCtx = innerContext = AllocateSslContext(credential, sslAuthenticationOptions, protocols);
sslCtx = innerContext = AllocateSslContext(credential, sslAuthenticationOptions);
}

try
Expand Down Expand Up @@ -230,6 +292,7 @@ internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credentia
{
alpnHandle = GCHandle.Alloc(sslAuthenticationOptions.ApplicationProtocols);
Interop.Ssl.SslSetData(context, GCHandle.ToIntPtr(alpnHandle));
context.AlpnHandle = alpnHandle;
}
else
{
Expand All @@ -252,29 +315,6 @@ internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credentia
}
}

byte[]? cipherList =
CipherSuitesPolicyPal.GetOpenSslCipherList(sslAuthenticationOptions.CipherSuitesPolicy, protocols, sslAuthenticationOptions.EncryptionPolicy);

Debug.Assert(cipherList == null || (cipherList.Length >= 1 && cipherList[cipherList.Length - 1] == 0));

byte[]? cipherSuites =
CipherSuitesPolicyPal.GetOpenSslCipherSuites(sslAuthenticationOptions.CipherSuitesPolicy, protocols, sslAuthenticationOptions.EncryptionPolicy);

Debug.Assert(cipherSuites == null || (cipherSuites.Length >= 1 && cipherSuites[cipherSuites.Length - 1] == 0));

unsafe
{
fixed (byte* cipherListStr = cipherList)
fixed (byte* cipherSuitesStr = cipherSuites)
{
if (!Ssl.SslSetCiphers(context, cipherListStr, cipherSuitesStr))
{
Crypto.ErrClearError();
throw new PlatformNotSupportedException(SR.Format(SR.net_ssl_encryptionpolicy_notsupported, sslAuthenticationOptions.EncryptionPolicy));
}
}
}

if (sslAuthenticationOptions.CertificateContext != null && sslAuthenticationOptions.CertificateContext.IntermediateCertificates.Length > 0)
{
if (!Ssl.AddExtraChainCertificates(context, sslAuthenticationOptions.CertificateContext!.IntermediateCertificates))
Expand All @@ -283,9 +323,6 @@ internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credentia
}
}

context.AlpnHandle = alpnHandle;


if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.RemoteCertRequired)
{
unsafe
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ internal static partial class Interop
{
internal static partial class Ssl
{
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SetProtocolOptions")]
internal static extern void SetProtocolOptions(IntPtr ctx, SslProtocols protocols);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetProtocolOptions")]
internal static extern void SslCtxSetProtocolOptions(IntPtr ctx, SslProtocols protocols);

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SetProtocolOptions")]
internal static extern void SetProtocolOptions(SafeSslContextHandle ctx, SslProtocols protocols);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetProtocolOptions")]
internal static extern void SslCtxSetProtocolOptions(SafeSslContextHandle ctx, SslProtocols protocols);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -290,14 +290,14 @@ static const Entry s_cryptoNative[] =
DllImportEntry(CryptoNative_SslCtxSetCiphers)
DllImportEntry(CryptoNative_SslCtxSetEncryptionPolicy)
DllImportEntry(CryptoNative_SetCiphers)
DllImportEntry(CryptoNative_SetProtocolOptions)
DllImportEntry(CryptoNative_SslAddExtraChainCert)
DllImportEntry(CryptoNative_SslCreate)
DllImportEntry(CryptoNative_SslCtxCheckPrivateKey)
DllImportEntry(CryptoNative_SslCtxCreate)
DllImportEntry(CryptoNative_SslCtxDestroy)
DllImportEntry(CryptoNative_SslCtxSetAlpnProtos)
DllImportEntry(CryptoNative_SslCtxSetAlpnSelectCb)
DllImportEntry(CryptoNative_SslCtxSetProtocolOptions)
DllImportEntry(CryptoNative_SslCtxSetQuietShutdown)
DllImportEntry(CryptoNative_SslCtxSetVerify)
DllImportEntry(CryptoNative_SslCtxUseCertificate)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,22 +231,7 @@ static void ResetCtxProtocolRestrictions(SSL_CTX* ctx)
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, 0, NULL);
}

/*
static void ResetProtocolRestrictions(SSL* ssl)
{
#ifndef SSL_CTRL_SET_MIN_PROTO_VERSION
#define SSL_CTRL_SET_MIN_PROTO_VERSION 123
#endif
#ifndef SSL_CTRL_SET_MAX_PROTO_VERSION
#define SSL_CTRL_SET_MAX_PROTO_VERSION 124
#endif

SSL_ctrl(ssl, SSL_CTRL_SET_MIN_PROTO_VERSION, 0, NULL);
SSL_ctrl(ssl, SSL_CTRL_SET_MAX_PROTO_VERSION, 0, NULL);
}
*/

void CryptoNative_SetProtocolOptions(SSL_CTX* ctx, SslProtocols protocols)
void CryptoNative_SslCtxSetProtocolOptions(SSL_CTX* ctx, SslProtocols protocols)
{
// Ensure that ECDHE is available
if (TrySetECDHNamedCurve(ctx) == 0)
Expand Down Expand Up @@ -490,12 +475,6 @@ void CryptoNative_SslSetVerifyPeer(SSL* ssl)
SSL_set_verify(ssl, SSL_VERIFY_PEER, verify_callback);
}

//void
//CryptoNative_SslCtxSetCertVerifyCallback(SSL_CTX* ctx, SslCtxSetCertVerifyCallbackCallback callback, void* arg)
//{
// SSL_CTX_set_cert_verify_callback(ctx, callback, arg);
//}

int32_t CryptoNative_SslCtxSetEncryptionPolicy(SSL_CTX* ctx, EncryptionPolicy policy)
{
switch (policy)
Expand Down Expand Up @@ -821,8 +800,8 @@ int32_t CryptoNative_OpenSslGetProtocolSupport(SslProtocols protocol)

if (clientCtx != NULL && serverCtx != NULL && cert != NULL && evp != NULL && bio1 != NULL && bio2 != NULL)
{
CryptoNative_SetProtocolOptions(serverCtx, protocol);
CryptoNative_SetProtocolOptions(clientCtx, protocol);
CryptoNative_SslCtxSetProtocolOptions(serverCtx, protocol);
CryptoNative_SslCtxSetProtocolOptions(clientCtx, protocol);
SSL_CTX_set_verify(clientCtx, SSL_VERIFY_NONE, NULL);
SSL_CTX_set_verify(serverCtx, SSL_VERIFY_NONE, NULL);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ PALEXPORT SSL_CTX* CryptoNative_SslCtxCreate(const SSL_METHOD* method);
/*
Sets the specified protocols in the SSL_CTX options.
*/
PALEXPORT void CryptoNative_SetProtocolOptions(SSL_CTX* ctx, SslProtocols protocols);
PALEXPORT void CryptoNative_SslCtxSetProtocolOptions(SSL_CTX* ctx, SslProtocols protocols);

/*
Shims the SSL_new method.
Expand Down