Kestrel Override Client Cert Validation (#11423)

This commit is contained in:
Mikael Mengistu 2019-06-20 17:37:42 -07:00 committed by GitHub
parent 25d568885b
commit e95c3a08eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 14 deletions

View File

@ -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<Microsoft.AspNetCore.Connections.ConnectionContext, string, System.Security.Cryptography.X509Certificates.X509Certificate2> 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

View File

@ -55,7 +55,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https
public ClientCertificateMode ClientCertificateMode { get; set; }
/// <summary>
/// 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 <see cref="AllowAnyClientCertificate"/> is called after this callback is set.
/// </summary>
public Func<X509Certificate2, X509Chain, SslPolicyErrors, bool> ClientCertificateValidation { get; set; }
@ -75,6 +76,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https
/// </summary>
public bool CheckCertificateRevocation { get; set; }
/// <summary>
/// Overrides the current <see cref="ClientCertificateValidation"/> callback and allows any client certificate.
/// </summary>
public void AllowAnyClientCertificate()
{
ClientCertificateValidation = (_, __, ___) => true;
}
/// <summary>
/// Provides direct configuration of the <see cref="SslServerAuthenticationOptions"/> on a per-connection basis.
/// This is called after all of the other settings have already been applied.

View File

@ -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;

View File

@ -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();
});
}