Skip to content

Instantly share code, notes, and snippets.

@rzikm
Last active October 4, 2023 16:38
Show Gist options
  • Save rzikm/a14563740bb20aa866b6dd1607421830 to your computer and use it in GitHub Desktop.
Save rzikm/a14563740bb20aa866b6dd1607421830 to your computer and use it in GitHub Desktop.
[API Proposal] QuicConnection TLS details

Background and motivation

ASP.NET Core has an ITlsHandshakeFeature type that a dev can use to get information about the TLS connection. We want to support it for HTTP/3: today HTTP/3 only runs on TLS 1.3, but it'll eventually also run on whatever comes after TLS 1.3 and there needs to be a way for people to get that information.

We (asp.net core team) think that this has been discussed and brought up before but I couldn't find an issue in runtime for exposing this information. Tracking in asp.net core: dotnet/aspnetcore#35039. This doesn't block HTTP/3 for us in .NET 7 but will eventually need to be done.

API Proposal (edited by @rzikm)

The proposed API copies that of SslStream.

public class QuicConnection
{
    //
    // Version of TLS used for the handshake, currently expected to always return Tls13
    //
    public SslProtocols SslProtocol { get; }

    //
    // currently, QUIC allows negotiating only following TLS 1.3 ciphers
    // - TLS_AES_128_GCM_SHA256 = 0x1301, // rfc8446
    // - TLS_AES_256_GCM_SHA384 = 0x1302, // rfc8446
    // - TLS_CHACHA20_POLY1305_SHA256 = 0x1303, // rfc8446
    // - TLS_AES_128_CCM_SHA256 = 0x1304, // rfc8446
    // 
    [CLSCompliant(false)]
    public TlsCipherSuite NegotiatedCipherSuite { get; }

    // based on the above, currently expected to return
    // - Aes128
    // - Aes256
    // - None (for ChaCha20Poly1305) = based on SslConnectionInfo.Unix.cs, we probably don't have appropriate member for that. We can enhance CipherAlgorithmType enum in another proposal.
    public CipherAlgorithmType CipherAlgorithm { get; }

    // based on the above, expected to return
    // - 128 (Aes128)
    // - 256 (Aes256 and ChaCha20Poly1305)
    public int CipherStrength { get; }
    
    //
    // defined in SslStream but don't make that much sense as QUIC does not use the HashAlgorithm during encryption (it uses AEAD of version of the CipherAlgorithm which don't use the hash algorithm
    // from the cipher suite), and it would only be reported because it was part of the negotiated cipher suite
    //
    public HashAlgorithmType HashAlgorithm { get; }
    // MsQuic currently returns always 0 for all ciphers, and same behavior is on SslStream as well on the cipers above (based on SslConnectionInfo.Unix.cs)
    public int HashStrength { get; }

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

API Usage

await using var connection = await listener.AcceptConnectionAsync();

Console.WriteLine($"connection.NegotiatedCipherSuite: {connection.NegotiatedCipherSuite}");
Console.WriteLine($"connection.CipherAlgorithm: {connection.CipherAlgorithm}");
Console.WriteLine($"connection.CipherStrength: {connection.CipherStrength}");
Console.WriteLine($"connection.HashAlgorithm: {connection.HashAlgorithm}");
Console.WriteLine($"connection.HashStrength: {connection.HashStrength}");
Console.WriteLine($"connection.KeyExchangeAlgorithm: {connection.KeyExchangeAlgorithm}");
Console.WriteLine($"connection.KeyExchangeStrength: {connection.KeyExchangeStrength}");

Potential output:

connection.NegotiatedCipherSuite: TLS_AES_256_GCM_SHA384
connection.CipherAlgorithm: Aes256
connection.CipherStrength: 256
connection.HashAlgorithm: Sha384
connection.HashStrength: 0
connection.KeyExchangeAlgorithm: None
connection.KeyExchangeStrength: 0

Alternative Designs

Put all the properties on a new class QuicConnectionInfo instead of directly on QuicConnection. This would be inconsistent with SslStream, and would impose an extra allocation. Furthermore, we already have NegotiatedApplicationProtocol on QuicConnection so it would be inconsistent to have some properties on QuicConnection and some on QuicConnectionInfo.

Risks

no response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment