diff --git a/src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp3.0.cs b/src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp3.0.cs index e301c44ccd..64277f5f9d 100644 --- a/src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp3.0.cs +++ b/src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp3.0.cs @@ -282,6 +282,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https public System.Security.Cryptography.X509Certificates.X509Certificate2 ServerCertificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } public System.Func ServerCertificateSelector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } public System.Security.Authentication.SslProtocols SslProtocols { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public void AllowAnyClientCertificate() { } } } namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal diff --git a/src/Servers/Kestrel/Core/src/HttpsConnectionAdapterOptions.cs b/src/Servers/Kestrel/Core/src/HttpsConnectionAdapterOptions.cs index baf7785773..92e80cc8d0 100644 --- a/src/Servers/Kestrel/Core/src/HttpsConnectionAdapterOptions.cs +++ b/src/Servers/Kestrel/Core/src/HttpsConnectionAdapterOptions.cs @@ -55,7 +55,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https public ClientCertificateMode ClientCertificateMode { get; set; } /// - /// Specifies a callback for additional client certificate validation that will be invoked during authentication. + /// Specifies a callback for additional client certificate validation that will be invoked during authentication. This will be ignored + /// if is called after this callback is set. /// public Func ClientCertificateValidation { get; set; } @@ -75,6 +76,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https /// public bool CheckCertificateRevocation { get; set; } + /// + /// Overrides the current callback and allows any client certificate. + /// + public void AllowAnyClientCertificate() + { + ClientCertificateValidation = (_, __, ___) => true; + } + /// /// Provides direct configuration of the on a per-connection basis. /// This is called after all of the other settings have already been applied. diff --git a/src/Servers/Kestrel/Kestrel/test/HttpsConnectionAdapterOptionsTest.cs b/src/Servers/Kestrel/Kestrel/test/HttpsConnectionAdapterOptionsTest.cs index 13b80b629b..aa4c003661 100644 --- a/src/Servers/Kestrel/Kestrel/test/HttpsConnectionAdapterOptionsTest.cs +++ b/src/Servers/Kestrel/Kestrel/test/HttpsConnectionAdapterOptionsTest.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs index f0da9d9b7d..cd06d0a3d1 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs @@ -339,11 +339,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests void ConfigureListenOptions(ListenOptions listenOptions) { listenOptions.Protocols = httpProtocols; - listenOptions.UseHttps(new HttpsConnectionAdapterOptions + listenOptions.UseHttps(options => { - ServerCertificate = _x509Certificate2, - ClientCertificateMode = ClientCertificateMode.RequireCertificate, - ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true + options.ServerCertificate = _x509Certificate2; + options.ClientCertificateMode = ClientCertificateMode.RequireCertificate; + options.AllowAnyClientCertificate(); }); } @@ -388,11 +388,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests { void ConfigureListenOptions(ListenOptions listenOptions) { - listenOptions.UseHttps(new HttpsConnectionAdapterOptions + listenOptions.UseHttps(options => { - ServerCertificate = _x509Certificate2, - ClientCertificateMode = ClientCertificateMode.RequireCertificate, - ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true + options.ServerCertificate = _x509Certificate2; + options.ClientCertificateMode = ClientCertificateMode.RequireCertificate; + options.AllowAnyClientCertificate(); }); } @@ -498,16 +498,41 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests } } + [Fact] + public async Task AllowAnyCertOverridesCertificateValidation() + { + void ConfigureListenOptions(ListenOptions listenOptions) + { + listenOptions.UseHttps(options => + { + options.ServerCertificate = _x509Certificate2; + options.ClientCertificateMode = ClientCertificateMode.RequireCertificate; + options.ClientCertificateValidation = (certificate, x509Chain, sslPolicyErrors) => false; + options.AllowAnyClientCertificate(); + }); + } + + await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory) { ExpectedConnectionMiddlewareCount = 1 }, ConfigureListenOptions)) + { + using (var connection = server.CreateConnection()) + { + var stream = OpenSslStream(connection.Stream); + await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); + await AssertConnectionResult(stream, true); + } + } + } + [Fact] public async Task CertificatePassedToHttpContextIsNotDisposed() { void ConfigureListenOptions(ListenOptions listenOptions) { - listenOptions.UseHttps(new HttpsConnectionAdapterOptions + listenOptions.UseHttps(options => { - ServerCertificate = _x509Certificate2, - ClientCertificateMode = ClientCertificateMode.RequireCertificate, - ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => true + options.ServerCertificate = _x509Certificate2; + options.ClientCertificateMode = ClientCertificateMode.RequireCertificate; + options.AllowAnyClientCertificate(); }); }