Ejemplo n.º 1
0
        public async Task SslStream_SecondNegotiateClientCertificateAsync_Throws(bool sendClientCertificate)
        {
            using CancellationTokenSource cts = new CancellationTokenSource();
            cts.CancelAfter(TestConfiguration.PassingTestTimeout);

            (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams();
            using (client)
                using (server)
                    using (X509Certificate2 serverCertificate = Configuration.Certificates.GetServerCertificate())
                        using (X509Certificate2 clientCertificate = Configuration.Certificates.GetClientCertificate())
                        {
                            SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions()
                            {
                                TargetHost          = Guid.NewGuid().ToString("N"),
                                EnabledSslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12,
                            };
                            clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
                            clientOptions.LocalCertificateSelectionCallback   = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) =>
                            {
                                return(sendClientCertificate ? clientCertificate : null);
                            };

                            SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions()
                            {
                                ServerCertificate = serverCertificate
                            };
                            serverOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

                            await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                                client.AuthenticateAsClientAsync(clientOptions, cts.Token),
                                server.AuthenticateAsServerAsync(serverOptions, cts.Token));

                            await TestHelper.PingPong(client, server, cts.Token);

                            Assert.Null(server.RemoteCertificate);

                            // Client needs to be reading for renegotiation to happen.
                            byte[]          buffer = new byte[TestHelper.s_ping.Length];
                            ValueTask <int> t      = client.ReadAsync(buffer, cts.Token);

                            await server.NegotiateClientCertificateAsync(cts.Token);

                            if (sendClientCertificate)
                            {
                                Assert.NotNull(server.RemoteCertificate);
                            }
                            else
                            {
                                Assert.Null(server.RemoteCertificate);
                            }
                            // Finish the client's read
                            await server.WriteAsync(TestHelper.s_ping, cts.Token);

                            await t;

                            await Assert.ThrowsAsync <InvalidOperationException>(() => server.NegotiateClientCertificateAsync());
                        }
        }
Ejemplo n.º 2
0
        public async Task SslStream_TargetHostName_Succeeds(bool useEmptyName)
        {
            string targetName = useEmptyName ? string.Empty : Guid.NewGuid().ToString("N");
            int    count      = 0;

            (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams();
            using (clientStream)
                using (serverStream)
                    using (var client = new SslStream(clientStream))
                        using (var server = new SslStream(serverStream))
                            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
                            {
                                // It should be empty before handshake.
                                Assert.Equal(string.Empty, client.TargetHostName);
                                Assert.Equal(string.Empty, server.TargetHostName);

                                SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions()
                                {
                                    TargetHost = targetName
                                };
                                clientOptions.RemoteCertificateValidationCallback =
                                    (sender, certificate, chain, sslPolicyErrors) =>
                                {
                                    SslStream stream = (SslStream)sender;
                                    Assert.Equal(targetName, stream.TargetHostName);
                                    count++;
                                    return(true);
                                };

                                SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions();
                                serverOptions.ServerCertificateSelectionCallback =
                                    (sender, name) =>
                                {
                                    SslStream stream = (SslStream)sender;
                                    Assert.Equal(targetName, stream.TargetHostName);

                                    return(certificate);
                                };

                                await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                                    client.AuthenticateAsClientAsync(clientOptions),
                                    server.AuthenticateAsServerAsync(serverOptions));

                                await TestHelper.PingPong(client, server);

                                Assert.Equal(targetName, client.TargetHostName);
                                Assert.Equal(targetName, server.TargetHostName);
                                Assert.Equal(1, count);
                            }
        }
Ejemplo n.º 3
0
        public async Task SslStream_NegotiateClientCertificateAsyncConcurrentIO_Throws(bool doRead)
        {
            using CancellationTokenSource cts = new CancellationTokenSource();
            cts.CancelAfter(TestConfiguration.PassingTestTimeout);

            (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams();
            using (client)
                using (server)
                    using (X509Certificate2 serverCertificate = Configuration.Certificates.GetServerCertificate())
                        using (X509Certificate2 clientCertificate = Configuration.Certificates.GetClientCertificate())
                        {
                            SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions()
                            {
                                TargetHost         = Guid.NewGuid().ToString("N"),
                                ClientCertificates = new X509CertificateCollection(new X509Certificate2[] { clientCertificate })
                            };
                            clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

                            SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions()
                            {
                                ServerCertificate = serverCertificate
                            };
                            serverOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

                            await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                                client.AuthenticateAsClientAsync(clientOptions, cts.Token),
                                server.AuthenticateAsServerAsync(serverOptions, cts.Token));

                            await TestHelper.PingPong(client, server, cts.Token);

                            Assert.Null(server.RemoteCertificate);

                            Task t = server.NegotiateClientCertificateAsync(cts.Token);
                            if (doRead)
                            {
                                byte[] buffer = new byte[TestHelper.s_ping.Length];
                                await Assert.ThrowsAsync <NotSupportedException>(() => server.ReadAsync(buffer).AsTask());
                            }
                            else
                            {
                                await Assert.ThrowsAsync <NotSupportedException>(() => server.WriteAsync(TestHelper.s_ping).AsTask());
                            }
                        }
        }
Ejemplo n.º 4
0
        public async Task NegotiateClientCertificateAsync_PendingData_Throws()
        {
            using CancellationTokenSource cts = new CancellationTokenSource();
            cts.CancelAfter(TestConfiguration.PassingTestTimeout);

            (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams();
            using (client)
                using (server)
                    using (X509Certificate2 serverCertificate = Configuration.Certificates.GetServerCertificate())
                        using (X509Certificate2 clientCertificate = Configuration.Certificates.GetClientCertificate())
                        {
                            SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions()
                            {
                                TargetHost         = Guid.NewGuid().ToString("N"),
                                ClientCertificates = new X509CertificateCollection(new X509Certificate2[] { clientCertificate })
                            };
                            clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

                            SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions()
                            {
                                ServerCertificate = serverCertificate
                            };
                            serverOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

                            await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                                client.AuthenticateAsClientAsync(clientOptions, cts.Token),
                                server.AuthenticateAsServerAsync(serverOptions, cts.Token));

                            await TestHelper.PingPong(client, server, cts.Token);

                            Assert.Null(server.RemoteCertificate);

                            // This should go out in single TLS frame
                            await client.WriteAsync(new byte[200], cts.Token);

                            byte[] readBuffer = new byte[10];
                            // when we read part of the frame, remaining part should left decrypted
                            await server.ReadAsync(readBuffer, cts.Token);

                            await Assert.ThrowsAsync <InvalidOperationException>(() => server.NegotiateClientCertificateAsync(cts.Token));
                        }
        }
        public async Task CertificateSelectionCallback_DelayedCertificate_OK(bool delayCertificate, bool sendClientCertificate)
        {
            X509Certificate?remoteCertificate = null;

            (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams();
            using (client)
                using (server)
                {
                    int count = 0;
                    SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions();
                    clientOptions.TargetHost = "localhost";
                    // Force Tls 1.2 to avoid issues with certain OpenSSL versions and Tls 1.3
                    // https://github.com/openssl/openssl/issues/7384
                    clientOptions.EnabledSslProtocols = SslProtocols.Tls12;
                    clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
                    clientOptions.LocalCertificateSelectionCallback   = (sender, targetHost, localCertificates, certificate, acceptableIssuers) =>
                    {
                        count++;
                        remoteCertificate = certificate;
                        if (delayCertificate && count == 1)
                        {
                            // wait until we get remote certificate from peer e.g. handshake started.
                            return(null);
                        }

                        return(sendClientCertificate ? _clientCertificate : null);
                    };

                    SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions();
                    serverOptions.ServerCertificate                   = _serverCertificate;
                    serverOptions.ClientCertificateRequired           = true;
                    serverOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        if (sendClientCertificate)
                        {
                            Assert.NotNull(certificate);
                            // The client chain may be incomplete.
                            Assert.True(sslPolicyErrors == SslPolicyErrors.None || sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors);
                        }
                        else
                        {
                            Assert.Equal(SslPolicyErrors.RemoteCertificateNotAvailable, sslPolicyErrors);
                        }

                        return(true);
                    };


                    await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                        client.AuthenticateAsClientAsync(clientOptions),
                        server.AuthenticateAsServerAsync(serverOptions));

                    // verify that the session is usable with or without client's certificate
                    await TestHelper.PingPong(client, server);

                    await TestHelper.PingPong(server, client);

                    if (delayCertificate)
                    {
                        // LocalCertificateSelectionCallback should be called with real remote certificate.
                        Assert.NotNull(remoteCertificate);
                    }
                }
        }
Ejemplo n.º 6
0
        public async Task SslStream_NegotiateClientCertificateAsyncTls13_Succeeds(bool sendClientCertificate)
        {
            bool negotiateClientCertificateCalled = false;

            using CancellationTokenSource cts = new CancellationTokenSource();
            cts.CancelAfter(TestConfiguration.PassingTestTimeout);

            (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams();
            using (client)
                using (server)
                    using (X509Certificate2 serverCertificate = Configuration.Certificates.GetServerCertificate())
                        using (X509Certificate2 clientCertificate = Configuration.Certificates.GetClientCertificate())
                        {
                            SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions()
                            {
                                TargetHost          = Guid.NewGuid().ToString("N"),
                                EnabledSslProtocols = SslProtocols.Tls13,
                            };
                            clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
                            clientOptions.LocalCertificateSelectionCallback   = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) =>
                            {
                                return(sendClientCertificate ? clientCertificate : null);
                            };

                            SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions()
                            {
                                ServerCertificate = serverCertificate
                            };
                            serverOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
                            {
                                if (negotiateClientCertificateCalled && sendClientCertificate)
                                {
                                    Assert.Equal(clientCertificate.GetCertHash(), certificate?.GetCertHash());
                                }
                                else
                                {
                                    Assert.Null(certificate);
                                }

                                return(true);
                            };

                            await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                                client.AuthenticateAsClientAsync(clientOptions, cts.Token),
                                server.AuthenticateAsServerAsync(serverOptions, cts.Token));

                            // need this to complete TLS 1.3 handshake
                            await TestHelper.PingPong(client, server);

                            Assert.Null(server.RemoteCertificate);

                            // Client needs to be reading for renegotiation to happen.
                            byte[]          buffer = new byte[TestHelper.s_ping.Length];
                            ValueTask <int> t      = client.ReadAsync(buffer, cts.Token);

                            negotiateClientCertificateCalled = true;
                            await server.NegotiateClientCertificateAsync(cts.Token);

                            if (sendClientCertificate)
                            {
                                Assert.NotNull(server.RemoteCertificate);
                            }
                            else
                            {
                                Assert.Null(server.RemoteCertificate);
                            }
                            // Finish the client's read
                            await server.WriteAsync(TestHelper.s_ping, cts.Token);

                            await t;
                            // verify that the session is usable with or without client's certificate
                            await TestHelper.PingPong(client, server, cts.Token);

                            await TestHelper.PingPong(server, client, cts.Token);
                        }
        }