Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose TLS details for QUIC connection #93014

Closed
wants to merge 3 commits into from
Closed
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
9 changes: 9 additions & 0 deletions src/libraries/System.Net.Quic/ref/System.Net.Quic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,20 @@ public QuicClientConnectionOptions() { }
public sealed partial class QuicConnection : System.IAsyncDisposable
{
internal QuicConnection() { }
public System.Security.Authentication.CipherAlgorithmType CipherAlgorithm { get { throw null; } }
public int CipherStrength { get { throw null; } }
public System.Security.Authentication.HashAlgorithmType HashAlgorithm { get { throw null; } }
public int HashStrength { get { throw null; } }
public static bool IsSupported { get { throw null; } }
public System.Security.Authentication.ExchangeAlgorithmType KeyExchangeAlgorithm { get { throw null; } }
public int KeyExchangeStrength { get { throw null; } }
public System.Net.IPEndPoint LocalEndPoint { get { throw null; } }
public System.Net.Security.SslApplicationProtocol NegotiatedApplicationProtocol { get { throw null; } }
[System.CLSCompliantAttribute(false)]
public System.Net.Security.TlsCipherSuite NegotiatedCipherSuite { get { throw null; } }
public System.Security.Cryptography.X509Certificates.X509Certificate? RemoteCertificate { get { throw null; } }
public System.Net.IPEndPoint RemoteEndPoint { get { throw null; } }
public System.Security.Authentication.SslProtocols SslProtocol { get { throw null; } }
public string TargetHostName { get { throw null; } }
public System.Threading.Tasks.ValueTask<System.Net.Quic.QuicStream> AcceptInboundStreamAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public System.Threading.Tasks.ValueTask CloseAsync(long errorCode, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
using Microsoft.Quic;
using static Microsoft.Quic.MsQuic;
using static Microsoft.Quic.QUIC_CIPHER_ALGORITHM;
using static Microsoft.Quic.QUIC_CIPHER_SUITE;
using static Microsoft.Quic.QUIC_HASH_ALGORITHM;
using static Microsoft.Quic.QUIC_KEY_EXCHANGE_ALGORITHM;
using static Microsoft.Quic.QUIC_TLS_PROTOCOL_VERSION;

using CONNECTED_DATA = Microsoft.Quic.QUIC_CONNECTION_EVENT._Anonymous_e__Union._CONNECTED_e__Struct;
using LOCAL_ADDRESS_CHANGED_DATA = Microsoft.Quic.QUIC_CONNECTION_EVENT._Anonymous_e__Union._LOCAL_ADDRESS_CHANGED_e__Struct;
using PEER_ADDRESS_CHANGED_DATA = Microsoft.Quic.QUIC_CONNECTION_EVENT._Anonymous_e__Union._PEER_ADDRESS_CHANGED_e__Struct;
Expand Down Expand Up @@ -221,6 +228,40 @@ public X509Certificate? RemoteCertificate
}
}

/// <summary>
/// Gets the <see cref="SslProtocols" /> corresponding to the TLS version used during the connection handshake.
/// </summary>
public SslProtocols SslProtocol { get; private set; }

/// <summary>
/// Gets the cipher suite which was negotiated for this connection.
/// </summary>
[CLSCompliant(false)]
public TlsCipherSuite NegotiatedCipherSuite { get; private set; }

/// <summary>
/// Gets a value that identifies the bulk encryption algorithm used by this connection.
/// </summary>
public CipherAlgorithmType CipherAlgorithm { get; private set; }

/// <summary>
/// Gets a value that identifies the strength of the cipher algorithm used by this connection.
/// </summary>
public int CipherStrength { get; private set; }

//
// defined in SslStream but we don't need it as QUIC uses AEAD which don't use the hash algorithm
// from the cipher suite
//
public HashAlgorithmType HashAlgorithm { get; private set; }
public int HashStrength { get; private set; }

//
// based on SslConnectionInfo.Unix.cs it would return 0/None in all cases
//
public ExchangeAlgorithmType KeyExchangeAlgorithm { get; private set; }
public int KeyExchangeStrength { get; private set; }

/// <summary>
/// Final, negotiated application protocol.
/// </summary>
Expand Down Expand Up @@ -507,6 +548,45 @@ private unsafe int HandleEventConnected(ref CONNECTED_DATA data)
// Final (1-RTT) secrets have been derived, log them if desired to allow decrypting application traffic.
_tlsSecret?.WriteSecret();

QUIC_HANDSHAKE_INFO handshakeInfo = MsQuicHelpers.GetMsQuicParameter<QUIC_HANDSHAKE_INFO>(_handle, QUIC_PARAM_TLS_HANDSHAKE_INFO);

SslProtocol = handshakeInfo.TlsProtocolVersion switch
{
QUIC_TLS_PROTOCOL_VERSION.TLS_1_3 => SslProtocols.Tls13,
_ => SslProtocols.None,
};

CipherAlgorithm = handshakeInfo.CipherAlgorithm switch
{
QUIC_CIPHER_ALGORITHM.AES_128 => CipherAlgorithmType.Aes128,
QUIC_CIPHER_ALGORITHM.AES_256 => CipherAlgorithmType.Aes256,
QUIC_CIPHER_ALGORITHM.CHACHA20 => CipherAlgorithmType.None, // TODO: CipherAlgorithmType.ChaCha20,
_ => CipherAlgorithmType.None,
};
CipherStrength = handshakeInfo.CipherStrength;

HashAlgorithm = handshakeInfo.Hash switch
{
QUIC_HASH_ALGORITHM.SHA_256 => HashAlgorithmType.Sha256,
QUIC_HASH_ALGORITHM.SHA_384 => HashAlgorithmType.Sha384,
_ => HashAlgorithmType.None,
};
HashStrength = handshakeInfo.HashStrength;

KeyExchangeAlgorithm = handshakeInfo.KeyExchangeAlgorithm switch
{
_ => ExchangeAlgorithmType.None,
};
KeyExchangeStrength = handshakeInfo.KeyExchangeStrength;

NegotiatedCipherSuite = handshakeInfo.CipherSuite switch
{
QUIC_CIPHER_SUITE.TLS_AES_128_GCM_SHA256 => TlsCipherSuite.TLS_AES_128_GCM_SHA256,
QUIC_CIPHER_SUITE.TLS_AES_256_GCM_SHA384 => TlsCipherSuite.TLS_AES_256_GCM_SHA384,
QUIC_CIPHER_SUITE.TLS_CHACHA20_POLY1305_SHA256 => TlsCipherSuite.TLS_CHACHA20_POLY1305_SHA256,
_ => TlsCipherSuite.TLS_AES_128_GCM_SHA256,
};

if (NetEventSource.Log.IsEnabled())
{
NetEventSource.Info(this, $"{this} Connection connected {LocalEndPoint} -> {RemoteEndPoint} for {_negotiatedApplicationProtocol} protocol");
Expand Down
Loading