Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ private static bool DisableTlsResume
// This is helper function to adjust requested protocols based on CipherSuitePolicy and system capability.
private static SslProtocols CalculateEffectiveProtocols(SslAuthenticationOptions sslAuthenticationOptions)
{
SslProtocols protocols = sslAuthenticationOptions.EnabledSslProtocols;
// make sure low bit is not set since we use it in context dictionary to distinguish use with ALPN
Debug.Assert(((int)sslAuthenticationOptions.EnabledSslProtocols & 1) == 0);
SslProtocols protocols = sslAuthenticationOptions.EnabledSslProtocols & ~((SslProtocols)1);

if (!Interop.Ssl.Tls13Supported)
{
Expand Down Expand Up @@ -122,7 +124,7 @@ private static SslProtocols CalculateEffectiveProtocols(SslAuthenticationOptions
}

// 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, SslProtocols protocols, bool enableResume)
{
SafeX509Handle? certHandle = credential.CertHandle;
SafeEvpPKeyHandle? certKeyHandle = credential.CertKeyHandle;
Expand Down Expand Up @@ -181,6 +183,8 @@ internal static SafeSslContextHandle AllocateSslContext(SafeFreeSslCredentials c
// https://www.openssl.org/docs/manmaster/ssl/SSL_shutdown.html
Ssl.SslCtxSetQuietShutdown(sslCtx);

Ssl.SslCtxSetCaching(sslCtx, enableResume ? 1 : 0);

if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.ApplicationProtocols != null && sslAuthenticationOptions.ApplicationProtocols.Count != 0)
{
unsafe
Expand Down Expand Up @@ -222,24 +226,24 @@ internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credentia
SafeSslContextHandle? sslCtxHandle = null;
SafeSslContextHandle? newCtxHandle = null;
SslProtocols protocols = CalculateEffectiveProtocols(sslAuthenticationOptions);
bool hasAlpn = sslAuthenticationOptions.ApplicationProtocols != null && sslAuthenticationOptions.ApplicationProtocols.Count != 0;
bool cacheSslContext = !DisableTlsResume && sslAuthenticationOptions.EncryptionPolicy == EncryptionPolicy.RequireEncryption &&
sslAuthenticationOptions.IsServer &&
sslAuthenticationOptions.CertificateContext != null &&
sslAuthenticationOptions.CertificateContext.SslContexts != null &&
sslAuthenticationOptions.CipherSuitesPolicy == null &&
(!sslAuthenticationOptions.IsServer ||
(sslAuthenticationOptions.ApplicationProtocols != null && sslAuthenticationOptions.ApplicationProtocols.Count != 0));
sslAuthenticationOptions.CipherSuitesPolicy == null;

if (cacheSslContext)
{
sslAuthenticationOptions.CertificateContext!.SslContexts!.TryGetValue(protocols, out sslCtxHandle);
sslAuthenticationOptions.CertificateContext!.SslContexts!.TryGetValue(protocols | (SslProtocols)(hasAlpn ? 1 : 0), out sslCtxHandle);
}

if (sslCtxHandle == null)
{
// We did not get SslContext from cache
sslCtxHandle = newCtxHandle = AllocateSslContext(credential, sslAuthenticationOptions, protocols);
sslCtxHandle = newCtxHandle = AllocateSslContext(credential, sslAuthenticationOptions, protocols, cacheSslContext);

if (cacheSslContext && sslAuthenticationOptions.CertificateContext!.SslContexts!.TryAdd(protocols, newCtxHandle))
if (cacheSslContext && sslAuthenticationOptions.CertificateContext!.SslContexts!.TryAdd(protocols | (SslProtocols)(hasAlpn ? 1 : 0), newCtxHandle))
{
newCtxHandle = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ internal static partial class Ssl
[GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetAlpnSelectCb")]
internal static unsafe partial void SslCtxSetAlpnSelectCb(SafeSslContextHandle ctx, delegate* unmanaged<IntPtr, byte**, byte*, byte*, uint, IntPtr, int> callback, IntPtr arg);

[GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetCaching")]
internal static unsafe partial void SslCtxSetCaching(SafeSslContextHandle ctx, int mode);

internal static bool AddExtraChainCertificates(SafeSslContextHandle ctx, X509Certificate2[] chain)
{
// send pre-computed list of intermediates.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ static const Entry s_cryptoNative[] =
DllImportEntry(CryptoNative_IsSslRenegotiatePending)
DllImportEntry(CryptoNative_IsSslStateOK)
DllImportEntry(CryptoNative_SslCtxAddExtraChainCert)
DllImportEntry(CryptoNative_SslCtxSetCaching)
DllImportEntry(CryptoNative_SslCtxSetCiphers)
DllImportEntry(CryptoNative_SslCtxSetEncryptionPolicy)
DllImportEntry(CryptoNative_SetCiphers)
Expand Down
10 changes: 10 additions & 0 deletions src/native/libs/System.Security.Cryptography.Native/pal_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,16 @@ void CryptoNative_SslSetVerifyPeer(SSL* ssl)
SSL_set_verify(ssl, SSL_VERIFY_PEER, verify_callback);
}

void CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode)
{
// We never reuse same CTX for both client and server
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SESS_CACHE_MODE, mode ? SSL_SESS_CACHE_BOTH : SSL_SESS_CACHE_OFF, NULL);
if (mode == 0)
{
SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
}
}

int32_t CryptoNative_SslCtxSetEncryptionPolicy(SSL_CTX* ctx, EncryptionPolicy policy)
{
switch (policy)
Expand Down
5 changes: 5 additions & 0 deletions src/native/libs/System.Security.Cryptography.Native/pal_ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ Sets the specified protocols in the SSL_CTX options.
*/
PALEXPORT void CryptoNative_SslCtxSetProtocolOptions(SSL_CTX* ctx, SslProtocols protocols);

/*
Sets session caching. 0 is disabled.
*/
PALEXPORT void CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode);

/*
Shims the SSL_new method.

Expand Down