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();
            }
        }
Ejemplo n.º 2
0
 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);
                }
            }
        }
Ejemplo n.º 6
0
        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);
                }
            }
        }
Ejemplo n.º 8
0
        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()
            });
        }
Ejemplo n.º 10
0
        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);
                }
            }
        }
Ejemplo n.º 12
0
        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();
        }
Ejemplo n.º 13
0
        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);
                }
            }
        }
Ejemplo n.º 16
0
        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);
        }
Ejemplo n.º 17
0
 public ClientCertificateIssuerNameRegistry(bool checkIssuer, ClientCertificateMode mode, params string[] values)
 {
     _checkIssuer = checkIssuer;
     _mode        = mode;
     _values      = values;
 }
Ejemplo n.º 18
0
 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);
            }
Ejemplo n.º 20
0
 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()
            });
        }
Ejemplo n.º 22
0
 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;
 }