From 7a951c4a2be796a059316200aa09ae03365981f4 Mon Sep 17 00:00:00 2001 From: wfurt Date: Mon, 9 May 2022 09:48:41 -0700 Subject: [PATCH] add option to set TLS cache size --- .../Interop.OpenSsl.cs | 26 ++++++++++++++++--- .../Interop.SslCtx.cs | 2 +- .../pal_ssl.c | 6 ++++- .../pal_ssl.h | 2 +- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index 43af210c122dd5..a3e872fe049627 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -22,6 +22,8 @@ internal static partial class OpenSsl { private const string DisableTlsResumeCtxSwitch = "System.Net.Security.DisableTlsResume"; private const string DisableTlsResumeEnvironmentVariable = "DOTNET_SYSTEM_NET_SECURITY_DISABLETLSRESUME"; + private const string TlsCacheSizeCtxName = "System.Net.Security.TlsCacheSize"; + private const string TlsCacheSizeEnvironmentVariable = "DOTNET_SYSTEM_NET_SECURITY_TLSCACHESIZE"; private const SslProtocols FakeAlpnSslProtocol = (SslProtocols)1; // used to distinguish server sessions with ALPN private static readonly IdnMapping s_idnMapping = new IdnMapping(); private static readonly ConcurrentDictionary s_clientSslContexts = new ConcurrentDictionary(); @@ -50,6 +52,8 @@ internal static partial class OpenSsl return bindingHandle; } + private static int s_cacheSize = GetCacheSize(); + private static volatile int s_disableTlsResume = -1; private static bool DisableTlsResume @@ -79,6 +83,22 @@ private static bool DisableTlsResume } } + private static int GetCacheSize() + { + int cacheSize = -1; + string? value = AppContext.GetData(TlsCacheSizeCtxName) as string ?? Environment.GetEnvironmentVariable(TlsCacheSizeEnvironmentVariable); + try + { + if (value != null) + { + cacheSize = int.Parse(value); + } + } + catch { }; + + return cacheSize; + } + // This is helper function to adjust requested protocols based on CipherSuitePolicy and system capability. private static SslProtocols CalculateEffectiveProtocols(SslAuthenticationOptions sslAuthenticationOptions) { @@ -186,18 +206,18 @@ internal static unsafe SafeSslContextHandle AllocateSslContext(SafeFreeSslCreden { if (sslAuthenticationOptions.IsServer) { - Ssl.SslCtxSetCaching(sslCtx, 1, null, null); + Ssl.SslCtxSetCaching(sslCtx, 1, s_cacheSize, null, null); } else { - int result = Ssl.SslCtxSetCaching(sslCtx, 1, &NewSessionCallback, &RemoveSessionCallback); + int result = Ssl.SslCtxSetCaching(sslCtx, 1, s_cacheSize, &NewSessionCallback, &RemoveSessionCallback); Debug.Assert(result == 1); sslCtx.EnableSessionCache(); } } else { - Ssl.SslCtxSetCaching(sslCtx, 0, null, null); + Ssl.SslCtxSetCaching(sslCtx, 0, -1, null, null); } if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.ApplicationProtocols != null && sslAuthenticationOptions.ApplicationProtocols.Count != 0) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs index 1c36f62bbbe9a1..024cac300ffc78 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs @@ -33,7 +33,7 @@ internal static partial class Ssl internal static unsafe partial void SslCtxSetAlpnSelectCb(SafeSslContextHandle ctx, delegate* unmanaged callback, IntPtr arg); [LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetCaching")] - internal static unsafe partial int SslCtxSetCaching(SafeSslContextHandle ctx, int mode, delegate* unmanaged neewSessionCallback, delegate* unmanaged removeSessionCallback); + internal static unsafe partial int SslCtxSetCaching(SafeSslContextHandle ctx, int mode, int cacheSize, delegate* unmanaged neewSessionCallback, delegate* unmanaged removeSessionCallback); internal static bool AddExtraChainCertificates(SafeSslContextHandle ctx, X509Certificate2[] chain) { diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c index 119ca4a4e2aecd..25a8d5433b334d 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c @@ -649,7 +649,7 @@ void CryptoNative_SslSetVerifyPeer(SSL* ssl) SSL_set_verify(ssl, SSL_VERIFY_PEER, verify_callback); } -int CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode, SslCtxNewSessionCallback newSessionCb, SslCtxRemoveSessionCallback removeSessionCb) +int CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode, int cacheSize, SslCtxNewSessionCallback newSessionCb, SslCtxRemoveSessionCallback removeSessionCb) { int retValue = 1; if (mode && !API_EXISTS(SSL_SESSION_get0_hostname)) @@ -672,6 +672,10 @@ int CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode, SslCtxNewSessionCallba { SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET); } + else if (cacheSize >= 0) + { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SESS_CACHE_SIZE, (long)cacheSize, NULL); + } if (newSessionCb != NULL) { diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h index e88eb18444854e..2a6cb9881ee549 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h @@ -162,7 +162,7 @@ PALEXPORT void CryptoNative_SslSetPostHandshakeAuth(SSL* ssl, int32_t val); /* Sets session caching. 0 is disabled. */ -PALEXPORT int CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode, SslCtxNewSessionCallback newCb, SslCtxRemoveSessionCallback removeCb); +PALEXPORT int CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode, int cacheSize, SslCtxNewSessionCallback newCb, SslCtxRemoveSessionCallback removeCb); /* Returns name associated with given ssl session.