public async Task RejectsConnectionOnSslPolicyErrorsWhenNoValidation(ClientCertificateMode mode) { var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)) { ConnectionAdapters = { new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2, ClientCertificateMode = mode }) } }; using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), listenOptions)) { using (var connection = server.CreateConnection()) { var stream = OpenSslStream(connection.Stream); await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); await AssertConnectionResult(stream, false); } await server.StopAsync(); } }
public ServerTlsSettings(X509Certificate certificate, ClientCertificateMode clientCertificateMode, bool checkCertificateRevocation, SslProtocols enabledProtocols) : base(enabledProtocols, checkCertificateRevocation) { Certificate = certificate; NegotiateClientCertificate = clientCertificateMode != ClientCertificateMode.NoCertificate; ClientCertificateMode = clientCertificateMode; }
public async Task ValidationFailureRejectsConnection(ClientCertificateMode mode) { var serviceContext = new TestServiceContext(); var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)) { ConnectionAdapters = { new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2, ClientCertificateMode = mode, ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => false }) } }; using (var server = new TestServer(context => Task.CompletedTask, serviceContext, listenOptions)) { using (var client = new TcpClient()) { var stream = await OpenSslStream(client, server); await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); await AssertConnectionResult(stream, false); } } }
public async Task ValidationFailureRejectsConnection(ClientCertificateMode mode) { void ConfigureListenOptions(ListenOptions listenOptions) { listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2, ClientCertificateMode = mode, ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => false }); } 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, false); } } }
public async Task ClientCertificateValidationGetsCalledWithNotNullParameters(ClientCertificateMode mode) { var clientCertificateValidationCalled = false; void ConfigureListenOptions(ListenOptions listenOptions) { listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2, ClientCertificateMode = mode, ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => { clientCertificateValidationCalled = true; Assert.NotNull(certificate); Assert.NotNull(chain); return(true); } }); } await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions)) { using (var connection = server.CreateConnection()) { var stream = OpenSslStreamWithCert(connection.Stream); await stream.AuthenticateAsClientAsync("localhost"); await AssertConnectionResult(stream, true); Assert.True(clientCertificateValidationCalled); } } }
public async Task ClientCertificateValidationGetsCalledWithNotNullParameters(ClientCertificateMode mode) { var clientCertificateValidationCalled = false; var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)) { ConnectionAdapters = { new HttpsConnectionAdapter(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2, ClientCertificateMode = mode, ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => { clientCertificateValidationCalled = true; Assert.NotNull(certificate); Assert.NotNull(chain); return(true); } }) } }; await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), listenOptions)) { 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); Assert.True(clientCertificateValidationCalled); } } }
public async Task ClientCertificateValidationGetsCalledWithNotNullParameters(ClientCertificateMode mode) { var clientCertificateValidationCalled = false; var serviceContext = new TestServiceContext(new HttpsConnectionFilter( new HttpsConnectionFilterOptions { ServerCertificate = _x509Certificate2, ClientCertificateMode = mode, ClientCertificateValidation = (certificate, chain, sslPolicyErrors) => { clientCertificateValidationCalled = true; Assert.NotNull(certificate); Assert.NotNull(chain); return(true); } }, new NoOpConnectionFilter()) ); using (var server = new TestServer(context => TaskUtilities.CompletedTask, serviceContext, _serverAddress)) { using (var client = new TcpClient()) { var stream = await OpenSslStream(client, server); await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); await AssertConnectionResult(stream, true); Assert.True(clientCertificateValidationCalled); } } }
public async Task ClientCertificate_AllowOrRequire_Available_Invalid_Refused(ClientCertificateMode mode, bool serverAllowInvalid) { var builder = CreateHostBuilder(async context => { var hasCert = context.Connection.ClientCertificate != null; await context.Response.WriteAsync(hasCert.ToString()); }, configureKestrel: kestrelOptions => { kestrelOptions.ListenAnyIP(0, listenOptions => { listenOptions.Protocols = HttpProtocols.Http3; listenOptions.UseHttps(httpsOptions => { httpsOptions.ServerCertificate = TestResources.GetTestCertificate(); httpsOptions.ClientCertificateMode = mode; if (serverAllowInvalid) { httpsOptions.AllowAnyClientCertificate(); // The self-signed cert is invalid. Let it fail the default checks. } }); }); }); using var host = builder.Build(); using var client = Http3Helpers.CreateClient(includeClientCert: true); await host.StartAsync().DefaultTimeout(); var request = new HttpRequestMessage(HttpMethod.Get, $"https://127.0.0.1:{host.GetPort()}/"); request.Version = HttpVersion.Version30; request.VersionPolicy = HttpVersionPolicy.RequestVersionExact; var sendTask = client.SendAsync(request, CancellationToken.None); if (!serverAllowInvalid) { // In .NET 6 there is a race condition between throwing HttpRequestException and QuicException. // Unable to test the exact error. var ex = await Assert.ThrowsAnyAsync <Exception>(() => sendTask).DefaultTimeout(); Logger.LogInformation(ex, "SendAsync successfully threw error."); } else { // Because we can't verify the exact error reason, check that the cert is the cause be successfully // making a call when invalid certs are allowed. var response = await sendTask.DefaultTimeout(); response.EnsureSuccessStatusCode(); } await host.StopAsync().DefaultTimeout(); }
public void AddClientCertificate(ClientCertificateMode mode, params string[] values) { var handler = new ClientCertificateHandler(mode, values); AddMapping(new AuthenticationOptionMapping { TokenHandler = new SecurityTokenHandlerCollection { handler }, Options = AuthenticationOptions.ForClientCertificate() }); }
public async Task ClientCertificate_AllowOrRequire_Available_Invalid_Refused(ClientCertificateMode mode) { var builder = CreateHostBuilder(async context => { var hasCert = context.Connection.ClientCertificate != null; await context.Response.WriteAsync(hasCert.ToString()); }, configureKestrel: kestrelOptions => { kestrelOptions.ListenAnyIP(0, listenOptions => { listenOptions.Protocols = HttpProtocols.Http3; listenOptions.UseHttps(httpsOptions => { httpsOptions.ServerCertificate = TestResources.GetTestCertificate(); httpsOptions.ClientCertificateMode = mode; // httpsOptions.AllowAnyClientCertificate(); // The self-signed cert is invalid. Let it fail the default checks. }); }); }); using var host = builder.Build(); using var client = Http3Helpers.CreateClient(includeClientCert: true); await host.StartAsync().DefaultTimeout(); var request = new HttpRequestMessage(HttpMethod.Get, $"https://127.0.0.1:{host.GetPort()}/"); request.Version = HttpVersion.Version30; request.VersionPolicy = HttpVersionPolicy.RequestVersionExact; var ex = await Assert.ThrowsAsync <HttpRequestException>(() => client.SendAsync(request, CancellationToken.None).DefaultTimeout()); // This poor error is likely a symptom of https://github.com/dotnet/runtime/issues/57246 // QuicListener returns the connection before (or in spite of) the cert validation failing. // There's a race where the stream could be accepted before the connection is aborted. var qex = Assert.IsType <QuicOperationAbortedException>(ex.InnerException); Assert.Equal("Operation aborted.", qex.Message); await host.StopAsync().DefaultTimeout(); }
public async Task RejectsConnectionOnSslPolicyErrorsWhenNoValidation(ClientCertificateMode mode) { void ConfigureListenOptions(ListenOptions listenOptions) { listenOptions.UseHttps(new HttpsConnectionAdapterOptions { ServerCertificate = _x509Certificate2, ClientCertificateMode = mode }); } await using (var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions)) { using (var connection = server.CreateConnection()) { var stream = OpenSslStreamWithCert(connection.Stream); await stream.AuthenticateAsClientAsync("localhost"); await AssertConnectionResult(stream, false); } } }
public async Task ClientCertificate_AllowOrRequire_Available_Accepted(ClientCertificateMode mode) { var builder = CreateHostBuilder(async context => { var hasCert = context.Connection.ClientCertificate != null; await context.Response.WriteAsync(hasCert.ToString()); }, configureKestrel: kestrelOptions => { kestrelOptions.ListenAnyIP(0, listenOptions => { listenOptions.Protocols = HttpProtocols.Http3; listenOptions.UseHttps(httpsOptions => { httpsOptions.ServerCertificate = TestResources.GetTestCertificate(); httpsOptions.ClientCertificateMode = mode; httpsOptions.AllowAnyClientCertificate(); }); }); }); using var host = builder.Build(); using var client = Http3Helpers.CreateClient(includeClientCert: true); await host.StartAsync().DefaultTimeout(); var request = new HttpRequestMessage(HttpMethod.Get, $"https://127.0.0.1:{host.GetPort()}/"); request.Version = HttpVersion.Version30; request.VersionPolicy = HttpVersionPolicy.RequestVersionExact; var response = await client.SendAsync(request, CancellationToken.None).DefaultTimeout(); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadAsStringAsync(); Assert.Equal(HttpVersion.Version30, response.Version); Assert.Equal("True", result); await host.StopAsync().DefaultTimeout(); }
public ClientCertificateHandler(ClientCertificateMode mode, params string[] values) { X509CertificateValidator validator; ClientCertificateIssuerNameRegistry registry; // set validator and registry if (mode == ClientCertificateMode.ChainValidation) { validator = X509CertificateValidator.ChainTrust; registry = new ClientCertificateIssuerNameRegistry(false, mode); } else if (mode == ClientCertificateMode.ChainValidationWithIssuerSubjectName || mode == ClientCertificateMode.ChainValidationWithIssuerThumbprint) { validator = X509CertificateValidator.ChainTrust; registry = new ClientCertificateIssuerNameRegistry(true, mode, values); } else if (mode == ClientCertificateMode.PeerValidation) { validator = X509CertificateValidator.PeerTrust; registry = new ClientCertificateIssuerNameRegistry(false, mode); } else if (mode == ClientCertificateMode.IssuerThumbprint) { validator = X509CertificateValidator.None; registry = new ClientCertificateIssuerNameRegistry(true, mode, values); } else { throw new ArgumentException("mode"); } Configuration = new SecurityTokenHandlerConfiguration { CertificateValidationMode = X509CertificateValidationMode.Custom, CertificateValidator = validator, IssuerNameRegistry = registry }; }
public ClientCertificateHandler(ClientCertificateMode mode, params string[] values) { X509CertificateValidator validator; ClientCertificateIssuerNameRegistry registry; // set validator and registry if (mode == ClientCertificateMode.ChainValidation) { validator = X509CertificateValidator.ChainTrust; registry = new ClientCertificateIssuerNameRegistry(false, mode); } else if (mode == ClientCertificateMode.ChainValidationWithIssuerSubjectName || mode == ClientCertificateMode.ChainValidationWithIssuerThumbprint) { validator = X509CertificateValidator.ChainTrust; registry = new ClientCertificateIssuerNameRegistry(true, mode, values); } else if (mode == ClientCertificateMode.PeerValidation) { validator = X509CertificateValidator.PeerTrust; registry = new ClientCertificateIssuerNameRegistry(false, mode); } else if (mode == ClientCertificateMode.IssuerThumbprint) { validator = X509CertificateValidator.None; registry = new ClientCertificateIssuerNameRegistry(true, mode, values); } else { throw new ArgumentException("mode"); } Configuration = new SecurityTokenHandlerConfiguration { CertificateValidationMode = X509CertificateValidationMode.Custom, CertificateValidator = validator, IssuerNameRegistry = registry }; }
public async Task RejectsConnectionOnSslPolicyErrorsWhenNoValidation(ClientCertificateMode mode) { var serviceContext = new TestServiceContext(new HttpsConnectionFilter( new HttpsConnectionFilterOptions { ServerCertificate = _x509Certificate2, ClientCertificateMode = mode, }, new NoOpConnectionFilter()) ); using (var server = new TestServer(context => TaskUtilities.CompletedTask, serviceContext, _serverAddress)) { using (var client = new TcpClient()) { var stream = await OpenSslStream(client, server); await stream.AuthenticateAsClientAsync("localhost", new X509CertificateCollection(), SslProtocols.Tls12 | SslProtocols.Tls11, false); await AssertConnectionResult(stream, false); } } }
internal static bool RemoteCertificateValidationCallback( ClientCertificateMode clientCertificateMode, Func <X509Certificate2, X509Chain, SslPolicyErrors, bool> clientCertificateValidation, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { if (certificate == null) { return(clientCertificateMode != ClientCertificateMode.RequireCertificate); } if (clientCertificateValidation == null) { if (sslPolicyErrors != SslPolicyErrors.None) { return(false); } } var certificate2 = ConvertToX509Certificate2(certificate); if (certificate2 == null) { return(false); } if (clientCertificateValidation != null) { if (!clientCertificateValidation(certificate2, chain, sslPolicyErrors)) { return(false); } } return(true); }
public ClientCertificateIssuerNameRegistry(bool checkIssuer, ClientCertificateMode mode, params string[] values) { _checkIssuer = checkIssuer; _mode = mode; _values = values; }
public SniOptions(SslServerAuthenticationOptions sslOptions, HttpProtocols httpProtocols, ClientCertificateMode clientCertificateMode) { SslOptions = sslOptions; HttpProtocols = httpProtocols; ClientCertificateMode = clientCertificateMode; }
public void GivenCertificateConfiguration_ConfigureHttpsSettings_Succeeds(bool serverPfxPasswordProtected, ClientCertificateMode clientCertificateMode) { var clientCertificateValidatorService = Mock.Of <IClientCertificateValidatorService>(); var httpsConnectionAdapterOptions = new HttpsConnectionAdapterOptions(); var networkServerConfiguration = new NetworkServerConfiguration { LnsServerPfxPath = serverPfxPasswordProtected ? this.passwordProtectedPfx : this.notProtectedPfx, LnsServerPfxPassword = serverPfxPasswordProtected ? CertificatePassword : string.Empty, ClientCertificateMode = clientCertificateMode }; BasicsStationNetworkServer.ConfigureHttpsSettings(networkServerConfiguration, clientCertificateValidatorService, httpsConnectionAdapterOptions); // assert Assert.NotNull(httpsConnectionAdapterOptions.ServerCertificate); Assert.Equal(httpsConnectionAdapterOptions.ClientCertificateMode, clientCertificateMode); if (clientCertificateMode is not ClientCertificateMode.NoCertificate) { Assert.NotNull(httpsConnectionAdapterOptions.ClientCertificateValidation); }
public ServerTlsSettings(X509Certificate certificate, ClientCertificateMode clientCertificateMode) : this(certificate, clientCertificateMode, false) { }
public static void AddClientCertificate(this AuthenticationConfiguration configuration, ClientCertificateMode mode, params string[] values) { var handler = new ClientCertificateHandler(mode, values); configuration.AddMapping(new AuthenticationOptionMapping { TokenHandler = new SecurityTokenHandlerCollection { handler }, Options = AuthenticationOptions.ForClientCertificate() }); }
public ServerTlsSettings(X509Certificate certificate, ClientCertificateMode clientCertificateMode, bool checkCertificateRevocation) : this(certificate, clientCertificateMode, checkCertificateRevocation, s_defaultServerProtocol) { }
public ClientCertificateIssuerNameRegistry(bool checkIssuer, ClientCertificateMode mode, params string[] values) { _checkIssuer = checkIssuer; _mode = mode; _values = values; }