Skip to content

Commit ee93104

Browse files
authoredMay 2, 2024··
Removed unused sessions from SSL_CTX internal cache (#101684)
* Disable OpenSSL internal SSL_SESSION cache for clients * Attempt no. 2 * Revert "Disable OpenSSL internal SSL_SESSION cache for clients" This reverts commit 56a308e.
1 parent fc76b1c commit ee93104

File tree

6 files changed

+40
-11
lines changed

6 files changed

+40
-11
lines changed
 

‎src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ private static unsafe void RemoveSessionCallback(IntPtr ctx, IntPtr session)
748748

749749
IntPtr name = Ssl.SessionGetHostname(session);
750750
Debug.Assert(name != IntPtr.Zero);
751-
ctxHandle.RemoveSession(name);
751+
ctxHandle.RemoveSession(name, session);
752752
}
753753

754754
[UnmanagedCallersOnly]

‎src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.SslCtx.cs

+26-10
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ internal static partial class Ssl
3939
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetCaching")]
4040
internal static unsafe partial int SslCtxSetCaching(SafeSslContextHandle ctx, int mode, int cacheSize, int contextIdLength, Span<byte> contextId, delegate* unmanaged<IntPtr, IntPtr, int> neewSessionCallback, delegate* unmanaged<IntPtr, IntPtr, void> removeSessionCallback);
4141

42+
[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxRemoveSession")]
43+
internal static unsafe partial void SslCtxRemoveSession(SafeSslContextHandle ctx, IntPtr session);
44+
4245
internal static bool AddExtraChainCertificates(SafeSslContextHandle ctx, ReadOnlyCollection<X509Certificate2> chain)
4346
{
4447
// send pre-computed list of intermediates.
@@ -142,27 +145,38 @@ internal bool TryAddSession(IntPtr namePtr, IntPtr session)
142145
// This will use strdup() so it is safe to pass in raw pointer.
143146
Interop.Ssl.SessionSetHostname(session, namePtr);
144147

148+
IntPtr oldSession = IntPtr.Zero;
149+
145150
lock (_sslSessions)
146151
{
147152
if (!_sslSessions.TryAdd(targetName, session))
148153
{
149-
if (_sslSessions.Remove(targetName, out IntPtr oldSession))
150-
{
151-
Interop.Ssl.SessionFree(oldSession);
152-
}
153-
154+
// session to this target host exists, replace it
155+
_sslSessions.Remove(targetName, out oldSession);
154156
bool added = _sslSessions.TryAdd(targetName, session);
155157
Debug.Assert(added);
156158
}
157159
}
158160

161+
if (oldSession != IntPtr.Zero)
162+
{
163+
// remove old session also from the internal OpenSSL cache
164+
// and drop reference count. Since SSL_CTX_remove_session
165+
// will call session_remove_cb, we need to do this outside
166+
// of _sslSessions lock to avoid deadlock with another thread
167+
// which could be holding SSL_CTX lock and trying to acquire
168+
// _sslSessions lock.
169+
Interop.Ssl.SslCtxRemoveSession(this, oldSession);
170+
Interop.Ssl.SessionFree(oldSession);
171+
}
172+
159173
return true;
160174
}
161175

162176
return false;
163177
}
164178

165-
internal void RemoveSession(IntPtr namePtr)
179+
internal void RemoveSession(IntPtr namePtr, IntPtr session)
166180
{
167181
Debug.Assert(_sslSessions != null);
168182

@@ -171,11 +185,14 @@ internal void RemoveSession(IntPtr namePtr)
171185

172186
if (_sslSessions != null && targetName != null)
173187
{
174-
IntPtr oldSession;
175-
bool removed;
188+
IntPtr oldSession = IntPtr.Zero;
189+
bool removed = false;
176190
lock (_sslSessions)
177191
{
178-
removed = _sslSessions.Remove(targetName, out oldSession);
192+
if (_sslSessions.TryGetValue(targetName, out IntPtr existingSession) && existingSession == session)
193+
{
194+
removed = _sslSessions.Remove(targetName, out oldSession);
195+
}
179196
}
180197

181198
if (removed)
@@ -209,7 +226,6 @@ internal bool TrySetSession(SafeSslHandle sslHandle, string name)
209226
// This will increase reference count on the session as needed.
210227
// We need to hold lock here to prevent session being deleted before the call is done.
211228
Interop.Ssl.SslSetSession(sslHandle, session);
212-
213229
return true;
214230
}
215231
}

‎src/native/libs/System.Security.Cryptography.Native/entrypoints.c

+1
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ static const Entry s_cryptoNative[] =
312312
DllImportEntry(CryptoNative_IsSslStateOK)
313313
DllImportEntry(CryptoNative_SslCtxAddExtraChainCert)
314314
DllImportEntry(CryptoNative_SslCtxSetCaching)
315+
DllImportEntry(CryptoNative_SslCtxRemoveSession)
315316
DllImportEntry(CryptoNative_SslCtxSetCiphers)
316317
DllImportEntry(CryptoNative_SslCtxSetDefaultOcspCallback)
317318
DllImportEntry(CryptoNative_SslCtxSetEncryptionPolicy)

‎src/native/libs/System.Security.Cryptography.Native/opensslshim.h

+2
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ int EVP_DigestSqueeze(EVP_MD_CTX *ctx, unsigned char *out, size_t outlen);
555555
REQUIRED_FUNCTION(SSL_CTX_new) \
556556
REQUIRED_FUNCTION(SSL_CTX_sess_set_new_cb) \
557557
REQUIRED_FUNCTION(SSL_CTX_sess_set_remove_cb) \
558+
REQUIRED_FUNCTION(SSL_CTX_remove_session) \
558559
LIGHTUP_FUNCTION(SSL_CTX_set_alpn_protos) \
559560
LIGHTUP_FUNCTION(SSL_CTX_set_alpn_select_cb) \
560561
REQUIRED_FUNCTION(SSL_CTX_set_cipher_list) \
@@ -1083,6 +1084,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
10831084
#define SSL_CTX_new SSL_CTX_new_ptr
10841085
#define SSL_CTX_sess_set_new_cb SSL_CTX_sess_set_new_cb_ptr
10851086
#define SSL_CTX_sess_set_remove_cb SSL_CTX_sess_set_remove_cb_ptr
1087+
#define SSL_CTX_remove_session SSL_CTX_remove_session_ptr
10861088
#define SSL_CTX_set_alpn_protos SSL_CTX_set_alpn_protos_ptr
10871089
#define SSL_CTX_set_alpn_select_cb SSL_CTX_set_alpn_select_cb_ptr
10881090
#define SSL_CTX_set_cipher_list SSL_CTX_set_cipher_list_ptr

‎src/native/libs/System.Security.Cryptography.Native/pal_ssl.c

+5
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,11 @@ int CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode, int cacheSize, int con
701701
return retValue;
702702
}
703703

704+
int CryptoNative_SslCtxRemoveSession(SSL_CTX* ctx, SSL_SESSION* session)
705+
{
706+
return SSL_CTX_remove_session(ctx, session);
707+
}
708+
704709
const char* CryptoNative_SslGetServerName(SSL* ssl)
705710
{
706711
return SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);

‎src/native/libs/System.Security.Cryptography.Native/pal_ssl.h

+5
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ Sets session caching. 0 is disabled.
167167
*/
168168
PALEXPORT int CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode, int cacheSize, int contextIdLength, uint8_t* contextId, SslCtxNewSessionCallback newSessionCb, SslCtxRemoveSessionCallback removeSessionCb);
169169

170+
/*
171+
Removes a session from internal cache.
172+
*/
173+
PALEXPORT int CryptoNative_SslCtxRemoveSession(SSL_CTX* ctx, SSL_SESSION* session);
174+
170175
/*
171176
Sets callback to log TLS session keys
172177
*/

0 commit comments

Comments
 (0)
Please sign in to comment.