Пример #1
0
        public override async ValueTask InitializeAsync(CancellationToken cancel)
        {
            await _underlying.InitializeAsync(cancel).ConfigureAwait(false);

            // This can only be created with a connected socket.
            _sslStream = new SslStream(new NetworkStream(_underlying.Socket !, false), false);

            try
            {
                if (_incoming)
                {
                    var options = new SslServerAuthenticationOptions();
                    options.ServerCertificate                   = _engine.TlsServerOptions.ServerCertificate;
                    options.ClientCertificateRequired           = _engine.TlsServerOptions.RequireClientCertificate;
                    options.EnabledSslProtocols                 = _engine.TlsServerOptions.EnabledSslProtocols !.Value;
                    options.RemoteCertificateValidationCallback =
                        _engine.TlsServerOptions.ClientCertificateValidationCallback ??
                        RemoteCertificateValidationCallback;
                    options.CertificateRevocationCheckMode = X509RevocationMode.NoCheck;
                    await _sslStream.AuthenticateAsServerAsync(options, cancel).ConfigureAwait(false);
                }
                else
                {
                    var options = new SslClientAuthenticationOptions();
                    options.TargetHost          = _host;
                    options.ClientCertificates  = _engine.TlsClientOptions.ClientCertificates;
                    options.EnabledSslProtocols = _engine.TlsClientOptions.EnabledSslProtocols !.Value;
                    options.RemoteCertificateValidationCallback =
                        _engine.TlsClientOptions.ServerCertificateValidationCallback ??
                        RemoteCertificateValidationCallback;
                    options.LocalCertificateSelectionCallback =
                        _engine.TlsClientOptions.ClientCertificateSelectionCallback ??
                        (options.ClientCertificates?.Count > 0 ?
                         CertificateSelectionCallback : (LocalCertificateSelectionCallback?)null);
                    options.CertificateRevocationCheckMode = X509RevocationMode.NoCheck;
                    await _sslStream.AuthenticateAsClientAsync(options, cancel).ConfigureAwait(false);
                }
            }
            catch (IOException ex) when(ex.IsConnectionLost())
            {
                throw new ConnectionLostException(ex, RetryPolicy.AfterDelay(TimeSpan.Zero), _connector);
            }
            catch (IOException ex)
            {
                throw new TransportException(ex, RetryPolicy.AfterDelay(TimeSpan.Zero), _connector);
            }
            catch (AuthenticationException ex)
            {
                throw new TransportException(ex, RetryPolicy.OtherReplica, _connector);
            }

            if (_engine.SecurityTraceLevel >= 1)
            {
                _engine.TraceStream(_sslStream, ToString());
            }

            // Use a buffered stream for writes. This ensures that small requests which are composed of multiple
            // small buffers will be sent within a single SSL frame.
            _writeStream = new BufferedStream(_sslStream);
        }
Пример #2
0
        public async Task SslStream_UntrustedCaWithCustomCallback_OK()
        {
            var clientOptions = new  SslClientAuthenticationOptions()
            {
                TargetHost = "localhost"
            };

            clientOptions.RemoteCertificateValidationCallback =
                (sender, certificate, chain, sslPolicyErrors) =>
            {
                chain.ChainPolicy.CustomTrustStore.Add(_serverChain[_serverChain.Count - 1]);
                chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;

                bool result = chain.Build((X509Certificate2)certificate);
                Assert.True(result);

                return(result);
            };

            var serverOptions = new SslServerAuthenticationOptions();

            serverOptions.ServerCertificateContext = SslStreamCertificateContext.Create(_serverCert, _serverChain);

            (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams();
            using (clientStream)
                using (serverStream)
                    using (SslStream client = new SslStream(clientStream))
                        using (SslStream server = new SslStream(serverStream))
                        {
                            Task t1 = client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None);
                            Task t2 = server.AuthenticateAsServerAsync(serverOptions, CancellationToken.None);

                            await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2);
                        }
        }
        public static Func <Uri, Task <T> > CreateRemoteStream <T>(string host, int port, string sni, Func <Socket, SslStream, T> func, SslProtocols sslProtocols = SslProtocols.None)
        {
            return(async(uri) =>
            {
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                await socket.ConnectAsync(host, port).ConfigureAwait(false);

                SslStream sslStream = new SslStream(new NetworkStream(socket, true), false);


                var info = new SslClientAuthenticationOptions()
                {
                    RemoteCertificateValidationCallback = (a, b, c, d) => true,

                    EnabledSslProtocols = sslProtocols,

                    TargetHost = sni
                };

                await sslStream.AuthenticateAsClientAsync(info, default).ConfigureAwait(false);

                return func(socket, sslStream);
            });
        }
Пример #4
0
        public async Task SslStream_UntrustedCaWithCustomCallback_Throws()
        {
            var options = new  SslClientAuthenticationOptions()
            {
                TargetHost = "localhost"
            };

            options.RemoteCertificateValidationCallback =
                (sender, certificate, chain, sslPolicyErrors) =>
            {
                chain.ChainPolicy.ExtraStore.AddRange(_serverChain);
                chain.ChainPolicy.CustomTrustStore.Add(_serverChain[_serverChain.Count - 1]);
                chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
                // This should work and we should be able to trust the chain.
                Assert.True(chain.Build((X509Certificate2)certificate));
                // Reject it in custom callback to simulate for example pinning.
                return(false);
            };

            (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams();
            using (clientStream)
                using (serverStream)
                    using (SslStream client = new SslStream(clientStream))
                        using (SslStream server = new SslStream(serverStream))
                        {
                            Task t1 = client.AuthenticateAsClientAsync(options, default);
                            Task t2 = server.AuthenticateAsServerAsync(_serverCert);

                            await Assert.ThrowsAsync <AuthenticationException>(() => t1);

                            // Server side should finish since we run custom callback after handshake is done.
                            await t2;
                        }
        }
Пример #5
0
        /// <summary>Initializes the pool.</summary>
        /// <param name="maxConnections">The maximum number of connections allowed to be associated with the pool at any given time.</param>
        ///
        public HttpConnectionPool(HttpConnectionPoolManager poolManager, string host, int port, string sslHostName, Uri proxyUri, int maxConnections)
        {
            Debug.Assert(proxyUri == null ?
                         host != null && port != 0 :    // direct http or https connection
                         (sslHostName == null ?
                          host == null && port == 0 :   // proxy connection
                          host != null && port != 0));  // SSL proxy tunnel

            _poolManager    = poolManager;
            _host           = host;
            _port           = port;
            _proxyUri       = proxyUri;
            _maxConnections = maxConnections;

            if (sslHostName != null)
            {
                // Precalculate cached SSL options to use for all connections.
                _sslOptions = _poolManager.Settings._sslOptions?.ShallowClone() ?? new SslClientAuthenticationOptions();
                _sslOptions.ApplicationProtocols = null;        // explicitly ignore any ApplicationProtocols set
                _sslOptions.TargetHost           = sslHostName; // always use the key's name rather than whatever was specified
            }

            if (_host != null)
            {
                // Precalculate ASCII bytes for header name
                // Note that if _host is null, this is a (non-tunneled) proxy connection, and we can't cache the hostname.
                // CONSIDER: Cache more than just host name -- port, header name, etc

                // Note the IDN hostname should always be ASCII, since it's already been IDNA encoded.
                _idnHostAsciiBytes = Encoding.ASCII.GetBytes(_host);
                Debug.Assert(Encoding.ASCII.GetString(_idnHostAsciiBytes) == _host);
            }
        }
Пример #6
0
        public async Task SslStream_Http2_Alpn_Success(Uri server)
        {
            using (TcpClient client = new TcpClient())
            {
                try
                {
                    await client.ConnectAsync(server.Host, server.Port);

                    using (SslStream clientStream = new SslStream(client.GetStream(), leaveInnerStreamOpen: false))
                    {
                        SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions
                        {
                            ApplicationProtocols = new List <SslApplicationProtocol> {
                                SslApplicationProtocol.Http2, SslApplicationProtocol.Http11
                            },
                            TargetHost = server.Host
                        };

                        await clientStream.AuthenticateAsClientAsync(clientOptions, CancellationToken.None);

                        Assert.Equal("h2", clientStream.NegotiatedApplicationProtocol.ToString());
                    }
                }
                catch (Exception e)
                {
                    // Failures to connect do not cause test failure.
                    _output.WriteLine("Unable to connect: {0}", e);
                }
            }
        }
        public async Task ServerAsyncAuthenticate_AsyncOptions_Success()
        {
            var state         = new object();
            var serverOptions = new SslServerAuthenticationOptions()
            {
                ServerCertificate = _serverCertificate
            };
            var clientOptions = new SslClientAuthenticationOptions()
            {
                TargetHost = _serverCertificate.GetNameInfo(X509NameType.SimpleName, false)
            };

            clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

            (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams();
            using (client)
                using (server)
                {
                    Task t1 = client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None);
                    Task t2 = server.AuthenticateAsServerAsync(
                        (stream, clientHelloInfo, userState, cancellationToken) =>
                    {
                        Assert.Equal(server, stream);
                        Assert.Equal(clientOptions.TargetHost, clientHelloInfo.ServerName);
                        Assert.True(object.ReferenceEquals(state, userState));
                        return(new ValueTask <SslServerAuthenticationOptions>(OptionsTask(serverOptions)));
                    },
                        state, CancellationToken.None);

                    await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2);
                }
        }
        public async Task ServerAsyncAuthenticate_SniSetVersion_Success(SslProtocols version)
        {
            var serverOptions = new SslServerAuthenticationOptions()
            {
                ServerCertificate = _serverCertificate, EnabledSslProtocols = version
            };
            var clientOptions = new SslClientAuthenticationOptions()
            {
                TargetHost = _serverCertificate.GetNameInfo(X509NameType.SimpleName, forIssuer: false), EnabledSslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12
            };

            clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

            (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams();
            using (client)
                using (server)
                {
                    Task t1 = client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None);
                    Task t2 = server.AuthenticateAsServerAsync(
                        (stream, clientHelloInfo, userState, cancellationToken) =>
                    {
                        Assert.Equal(server, stream);
                        Assert.Equal(clientOptions.TargetHost, clientHelloInfo.ServerName);
                        return(new ValueTask <SslServerAuthenticationOptions>(serverOptions));
                    },
                        null, CancellationToken.None);

                    await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2);

                    // Verify that the SNI callback can impact version.
                    Assert.Equal(version, client.SslProtocol);
                }
        }
Пример #9
0
        public void SslStream_StreamToStream_Alpn_NonMatchingProtocols_Fail()
        {
            VirtualNetwork network = new VirtualNetwork();

            using (var clientStream = new VirtualNetworkStream(network, false))
                using (var serverStream = new VirtualNetworkStream(network, true))
                    using (var client = new SslStream(clientStream, false))
                        using (var server = new SslStream(serverStream, false))
                            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
                            {
                                SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions
                                {
                                    ApplicationProtocols = new List <SslApplicationProtocol> {
                                        SslApplicationProtocol.Http11
                                    },
                                    RemoteCertificateValidationCallback = AllowAnyServerCertificate,
                                    TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false),
                                };

                                SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions
                                {
                                    ApplicationProtocols = new List <SslApplicationProtocol> {
                                        SslApplicationProtocol.Http2
                                    },
                                    ServerCertificate = certificate,
                                };

                                Task t1 = Assert.ThrowsAsync <AuthenticationException>(() => client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None));
                                Task t2 = Assert.ThrowsAsync <AuthenticationException>(() => server.AuthenticateAsServerAsync(serverOptions, CancellationToken.None));

                                Assert.True(Task.WaitAll(new[] { t1, t2 }, TestConfiguration.PassingTestTimeoutMilliseconds));
                            }
        }
Пример #10
0
        public void SslStream_StreamToStream_Alpn_Success(List <SslApplicationProtocol> clientProtocols, List <SslApplicationProtocol> serverProtocols, SslApplicationProtocol expected)
        {
            VirtualNetwork network = new VirtualNetwork();

            using (var clientStream = new VirtualNetworkStream(network, false))
                using (var serverStream = new VirtualNetworkStream(network, true))
                    using (var client = new SslStream(clientStream, false))
                        using (var server = new SslStream(serverStream, false))
                        {
                            SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions
                            {
                                ApplicationProtocols = clientProtocols,
                            };

                            SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions
                            {
                                ApplicationProtocols = serverProtocols,
                            };

                            Assert.True(DoHandshakeWithOptions(client, server, clientOptions, serverOptions));

                            Assert.Equal(expected, client.NegotiatedApplicationProtocol);
                            Assert.Equal(expected, server.NegotiatedApplicationProtocol);
                        }
        }
Пример #11
0
        private static SslClientAuthenticationOptions ConstructSslOptions(HttpConnectionPoolManager poolManager, string sslHostName)
        {
            Debug.Assert(sslHostName != null);

            SslClientAuthenticationOptions sslOptions = poolManager.Settings._sslOptions?.ShallowClone() ?? new SslClientAuthenticationOptions();

            sslOptions.ApplicationProtocols = null;        // explicitly ignore any ApplicationProtocols set
            sslOptions.TargetHost           = sslHostName; // always use the key's name rather than whatever was specified

            // Windows 7 and Windows 2008 R2 support TLS 1.1 and 1.2, but for legacy reasons by default those protocols
            // are not enabled when a developer elects to use the system default.  However, in .NET Core 2.0 and earlier,
            // HttpClientHandler would enable them, due to being a wrapper for WinHTTP, which enabled them.  Both for
            // compatibility and because we prefer those higher protocols whenever possible, SocketsHttpHandler also
            // pretends they're part of the default when running on Win7/2008R2.
            if (s_isWindows7Or2008R2 && sslOptions.EnabledSslProtocols == SslProtocols.None)
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(poolManager, $"Win7OrWin2K8R2 platform, Changing default TLS protocols to {SecurityProtocol.DefaultSecurityProtocols}");
                }
                sslOptions.EnabledSslProtocols = SecurityProtocol.DefaultSecurityProtocols;
            }

            return(sslOptions);
        }
Пример #12
0
        public static async ValueTask <SslStream> EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Stream stream, CancellationToken cancellationToken)
        {
            // If there's a cert validation callback, and if it came from HttpClientHandler,
            // wrap the original delegate in order to change the sender to be the request message (expected by HttpClientHandler's delegate).
            RemoteCertificateValidationCallback callback = sslOptions.RemoteCertificateValidationCallback;

            if (callback != null && callback.Target is CertificateCallbackMapper mapper)
            {
                sslOptions = sslOptions.ShallowClone(); // Clone as we're about to mutate it and don't want to affect the cached copy
                Func <HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> localFromHttpClientHandler = mapper.FromHttpClientHandler;
                HttpRequestMessage localRequest = request;
                sslOptions.RemoteCertificateValidationCallback = (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) =>
                                                                 localFromHttpClientHandler(localRequest, certificate as X509Certificate2, chain, sslPolicyErrors);
            }

            // Create the SslStream, authenticate, and return it.
            var sslStream = new SslStream(stream);

            try
            {
                await sslStream.AuthenticateAsClientAsync(sslOptions, cancellationToken).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                sslStream.Dispose();
                throw new HttpRequestException(SR.net_http_ssl_connection_failed, e);
            }
            return(sslStream);
        }
Пример #13
0
        public void SslStream_StreamToStream_DuplicateOptions_Throws()
        {
            RemoteCertificateValidationCallback rCallback = (sender, certificate, chain, errors) => { return(true); };
            LocalCertificateSelectionCallback   lCallback = (sender, host, localCertificates, remoteCertificate, issuers) => { return(null); };

            VirtualNetwork network = new VirtualNetwork();

            using (var clientStream = new VirtualNetworkStream(network, false))
                using (var serverStream = new VirtualNetworkStream(network, true))
                    using (var client = new SslStream(clientStream, false, rCallback, lCallback, EncryptionPolicy.RequireEncryption))
                        using (var server = new SslStream(serverStream, false, rCallback))
                            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
                            {
                                SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions();
                                clientOptions.RemoteCertificateValidationCallback = AllowAnyServerCertificate;
                                clientOptions.TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false);

                                SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions();
                                serverOptions.ServerCertificate = certificate;
                                serverOptions.RemoteCertificateValidationCallback = AllowAnyServerCertificate;

                                Task t1 = Assert.ThrowsAsync <InvalidOperationException>(() => client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None));
                                Task t2 = Assert.ThrowsAsync <InvalidOperationException>(() => server.AuthenticateAsServerAsync(serverOptions, CancellationToken.None));

                                Assert.True(Task.WaitAll(new[] { t1, t2 }, TestConfiguration.PassingTestTimeoutMilliseconds));
                            }
        }
        public async Task ServerAsyncAuthenticate_FailingOptionCallback_Throws(bool useAsync)
        {
            var serverOptions = new SslServerAuthenticationOptions()
            {
                ServerCertificate = _serverCertificate
            };
            var clientOptions = new SslClientAuthenticationOptions()
            {
                TargetHost = _serverCertificate.GetNameInfo(X509NameType.SimpleName, false)
            };

            clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

            (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams();
            using (client)
                using (server)
                {
                    Task t1 = client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None);
                    Task t2 = server.AuthenticateAsServerAsync(
                        (stream, clientHelloInfo, userState, cancellationToken) =>
                    {
                        if (useAsync)
                        {
                            return(new ValueTask <SslServerAuthenticationOptions>(FailedTask()));
                        }

                        throw new InvalidOperationException("foo");
                    },
                        null, CancellationToken.None);
                    await Assert.ThrowsAsync <InvalidOperationException>(() => t2);
                }
        }
Пример #15
0
        public void SslStream_StreamToStream_ServerCancellation_Throws()
        {
            VirtualNetwork network = new VirtualNetwork();

            using (var clientStream = new VirtualNetworkStream(network, isServer: false))
                using (var serverStream = new VirtualNetworkStream(network, isServer: true))
                    using (var client = new SslStream(clientStream))
                        using (var server = new SslStream(serverStream))
                            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
                            {
                                SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions();
                                clientOptions.RemoteCertificateValidationCallback = AllowAnyServerCertificate;
                                clientOptions.TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false);

                                SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions();
                                serverOptions.ServerCertificate = certificate;

                                CancellationTokenSource cts = new CancellationTokenSource();
                                cts.Cancel();

                                Task clientTask = Assert.ThrowsAsync <TimeoutException>(() => client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None));
                                Task serverTask = Assert.ThrowsAnyAsync <OperationCanceledException>(() => server.AuthenticateAsServerAsync(serverOptions, cts.Token));

                                Assert.True(Task.WaitAll(new[] { clientTask, serverTask }, TestConfiguration.PassingTestTimeoutMilliseconds));
                            }
        }
        public async Task ListenOptionsProtolsCanBeSetAfterUseHttps(HttpProtocols httpProtocols)
        {
            void ConfigureListenOptions(ListenOptions listenOptions)
            {
                listenOptions.UseHttps(_x509Certificate2);
                listenOptions.Protocols = httpProtocols;
            }

            await using var server = new TestServer(context => Task.CompletedTask, new TestServiceContext(LoggerFactory), ConfigureListenOptions);
            using var connection   = server.CreateConnection();

            var sslOptions = new SslClientAuthenticationOptions
            {
                TargetHost           = "localhost",
                EnabledSslProtocols  = SslProtocols.Tls12 | SslProtocols.Tls11,
                ApplicationProtocols = new List <SslApplicationProtocol> {
                    SslApplicationProtocol.Http11, SslApplicationProtocol.Http2
                },
            };

            using var stream = OpenSslStream(connection.Stream);
            await stream.AuthenticateAsClientAsync(sslOptions);

            Assert.Equal(
                httpProtocols.HasFlag(HttpProtocols.Http2) ?
                SslApplicationProtocol.Http2 :
                SslApplicationProtocol.Http11,
                stream.NegotiatedApplicationProtocol);
        }
Пример #17
0
        public async Task SslStream_StreamToStream_DuplicateOptions_Throws()
        {
            RemoteCertificateValidationCallback rCallback = (sender, certificate, chain, errors) => { return(true); };
            LocalCertificateSelectionCallback   lCallback = (sender, host, localCertificates, remoteCertificate, issuers) => { return(null); };

            (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams();
            using (clientStream)
                using (serverStream)
                    using (var client = new SslStream(clientStream, false, rCallback, lCallback, EncryptionPolicy.RequireEncryption))
                        using (var server = new SslStream(serverStream, false, rCallback))
                            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
                            {
                                SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions();
                                clientOptions.RemoteCertificateValidationCallback = AllowAnyServerCertificate;
                                clientOptions.TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false);

                                SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions();
                                serverOptions.ServerCertificate = certificate;
                                serverOptions.RemoteCertificateValidationCallback = AllowAnyServerCertificate;

                                Task t1 = Assert.ThrowsAsync <InvalidOperationException>(() => client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None));
                                Task t2 = Assert.ThrowsAsync <InvalidOperationException>(() => server.AuthenticateAsServerAsync(serverOptions, CancellationToken.None));

                                await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2);
                            }
        }
        [OuterLoop] // Test hits external azure server.
        public async Task SslStream_AllowRenegotiation_False_Throws()
        {
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            await s.ConnectAsync(Configuration.Security.TlsRenegotiationServer, 443);

            using (NetworkStream ns = new NetworkStream(s))
                using (SslStream ssl = new SslStream(ns, true))
                {
                    X509CertificateCollection certBundle = new X509CertificateCollection();
                    certBundle.Add(Configuration.Certificates.GetClientCertificate());

                    SslClientAuthenticationOptions options = new SslClientAuthenticationOptions
                    {
                        TargetHost                     = Configuration.Security.TlsRenegotiationServer,
                        ClientCertificates             = certBundle,
                        EnabledSslProtocols            = SslProtocols.Tls12,
                        CertificateRevocationCheckMode = X509RevocationMode.NoCheck,
                        AllowRenegotiation             = false
                    };

                    // Perform handshake to establish secure connection.
                    await ssl.AuthenticateAsClientAsync(options, CancellationToken.None);

                    Assert.True(ssl.IsAuthenticated);
                    Assert.True(ssl.IsEncrypted);

                    // Issue request that triggers regotiation from server.
                    byte[] message = Encoding.UTF8.GetBytes("GET /EchoClientCertificate.ashx HTTP/1.1\r\nHost: corefx-net-tls.azurewebsites.net\r\n\r\n");
                    await ssl.WriteAsync(message, 0, message.Length);

                    // Initiate Read operation, that results in starting renegotiation as per server response to the above request.
                    // This will throw IOException, since renegotiation is disabled on client side.
                    await Assert.ThrowsAsync <IOException>(() => ssl.ReadAsync(message, 0, message.Length));
                }
        }
Пример #19
0
        /// <summary>
        /// Connect to the given host on the port asynchronously
        /// </summary>
        /// <param name="host">The host to connect to</param>
        /// <param name="port">The port to use for communication</param>
        public async Task ConnectAsync(string host, int port)
        {
            // Don't reconnect
            if (_state == LDAPConnectionState.Connected)
            {
                return;
            }

            try
            {
                await _conn.ConnectAsync(host, port);

                if (_sslEnabled)
                {
                    _raw = _conn.GetStream();

                    var options = new SslClientAuthenticationOptions
                    {
                        TargetHost          = host,
                        EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls,
                        ClientCertificates  = null,
                        LocalCertificateSelectionCallback   = null,
                        CertificateRevocationCheckMode      = X509RevocationMode.NoCheck,
                        RemoteCertificateValidationCallback = (sender, cert, chain, errors) =>
                        {
                            // Accept all...bad idea
                            return(true);
                        },
                        ApplicationProtocols = new List <SslApplicationProtocol>()
                        {
                            SslApplicationProtocol.Http11
                        },
                        EncryptionPolicy = EncryptionPolicy.RequireEncryption,
                    };

                    _transport = new SslStream(_raw);
                    await(_transport as SslStream).AuthenticateAsClientAsync(options, CancellationToken.None);
                    Reader = new LDAPReader(_transport);
                    Writer = new LDAPWriter(_transport);
                }
                else
                {
                    _raw       = _conn.GetStream();
                    _transport = null;
                    Reader     = new LDAPReader(_raw);
                    Writer     = new LDAPWriter(_raw);
                }

                // Create the pump and start it
                _pump = new MessagePump(Reader, _raw, _log);
                _pump.Start();
                _state = LDAPConnectionState.Connected;
            }
            catch (Exception e)
            {
                _state = LDAPConnectionState.Faulted;
                throw new LDAPException("Failed to connect", e);
            }
        }
Пример #20
0
 public static Task AuthenticateAsClientAsync(this SslStream stream,
                                              bool async, SslClientAuthenticationOptions clientOptions,
                                              CancellationToken cancellationToken = default)
 {
     return(async
         ? stream.AuthenticateAsClientAsync(clientOptions, cancellationToken)
         : Task.Run(() => stream.AuthenticateAsClient(clientOptions)));
 }
Пример #21
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());
                        }
        }
Пример #22
0
        // Constructor for outbound connections
        internal MockConnection(IPEndPoint remoteEndPoint, SslClientAuthenticationOptions sslClientAuthenticationOptions, IPEndPoint localEndPoint = null)
        {
            _remoteEndPoint = remoteEndPoint;
            _localEndPoint  = localEndPoint;

            _isClient = true;
            _nextOutboundBidirectionalStream  = 0;
            _nextOutboundUnidirectionalStream = 2;
        }
Пример #23
0
        private static SocketsHttpHandler GetHttpClientHandler()
        {
            var sslOptions = new SslClientAuthenticationOptions
            {
                RemoteCertificateValidationCallback = (message, certificate, chain, sslErrors) =>
                {
                    // direct to url with matching server certificate
                    if (sslErrors.ToString() == "None")
                    {
                        return(true);
                    }

                    // support Azure Function redirect
                    if (sslErrors.ToString() == "RemoteCertificateNameMismatch")
                    {
                        if (certificate == null)
                        {
                            throw new Exception($"Server Certificate Validation Failure: Certificate is Null");
                        }
                        else
                        {
                            // Issed by Microsoft
                            if (certificate.Issuer.Contains("O=Microsoft Corporation")

                                // Azure Function Host URL
                                && certificate.Subject.Contains("CN=*.azurewebsites.net"))
                            {
                                return(true);
                            }
                            else
                            {
                                throw new Exception($"Server Certificate Validation Failure: Not Trusted Certificate - {certificate.Issuer}, {certificate.Subject}");
                            }
                        }
                    }

                    if (certificate == null)
                    {
                        throw new Exception($"Server Certificate Validation Failure: {sslErrors}");
                    }
                    else
                    {
                        throw new Exception($"Server Certificate Validation Failure: {sslErrors}, {certificate.Issuer}, {certificate.Subject}");
                    }
                }
            };

            var socketHandler = new SocketsHttpHandler
            {
                PooledConnectionLifetime = TimeSpan.FromMinutes(1),

                SslOptions = sslOptions
            };

            return(socketHandler);
        }
Пример #24
0
        public async ValueTask <Stream> GetClientStream(Socket socket)
        {
            var stream  = new SslStream(new NetworkStream(socket), false);
            var options = new SslClientAuthenticationOptions();

            options.TargetHost = "supersocket";
            options.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
            await stream.AuthenticateAsClientAsync(options);

            return(stream);
        }
Пример #25
0
        private static SslClientAuthenticationOptions ConstructSslOptions(HttpConnectionPoolManager poolManager, string sslHostName)
        {
            Debug.Assert(sslHostName != null);

            SslClientAuthenticationOptions sslOptions = poolManager.Settings._sslOptions?.ShallowClone() ?? new SslClientAuthenticationOptions();

            sslOptions.ApplicationProtocols = null;        // explicitly ignore any ApplicationProtocols set
            sslOptions.TargetHost           = sslHostName; // always use the key's name rather than whatever was specified

            return(sslOptions);
        }
Пример #26
0
        private static NegotiatedParams ConnectAndGetNegotiatedParams(ConnectionParams serverParams, ConnectionParams clientParams)
        {
            (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams();

            using (clientStream)
                using (serverStream)
                    using (SslStream server = new SslStream(serverStream, leaveInnerStreamOpen: false),
                           client = new SslStream(clientStream, leaveInnerStreamOpen: false))
                    {
                        var serverOptions = new SslServerAuthenticationOptions();
                        serverOptions.ServerCertificate   = Configuration.Certificates.GetSelfSignedServerCertificate();
                        serverOptions.EncryptionPolicy    = serverParams.EncryptionPolicy;
                        serverOptions.EnabledSslProtocols = serverParams.SslProtocols;
                        serverOptions.CipherSuitesPolicy  = serverParams.CipherSuitesPolicy;

                        var clientOptions = new SslClientAuthenticationOptions();
                        clientOptions.EncryptionPolicy    = clientParams.EncryptionPolicy;
                        clientOptions.EnabledSslProtocols = clientParams.SslProtocols;
                        clientOptions.CipherSuitesPolicy  = clientParams.CipherSuitesPolicy;
                        clientOptions.TargetHost          = "test";
                        clientOptions.RemoteCertificateValidationCallback =
                            new RemoteCertificateValidationCallback((object sender,
                                                                     X509Certificate certificate,
                                                                     X509Chain chain,
                                                                     SslPolicyErrors sslPolicyErrors) => {
                            return(true);
                        });

                        Exception failure = WaitForSecureConnection(client, clientOptions, server, serverOptions).GetAwaiter().GetResult();

                        if (failure == null)
                        {
                            // send some bytes, make sure they can talk
                            byte[] data         = new byte[] { 1, 2, 3 };
                            byte[] receivedData = new byte[1];
                            Task   serverTask   = server.WriteAsync(data, 0, data.Length);
                            for (int i = 0; i < data.Length; i++)
                            {
                                Assert.True(client.ReadAsync(receivedData, 0, 1).Wait(TestConfiguration.PassingTestTimeoutMilliseconds),
                                            $"Read task failed to finish in {TestConfiguration.PassingTestTimeoutMilliseconds}ms.");
                                Assert.Equal(data[i], receivedData[0]);
                            }

                            Assert.True(serverTask.Wait(TestConfiguration.PassingTestTimeoutMilliseconds),
                                        $"WriteTask failed to finish in {TestConfiguration.PassingTestTimeoutMilliseconds}ms.");
                            return(new NegotiatedParams(server, client));
                        }
                        else
                        {
                            return(new NegotiatedParams(failure));
                        }
                    }
        }
Пример #27
0
        /// <summary>
        /// Create an outbound QUIC connection.
        /// </summary>
        /// <param name="remoteEndPoint">The remote endpoint to connect to.</param>
        /// <param name="sslClientAuthenticationOptions">TLS options</param>
        /// <param name="localEndPoint">The local endpoint to connect from.</param>
        /// <param name="mock">Use mock QUIC implementation.</param>
        // !!! TEMPORARY FOR QUIC MOCK SUPPORT: Remove "mock" parameter before shipping
        public QuicConnection(IPEndPoint remoteEndPoint, SslClientAuthenticationOptions sslClientAuthenticationOptions, IPEndPoint localEndPoint = null, bool mock = false)
        {
            // TODO: TLS handling

            _mock           = mock;
            _remoteEndPoint = remoteEndPoint;
            _localEndPoint  = localEndPoint;

            _isClient = true;
            _nextOutboundBidirectionalStream  = 0;
            _nextOutboundUnidirectionalStream = 2;
        }
        private async ValueTask <(Socket, Stream, HttpResponseMessage)> ConnectAsync(HttpConnectionKind kind, HttpRequestMessage request, CancellationToken cancellationToken)
        {
            Stream stream = null;

            switch (_kind)
            {
            case HttpConnectionKind.Http:
            case HttpConnectionKind.Https:
            case HttpConnectionKind.ProxyConnect:
                stream = await ConnectAsync(request, cancellationToken).ConfigureAwait(false);

                break;

            case HttpConnectionKind.ProxyTunnel:
            case HttpConnectionKind.SslProxyTunnel:
                HttpResponseMessage response;
                (stream, response) = await EstablishProxyTunnel(request.Headers.Any()?request.Headers : null, cancellationToken).ConfigureAwait(false);

                if (response != null)
                {
                    // Return non-success response from proxy.
                    response.RequestMessage = request;
                    return(null, null, response);
                }
                break;
            }

            Socket socket = (stream as ExposedSocketNetworkStream)?.Socket;

            if (kind == HttpConnectionKind.Https || kind == HttpConnectionKind.SslProxyTunnel)
            {
                var sslOptions = new SslClientAuthenticationOptions();
                sslOptions.TargetHost          = _poolManager.settings.EndPointProvider.GetHost(_sslHost);
                sslOptions.EnabledSslProtocols = SslProtocols.Tls11;
                if (_poolManager.settings.RemoteCertificateValidationCallback != null)
                {
                    sslOptions.RemoteCertificateValidationCallback = _poolManager.settings.RemoteCertificateValidationCallback;
                }
                else
                {
                    sslOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        return(true);
                    };
                }
                sslOptions.ClientCertificates = _poolManager.settings.ClientCertificates;
                SslStream sslStream = await EstablishSslConnectionAsync(sslOptions, request, stream, cancellationToken).ConfigureAwait(false);

                stream = sslStream;
            }

            return(socket, stream, null);
        }
        private static NegotiatedParams ConnectAndGetNegotiatedParams(ConnectionParams serverParams, ConnectionParams clientParams)
        {
            VirtualNetwork vn = new VirtualNetwork();

            using (VirtualNetworkStream serverStream = new VirtualNetworkStream(vn, isServer: true),
                   clientStream = new VirtualNetworkStream(vn, isServer: false))
                using (SslStream server = new SslStream(serverStream, leaveInnerStreamOpen: false),
                       client = new SslStream(clientStream, leaveInnerStreamOpen: false))
                {
                    var serverOptions = new SslServerAuthenticationOptions();
                    serverOptions.ServerCertificate   = Configuration.Certificates.GetSelfSignedServerCertificate();
                    serverOptions.EncryptionPolicy    = serverParams.EncryptionPolicy;
                    serverOptions.EnabledSslProtocols = serverParams.SslProtocols;
                    serverOptions.CipherSuitesPolicy  = serverParams.CipherSuitesPolicy;

                    var clientOptions = new SslClientAuthenticationOptions();
                    clientOptions.EncryptionPolicy    = clientParams.EncryptionPolicy;
                    clientOptions.EnabledSslProtocols = clientParams.SslProtocols;
                    clientOptions.CipherSuitesPolicy  = clientParams.CipherSuitesPolicy;
                    clientOptions.TargetHost          = "test";
                    clientOptions.RemoteCertificateValidationCallback =
                        new RemoteCertificateValidationCallback((object sender,
                                                                 X509Certificate certificate,
                                                                 X509Chain chain,
                                                                 SslPolicyErrors sslPolicyErrors) => {
                        return(true);
                    });

                    Func <Task> serverTask = () => server.AuthenticateAsServerAsync(serverOptions, CancellationToken.None);
                    Func <Task> clientTask = () => client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None);

                    Exception failure = WaitForSecureConnection(vn, serverTask, clientTask).Result;

                    if (failure == null)
                    {
                        // send some bytes, make sure they can talk
                        byte[] data = new byte[] { 1, 2, 3 };
                        server.WriteAsync(data, 0, data.Length);

                        for (int i = 0; i < data.Length; i++)
                        {
                            Assert.Equal(data[i], client.ReadByte());
                        }

                        return(new NegotiatedParams(server, client));
                    }
                    else
                    {
                        return(new NegotiatedParams(failure));
                    }
                }
        }
Пример #30
0
            protected override IConnector GetConntector()
            {
                var authOptions = new SslClientAuthenticationOptions();

                authOptions.EnabledSslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12;
                authOptions.TargetHost          = IPAddress.Loopback.ToString();
                authOptions.RemoteCertificateValidationCallback += (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) =>
                {
                    return(true);
                };

                return(new SocketConnector(new SslStreamConnector(authOptions)));
            }