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 @@ -21,6 +21,10 @@ internal static partial class Interop
{
internal static partial class OpenSsl
{
#if DEBUG
private static readonly string? s_keyLogFile = Environment.GetEnvironmentVariable("SSLKEYLOGFILE");
private static readonly FileStream? s_fileStream = s_keyLogFile != null ? File.Open(s_keyLogFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite) : null;
#endif
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";
Expand Down Expand Up @@ -236,6 +240,12 @@ internal static unsafe SafeSslContextHandle AllocateSslContext(SslAuthentication
Ssl.SslCtxSetDefaultOcspCallback(sslCtx);
}
}
#if DEBUG
if (s_fileStream != null)
{
Ssl.SslCtxSetKeylogCallback(sslCtx, &KeyLogCallback);
}
#endif
}
catch
{
Expand Down Expand Up @@ -783,6 +793,23 @@ private static unsafe void RemoveSessionCallback(IntPtr ctx, IntPtr session)
ctxHandle.RemoveSession(name);
}

#if DEBUG
[UnmanagedCallersOnly]
private static unsafe void KeyLogCallback(IntPtr ssl, char* line)
{
Debug.Assert(s_fileStream != null);
ReadOnlySpan<byte> data = MemoryMarshal.CreateReadOnlySpanFromNullTerminated((byte*)line);
if (data.Length > 0)
{
lock (s_fileStream)
{
s_fileStream.Write(data);
s_fileStream.WriteByte((byte)'\n');
}
}
}
#endif

private static int BioRead(SafeBioHandle bio, byte[] buffer, int count)
{
Debug.Assert(buffer != null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ internal static partial class Ssl
[LibraryImport(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);

[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetKeylogCallback")]
internal static unsafe partial void SslCtxSetKeylogCallback(SafeSslContextHandle ctx, delegate* unmanaged<IntPtr, char*, void> callback);

[LibraryImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslCtxSetCaching")]
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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace System.Net.Quic;
internal sealed class MsQuicTlsSecret : IDisposable
{
private static readonly string? s_keyLogFile = Environment.GetEnvironmentVariable("SSLKEYLOGFILE");
private static readonly FileStream? s_fileStream = s_keyLogFile != null ? File.Open(s_keyLogFile, FileMode.Append, FileAccess.Write) : null;
private static readonly FileStream? s_fileStream = s_keyLogFile != null ? File.Open(s_keyLogFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite) : null;
Comment thread
wfurt marked this conversation as resolved.

private unsafe QUIC_TLS_SECRETS* _tlsSecrets;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,12 @@ void local_SSL_set_security_level(SSL* ssl, int32_t level)
(void)level;
}

void local_SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb)
{
(void)ctx;
(void)cb;
}

int local_BIO_up_ref(BIO *bio)
{
if (!bio)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,5 @@ const X509_ALGOR* local_X509_get0_tbs_sigalg(const X509* x509);
X509_PUBKEY* local_X509_get_X509_PUBKEY(const X509* x509);
int32_t local_X509_get_version(const X509* x509);
int32_t local_X509_up_ref(X509* x509);
typedef void (*SSL_CTX_keylog_cb_func)(const SSL *ssl, const char *line);
void local_SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb);
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ static const Entry s_cryptoNative[] =
DllImportEntry(CryptoNative_SslCtxSetCiphers)
DllImportEntry(CryptoNative_SslCtxSetDefaultOcspCallback)
DllImportEntry(CryptoNative_SslCtxSetEncryptionPolicy)
DllImportEntry(CryptoNative_SslCtxSetKeylogCallback)
DllImportEntry(CryptoNative_SetCiphers)
DllImportEntry(CryptoNative_SslCreate)
DllImportEntry(CryptoNative_SslCtxCheckPrivateKey)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len);
LIGHTUP_FUNCTION(SSL_CTX_set_ciphersuites) \
REQUIRED_FUNCTION(SSL_CTX_set_client_cert_cb) \
REQUIRED_FUNCTION(SSL_CTX_set_ex_data) \
FALLBACK_FUNCTION(SSL_CTX_set_keylog_callback) \
REQUIRED_FUNCTION(SSL_CTX_set_quiet_shutdown) \
FALLBACK_FUNCTION(SSL_CTX_set_options) \
FALLBACK_FUNCTION(SSL_CTX_set_security_level) \
Expand Down Expand Up @@ -1005,6 +1006,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define SSL_CTX_set_client_cert_cb SSL_CTX_set_client_cert_cb_ptr
#define SSL_CTX_set_ex_data SSL_CTX_set_ex_data_ptr
#define SSL_CTX_set_options SSL_CTX_set_options_ptr
#define SSL_CTX_set_keylog_callback SSL_CTX_set_keylog_callback_ptr
#define SSL_CTX_set_quiet_shutdown SSL_CTX_set_quiet_shutdown_ptr
#define SSL_CTX_set_security_level SSL_CTX_set_security_level_ptr
#define SSL_CTX_set_session_id_context SSL_CTX_set_session_id_context_ptr
Expand Down Expand Up @@ -1268,6 +1270,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define X509_get_X509_PUBKEY local_X509_get_X509_PUBKEY
#define X509_get_version local_X509_get_version
#define X509_up_ref local_X509_up_ref
#define SSL_CTX_set_keylog_callback local_SSL_CTX_set_keylog_callback

#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_0_2_RTM

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ int X509_set1_notBefore(X509* x509, const ASN1_TIME*);
int32_t X509_up_ref(X509* x509);
const char *SSL_SESSION_get0_hostname(const SSL_SESSION *s);
int SSL_SESSION_set1_hostname(SSL_SESSION *s, const char *hostname);
void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb);

#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_0_2_RTM
int32_t X509_check_host(X509* x509, const char* name, size_t namelen, unsigned int flags, char** peername);
Expand Down
7 changes: 7 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 @@ -1005,6 +1005,13 @@ void CryptoNative_SslSetClientCertCallback(SSL* ssl, int set)
SSL_set_cert_cb(ssl, set ? client_certificate_cb : NULL, NULL);
}

void CryptoNative_SslCtxSetKeylogCallback(SSL_CTX* ctx, SslCtxSetKeylogCallback cb)
{
// void shim functions don't lead to exceptions, so skip the unconditional error clearing.

SSL_CTX_set_keylog_callback(ctx, cb);
}

void CryptoNative_SslSetPostHandshakeAuth(SSL* ssl, int32_t val)
{
#if defined NEED_OPENSSL_1_1 || defined NEED_OPENSSL_3_0
Expand Down
8 changes: 8 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 @@ -124,6 +124,9 @@ typedef int32_t (*SslCtxNewSessionCallback)(SSL* ssl, SSL_SESSION* session);
// the function pointer used for new session
typedef void (*SslCtxRemoveSessionCallback)(SSL_CTX* ctx, SSL_SESSION* session);

// the function pointer for keylog
typedef void (*SslCtxSetKeylogCallback)(const SSL* ssl, const char *line);

/*
Ensures that libssl is correctly initialized and ready to use.
*/
Expand Down Expand Up @@ -164,6 +167,11 @@ Sets session caching. 0 is disabled.
*/
PALEXPORT int CryptoNative_SslCtxSetCaching(SSL_CTX* ctx, int mode, int cacheSize, int contextIdLength, uint8_t* contextId, SslCtxNewSessionCallback newSessionCb, SslCtxRemoveSessionCallback removeSessionCb);

/*
Sets callback to log TLS session keys
*/
PALEXPORT void CryptoNative_SslCtxSetKeylogCallback(SSL_CTX* ctx, SslCtxSetKeylogCallback callback);

/*
Returns name associated with given ssl session.
OpenSSL holds reference to it and it must not be freed.
Expand Down