From b829858de0e00dd22fb7f4857e598c85649ef145 Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Mon, 28 Mar 2022 16:24:39 +0200 Subject: [PATCH 1/4] Add CipherSuitesPolicy support for MsQuic --- .../src/Resources/Strings.resx | 3 ++ .../MsQuic/Interop/MsQuicEnums.cs | 10 ++++ .../MsQuic/Interop/MsQuicNativeMethods.cs | 6 ++- .../Interop/SafeMsQuicConfigurationHandle.cs | 52 +++++++++++++++---- .../MsQuic/MsQuicConnection.cs | 2 +- .../Implementations/MsQuic/MsQuicListener.cs | 1 + 6 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Net.Quic/src/Resources/Strings.resx b/src/libraries/System.Net.Quic/src/Resources/Strings.resx index f1e227448e030a..d8c87fc8e44c6f 100644 --- a/src/libraries/System.Net.Quic/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Quic/src/Resources/Strings.resx @@ -165,5 +165,8 @@ The application protocol list is invalid. + + QUIC does not support '{0}' cipher suite. + diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicEnums.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicEnums.cs index 190275ebbda3c6..d9aa1ec901791a 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicEnums.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicEnums.cs @@ -34,9 +34,19 @@ internal enum QUIC_CREDENTIAL_FLAGS : uint DEFER_CERTIFICATE_VALIDATION = 0x00000020, // Schannel only currently. REQUIRE_CLIENT_AUTHENTICATION = 0x00000040, // Schannel only currently. USE_TLS_BUILTIN_CERTIFICATE_VALIDATION = 0x00000080, + SET_ALLOWED_CIPHER_SUITES = 0x00002000, USE_PORTABLE_CERTIFICATES = 0x00004000, } + [Flags] + internal enum QUIC_ALLOWED_CIPHER_SUITE_FLAGS : uint + { + NONE = 0x0, + AES_128_GCM_SHA256 = 0x1, + AES_256_GCM_SHA384 = 0x2, + CHACHA20_POLY1305_SHA256 = 0x4, + } + internal enum QUIC_CERTIFICATE_HASH_STORE_FLAGS { QUIC_CERTIFICATE_HASH_STORE_FLAG_NONE = 0x0000, diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs index 1327c5a1030c59..4b70aea4cea1d4 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs @@ -250,6 +250,7 @@ internal struct CredentialConfig internal IntPtr Reserved; // Currently unused // TODO: define delegate for AsyncHandler and make proper use of it. internal IntPtr AsyncHandler; + internal QUIC_ALLOWED_CIPHER_SUITE_FLAGS AllowedCipherSuites; [CustomTypeMarshaller(typeof(CredentialConfig), Features = CustomTypeMarshallerFeatures.UnmanagedResources)] [StructLayout(LayoutKind.Sequential)] @@ -262,6 +263,7 @@ public struct Native internal IntPtr Principal; internal IntPtr Reserved; internal IntPtr AsyncHandler; + internal QUIC_ALLOWED_CIPHER_SUITE_FLAGS AllowedCipherSuites; public Native(CredentialConfig managed) { @@ -271,6 +273,7 @@ public Native(CredentialConfig managed) Principal = Marshal.StringToCoTaskMemUTF8(managed.Principal); Reserved = managed.Reserved; AsyncHandler = managed.AsyncHandler; + AllowedCipherSuites = managed.AllowedCipherSuites; } public CredentialConfig ToManaged() @@ -282,7 +285,8 @@ public CredentialConfig ToManaged() Certificate = Certificate, Principal = Marshal.PtrToStringUTF8(Principal)!, Reserved = Reserved, - AsyncHandler = AsyncHandler + AsyncHandler = AsyncHandler, + AllowedCipherSuites = AllowedCipherSuites }; } diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs index 21118d870f36c0..8ad8b9ff9a2655 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs @@ -39,11 +39,6 @@ public static SafeMsQuicConfigurationHandle Create(QuicClientConnectionOptions o if (options.ClientAuthenticationOptions != null) { - if (options.ClientAuthenticationOptions.CipherSuitesPolicy != null) - { - throw new PlatformNotSupportedException(SR.Format(SR.net_quic_ssl_option, nameof(options.ClientAuthenticationOptions.CipherSuitesPolicy))); - } - #pragma warning disable SYSLIB0040 // NoEncryption and AllowNoEncryption are obsolete if (options.ClientAuthenticationOptions.EncryptionPolicy == EncryptionPolicy.NoEncryption) { @@ -69,7 +64,7 @@ public static SafeMsQuicConfigurationHandle Create(QuicClientConnectionOptions o } } - return Create(options, QUIC_CREDENTIAL_FLAGS.CLIENT, certificate: certificate, certificateContext: null, options.ClientAuthenticationOptions?.ApplicationProtocols); + return Create(options, QUIC_CREDENTIAL_FLAGS.CLIENT, certificate: certificate, certificateContext: null, options.ClientAuthenticationOptions?.ApplicationProtocols, options.ClientAuthenticationOptions?.CipherSuitesPolicy); } public static SafeMsQuicConfigurationHandle Create(QuicOptions options, SslServerAuthenticationOptions? serverAuthenticationOptions, string? targetHost = null) @@ -102,12 +97,12 @@ public static SafeMsQuicConfigurationHandle Create(QuicOptions options, SslServe } } - return Create(options, flags, certificate, serverAuthenticationOptions?.ServerCertificateContext, serverAuthenticationOptions?.ApplicationProtocols); + return Create(options, flags, certificate, serverAuthenticationOptions?.ServerCertificateContext, serverAuthenticationOptions?.ApplicationProtocols, serverAuthenticationOptions?.CipherSuitesPolicy); } // TODO: this is called from MsQuicListener and when it fails it wreaks havoc in MsQuicListener finalizer. // Consider moving bigger logic like this outside of constructor call chains. - private static unsafe SafeMsQuicConfigurationHandle Create(QuicOptions options, QUIC_CREDENTIAL_FLAGS flags, X509Certificate? certificate, SslStreamCertificateContext? certificateContext, List? alpnProtocols) + private static unsafe SafeMsQuicConfigurationHandle Create(QuicOptions options, QUIC_CREDENTIAL_FLAGS flags, X509Certificate? certificate, SslStreamCertificateContext? certificateContext, List? alpnProtocols, CipherSuitesPolicy? cipherSuitesPolicy) { // TODO: some of these checks should be done by the QuicOptions type. if (alpnProtocols == null || alpnProtocols.Count == 0) @@ -191,10 +186,16 @@ private static unsafe SafeMsQuicConfigurationHandle Create(QuicOptions options, CredentialConfig config = default; config.Flags = flags; // TODO: consider using LOAD_ASYNCHRONOUS with a callback. + if (cipherSuitesPolicy != null) + { + config.Flags |= QUIC_CREDENTIAL_FLAGS.SET_ALLOWED_CIPHER_SUITES; + config.AllowedCipherSuites = CipherSuitePolicyToFlags(cipherSuitesPolicy); + } + if (certificateContext != null) { - certificate = (X509Certificate2?) _contextCertificate.GetValue(certificateContext); - intermediates = (X509Certificate2[]?) _contextChain.GetValue(certificateContext); + certificate = (X509Certificate2?)_contextCertificate.GetValue(certificateContext); + intermediates = (X509Certificate2[]?)_contextChain.GetValue(certificateContext); if (certificate == null || intermediates == null) { @@ -219,7 +220,7 @@ private static unsafe SafeMsQuicConfigurationHandle Create(QuicOptions options, { X509Certificate2Collection collection = new X509Certificate2Collection(); collection.Add(certificate); - for (int i= 0; i < intermediates?.Length; i++) + for (int i = 0; i < intermediates?.Length; i++) { collection.Add(intermediates[i]); } @@ -259,5 +260,34 @@ private static unsafe SafeMsQuicConfigurationHandle Create(QuicOptions options, return configurationHandle; } + + private static QUIC_ALLOWED_CIPHER_SUITE_FLAGS CipherSuitePolicyToFlags(CipherSuitesPolicy cipherSuitesPolicy) + { + QUIC_ALLOWED_CIPHER_SUITE_FLAGS flags = QUIC_ALLOWED_CIPHER_SUITE_FLAGS.NONE; + + foreach (TlsCipherSuite cipher in cipherSuitesPolicy.AllowedCipherSuites) + { + switch (cipher) + { + case TlsCipherSuite.TLS_AES_128_GCM_SHA256: + flags |= QUIC_ALLOWED_CIPHER_SUITE_FLAGS.AES_128_GCM_SHA256; + break; + case TlsCipherSuite.TLS_AES_256_GCM_SHA384: + flags |= QUIC_ALLOWED_CIPHER_SUITE_FLAGS.AES_256_GCM_SHA384; + break; + case TlsCipherSuite.TLS_CHACHA20_POLY1305_SHA256: + flags |= QUIC_ALLOWED_CIPHER_SUITE_FLAGS.CHACHA20_POLY1305_SHA256; + break; + case TlsCipherSuite.TLS_AES_128_CCM_SHA256: + // Not supported by MsQuic, but QUIC RFC allows it. + // TODO: should we throw as well? + break; + default: + throw new ArgumentException(SR.Format(SR.net_quic_unsupported_cipher_suite, cipher)); + } + } + + return flags; + } } } diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs index c8f4bb9361939e..bcdaeaa7998ddc 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs @@ -389,7 +389,7 @@ private static uint HandleEventStreamsAvailable(State state, ref ConnectionEvent private static uint HandleEventPeerCertificateReceived(State state, ref ConnectionEvent connectionEvent) { - SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None; + SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None; X509Chain? chain = null; X509Certificate2? certificate = null; X509Certificate2Collection? additionalCertificates = null; diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicListener.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicListener.cs index 71f19c29c29986..40f1df8b00b43e 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicListener.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicListener.cs @@ -56,6 +56,7 @@ public State(QuicListenerOptions options) AuthenticationOptions.RemoteCertificateValidationCallback = options.ServerAuthenticationOptions.RemoteCertificateValidationCallback; AuthenticationOptions.ServerCertificateSelectionCallback = options.ServerAuthenticationOptions.ServerCertificateSelectionCallback; AuthenticationOptions.ApplicationProtocols = options.ServerAuthenticationOptions.ApplicationProtocols; + AuthenticationOptions.CipherSuitesPolicy = options.ServerAuthenticationOptions.CipherSuitesPolicy; if (options.ServerAuthenticationOptions.ServerCertificate == null && options.ServerAuthenticationOptions.ServerCertificateContext == null && options.ServerAuthenticationOptions.ServerCertificateSelectionCallback != null) From 7dd85151c328c837456073a1c313839cb24cd236 Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Mon, 28 Mar 2022 17:58:11 +0200 Subject: [PATCH 2/4] Add tests --- .../src/Resources/Strings.resx | 3 + .../Interop/SafeMsQuicConfigurationHandle.cs | 13 ++-- .../MsQuicCipherSuitesPolicyTests.cs | 67 +++++++++++++++++++ .../tests/FunctionalTests/QuicTestBase.cs | 2 +- 4 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs diff --git a/src/libraries/System.Net.Quic/src/Resources/Strings.resx b/src/libraries/System.Net.Quic/src/Resources/Strings.resx index d8c87fc8e44c6f..d7ce6c7a662f37 100644 --- a/src/libraries/System.Net.Quic/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Quic/src/Resources/Strings.resx @@ -168,5 +168,8 @@ QUIC does not support '{0}' cipher suite. + + CipherSuitePolicy must specify at least one cipher supported by QUIC. + diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs index 8ad8b9ff9a2655..729af09dc097a3 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs @@ -74,11 +74,6 @@ public static SafeMsQuicConfigurationHandle Create(QuicOptions options, SslServe if (serverAuthenticationOptions != null) { - if (serverAuthenticationOptions.CipherSuitesPolicy != null) - { - throw new PlatformNotSupportedException(SR.Format(SR.net_quic_ssl_option, nameof(serverAuthenticationOptions.CipherSuitesPolicy))); - } - #pragma warning disable SYSLIB0040 // NoEncryption and AllowNoEncryption are obsolete if (serverAuthenticationOptions.EncryptionPolicy == EncryptionPolicy.NoEncryption) { @@ -279,14 +274,18 @@ private static QUIC_ALLOWED_CIPHER_SUITE_FLAGS CipherSuitePolicyToFlags(CipherSu flags |= QUIC_ALLOWED_CIPHER_SUITE_FLAGS.CHACHA20_POLY1305_SHA256; break; case TlsCipherSuite.TLS_AES_128_CCM_SHA256: - // Not supported by MsQuic, but QUIC RFC allows it. - // TODO: should we throw as well? + // not supported by MsQuic, but QUIC RFC allows it so we ignore it. break; default: throw new ArgumentException(SR.Format(SR.net_quic_unsupported_cipher_suite, cipher)); } } + if (flags == QUIC_ALLOWED_CIPHER_SUITE_FLAGS.NONE) + { + throw new ArgumentException(SR.net_quic_empty_cipher_suite); + } + return flags; } } diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs new file mode 100644 index 00000000000000..7eea74d68385a6 --- /dev/null +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System.Net.Quic.Implementations; +using System.Net.Security; +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace System.Net.Quic.Tests +{ + [ConditionalClass(typeof(QuicTestBase), nameof(IsSupported))] + [Collection(nameof(DisableParallelization))] + [SkipOnPlatform(TestPlatforms.Windows, "CipherSuitesPolicy is not supported on Windows")] + public class MsQuicCipherSuitesPolicyTests : QuicTestBase + { + public MsQuicCipherSuitesPolicyTests(ITestOutputHelper output) : base(output) { } + + private async Task TestConnection(CipherSuitesPolicy serverPolicy, CipherSuitesPolicy clientPolicy) + { + var listenerOptions = CreateQuicListenerOptions(); + listenerOptions.ServerAuthenticationOptions.CipherSuitesPolicy = serverPolicy; + using QuicListener listener = CreateQuicListener(listenerOptions); + + var clientOptions = CreateQuicClientOptions(); + clientOptions.ClientAuthenticationOptions.CipherSuitesPolicy = clientPolicy; + clientOptions.RemoteEndPoint = listener.ListenEndPoint; + using QuicConnection clientConnection = CreateQuicConnection(clientOptions); + + await clientConnection.ConnectAsync(); + await clientConnection.CloseAsync(0); + } + + [Fact] + public Task SupportedCipher_Success() + { + CipherSuitesPolicy policy = new CipherSuitesPolicy(new[] { TlsCipherSuite.TLS_AES_128_GCM_SHA256 }); + return TestConnection(policy, policy); + } + + [Fact] + public void EmptyCipherSuitesPolicy_ThrowsArgumentException() + { + var listenerOptions = CreateQuicListenerOptions(); + listenerOptions.ServerAuthenticationOptions.CipherSuitesPolicy = new CipherSuitesPolicy(Array.Empty()); + Assert.Throws(() => CreateQuicListener(listenerOptions)); + } + + [Fact] + public async Task UnsupportedCipher_ThrowsArgumentException() + { + TlsCipherSuite cipher = TlsCipherSuite.TLS_AES_128_CCM_8_SHA256; + CipherSuitesPolicy policy = new CipherSuitesPolicy(new[] { cipher }); + ArgumentException ex = await Assert.ThrowsAsync(() => TestConnection(policy, policy)); + + Assert.Contains(cipher.ToString(), ex.Message); + } + + [Fact] + public async Task MismatchedCipherPolicies_ConnectAsync_ThrowsQuicException() + { + await Assert.ThrowsAsync(() => TestConnection( + new CipherSuitesPolicy(new[] { TlsCipherSuite.TLS_AES_128_GCM_SHA256 }), + new CipherSuitesPolicy(new[] { TlsCipherSuite.TLS_AES_256_GCM_SHA384 }) + )); + } + } +} \ No newline at end of file diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestBase.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestBase.cs index 39e6be421905a3..7e9bb17867284e 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestBase.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestBase.cs @@ -113,7 +113,7 @@ internal QuicListener CreateQuicListener(IPEndPoint endpoint) return CreateQuicListener(options); } - private QuicListener CreateQuicListener(QuicListenerOptions options) => new QuicListener(ImplementationProvider, options); + internal QuicListener CreateQuicListener(QuicListenerOptions options) => new QuicListener(ImplementationProvider, options); internal Task<(QuicConnection, QuicConnection)> CreateConnectedQuicConnection(QuicListener listener) => CreateConnectedQuicConnection(null, listener); internal async Task<(QuicConnection, QuicConnection)> CreateConnectedQuicConnection(QuicClientConnectionOptions? clientOptions, QuicListenerOptions listenerOptions) From 05223d135da9ab7d1ce457c18fcbc812a444f7fb Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Tue, 29 Mar 2022 15:17:58 +0200 Subject: [PATCH 3/4] Code review feedback --- .../src/Resources/Strings.resx | 3 --- .../Interop/SafeMsQuicConfigurationHandle.cs | 7 +++---- .../MsQuicCipherSuitesPolicyTests.cs | 21 ++++++++----------- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/libraries/System.Net.Quic/src/Resources/Strings.resx b/src/libraries/System.Net.Quic/src/Resources/Strings.resx index d7ce6c7a662f37..33781106d834bf 100644 --- a/src/libraries/System.Net.Quic/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Quic/src/Resources/Strings.resx @@ -165,9 +165,6 @@ The application protocol list is invalid. - - QUIC does not support '{0}' cipher suite. - CipherSuitePolicy must specify at least one cipher supported by QUIC. diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs index 729af09dc097a3..a82418cf8d06e6 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs @@ -273,11 +273,10 @@ private static QUIC_ALLOWED_CIPHER_SUITE_FLAGS CipherSuitePolicyToFlags(CipherSu case TlsCipherSuite.TLS_CHACHA20_POLY1305_SHA256: flags |= QUIC_ALLOWED_CIPHER_SUITE_FLAGS.CHACHA20_POLY1305_SHA256; break; - case TlsCipherSuite.TLS_AES_128_CCM_SHA256: - // not supported by MsQuic, but QUIC RFC allows it so we ignore it. - break; + case TlsCipherSuite.TLS_AES_128_CCM_SHA256: // not supported by MsQuic (yet?), but QUIC RFC allows it so we ignore it. default: - throw new ArgumentException(SR.Format(SR.net_quic_unsupported_cipher_suite, cipher)); + // ignore + break; } } diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs index 7eea74d68385a6..4cf74c903293ba 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs @@ -37,22 +37,19 @@ public Task SupportedCipher_Success() return TestConnection(policy, policy); } - [Fact] - public void EmptyCipherSuitesPolicy_ThrowsArgumentException() + [Theory] + [InlineData(new TlsCipherSuite[] { })] + [InlineData(new[] { TlsCipherSuite.TLS_AES_128_CCM_8_SHA256 })] + public void NoSupportedCiphers_ThrowsArgumentException(TlsCipherSuite[] ciphers) { + CipherSuitesPolicy policy = new CipherSuitesPolicy(ciphers); var listenerOptions = CreateQuicListenerOptions(); - listenerOptions.ServerAuthenticationOptions.CipherSuitesPolicy = new CipherSuitesPolicy(Array.Empty()); + listenerOptions.ServerAuthenticationOptions.CipherSuitesPolicy = policy; Assert.Throws(() => CreateQuicListener(listenerOptions)); - } - - [Fact] - public async Task UnsupportedCipher_ThrowsArgumentException() - { - TlsCipherSuite cipher = TlsCipherSuite.TLS_AES_128_CCM_8_SHA256; - CipherSuitesPolicy policy = new CipherSuitesPolicy(new[] { cipher }); - ArgumentException ex = await Assert.ThrowsAsync(() => TestConnection(policy, policy)); - Assert.Contains(cipher.ToString(), ex.Message); + var clientOptions = CreateQuicClientOptions(); + clientOptions.ClientAuthenticationOptions.CipherSuitesPolicy = policy; + Assert.Throws(() => CreateQuicConnection(clientOptions)); } [Fact] From 1026073d4aaebab7d83f11402c56c3155537dc3d Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Tue, 29 Mar 2022 15:23:54 +0200 Subject: [PATCH 4/4] Fix test --- .../MsQuic/Interop/SafeMsQuicConfigurationHandle.cs | 2 +- .../tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs index a82418cf8d06e6..1d9d3d86cf3377 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs @@ -282,7 +282,7 @@ private static QUIC_ALLOWED_CIPHER_SUITE_FLAGS CipherSuitePolicyToFlags(CipherSu if (flags == QUIC_ALLOWED_CIPHER_SUITE_FLAGS.NONE) { - throw new ArgumentException(SR.net_quic_empty_cipher_suite); + throw new ArgumentException(SR.net_quic_empty_cipher_suite, nameof(SslClientAuthenticationOptions.CipherSuitesPolicy)); } return flags; diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs index 4cf74c903293ba..17793a6367b502 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicCipherSuitesPolicyTests.cs @@ -49,6 +49,7 @@ public void NoSupportedCiphers_ThrowsArgumentException(TlsCipherSuite[] ciphers) var clientOptions = CreateQuicClientOptions(); clientOptions.ClientAuthenticationOptions.CipherSuitesPolicy = policy; + clientOptions.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, 5000); Assert.Throws(() => CreateQuicConnection(clientOptions)); }