Skip to content

Commit bfaf24e

Browse files
[release/8.0] Removed unused sessions from SSL_CTX internal cache (#102095)
* Disable OpenSSL internal SSL_SESSION cache for clients * Attempt no. 2 * Revert "Disable OpenSSL internal SSL_SESSION cache for clients" This reverts commit 56a308e. --------- Co-authored-by: Radek Zikmund <[email protected]>
1 parent ca28411 commit bfaf24e

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ private static unsafe void RemoveSessionCallback(IntPtr ctx, IntPtr session)
787787

788788
IntPtr name = Ssl.SessionGetHostname(session);
789789
Debug.Assert(name != IntPtr.Zero);
790-
ctxHandle.RemoveSession(name);
790+
ctxHandle.RemoveSession(name, session);
791791
}
792792

793793
#if DEBUG

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

Lines changed: 26 additions & 10 deletions
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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ static const Entry s_cryptoNative[] =
299299
DllImportEntry(CryptoNative_IsSslStateOK)
300300
DllImportEntry(CryptoNative_SslCtxAddExtraChainCert)
301301
DllImportEntry(CryptoNative_SslCtxSetCaching)
302+
DllImportEntry(CryptoNative_SslCtxRemoveSession)
302303
DllImportEntry(CryptoNative_SslCtxSetCiphers)
303304
DllImportEntry(CryptoNative_SslCtxSetDefaultOcspCallback)
304305
DllImportEntry(CryptoNative_SslCtxSetEncryptionPolicy)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len);
525525
REQUIRED_FUNCTION(SSL_CTX_new) \
526526
REQUIRED_FUNCTION(SSL_CTX_sess_set_new_cb) \
527527
REQUIRED_FUNCTION(SSL_CTX_sess_set_remove_cb) \
528+
REQUIRED_FUNCTION(SSL_CTX_remove_session) \
528529
LIGHTUP_FUNCTION(SSL_CTX_set_alpn_protos) \
529530
LIGHTUP_FUNCTION(SSL_CTX_set_alpn_select_cb) \
530531
REQUIRED_FUNCTION(SSL_CTX_set_cipher_list) \
@@ -1040,6 +1041,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
10401041
#define SSL_CTX_new SSL_CTX_new_ptr
10411042
#define SSL_CTX_sess_set_new_cb SSL_CTX_sess_set_new_cb_ptr
10421043
#define SSL_CTX_sess_set_remove_cb SSL_CTX_sess_set_remove_cb_ptr
1044+
#define SSL_CTX_remove_session SSL_CTX_remove_session_ptr
10431045
#define SSL_CTX_set_alpn_protos SSL_CTX_set_alpn_protos_ptr
10441046
#define SSL_CTX_set_alpn_select_cb SSL_CTX_set_alpn_select_cb_ptr
10451047
#define SSL_CTX_set_cipher_list SSL_CTX_set_cipher_list_ptr

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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 5 additions & 0 deletions
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)