[PlatformSpecific(TestPlatforms.Linux)] // This only applies where OpenSsl is used.
        public async Task SslStream_SendReceiveOverNetworkStream_AuthenticationException()
        {
            SslProtocols clientProtocol;
            SslProtocols serverProtocol;

            // Try to find protocol mismatch.
            if (PlatformDetection.SupportsTls12 && (PlatformDetection.SupportsTls10 || PlatformDetection.SupportsTls11))
            {
                // OpenSSL 1.0 where new is Tls12
                clientProtocol = SslProtocols.Tls | SslProtocols.Tls11;
                serverProtocol = SslProtocols.Tls12;
            }
            else if (PlatformDetection.SupportsTls12 && PlatformDetection.SupportsTls13)
            {
                // OpenSSl 1.1 where new is 1.3 and legacy is 1.2
                clientProtocol = SslProtocols.Tls13;
                serverProtocol = SslProtocols.Tls12;
            }
            else
            {
                throw new SkipTestException("Did not find disjoined sets");
            }

            TcpListener listener = new TcpListener(IPAddress.Loopback, 0);

            using (X509Certificate2 serverCertificate = Configuration.Certificates.GetServerCertificate())
                using (TcpClient client = new TcpClient())
                {
                    listener.Start();

                    Task             clientConnectTask  = client.ConnectAsync(IPAddress.Loopback, ((IPEndPoint)listener.LocalEndpoint).Port);
                    Task <TcpClient> listenerAcceptTask = listener.AcceptTcpClientAsync();

                    await TestConfiguration.WhenAllOrAnyFailedWithTimeout(clientConnectTask, listenerAcceptTask);

                    TcpClient server = listenerAcceptTask.Result;
                    using (SslStream clientStream = new SslStream(
                               client.GetStream(),
                               false,
                               new RemoteCertificateValidationCallback(ValidateServerCertificate),
                               null,
                               EncryptionPolicy.RequireEncryption))
                        using (SslStream serverStream = new SslStream(
                                   server.GetStream(),
                                   false,
                                   null,
                                   null,
                                   EncryptionPolicy.RequireEncryption))
                        {
                            Task clientAuthenticationTask = clientStream.AuthenticateAsClientAsync(
                                serverCertificate.GetNameInfo(X509NameType.SimpleName, false),
                                null,
                                clientProtocol,
                                false);

                            AuthenticationException e = await Assert.ThrowsAsync <AuthenticationException>(() => serverStream.AuthenticateAsServerAsync(
                                                                                                               serverCertificate,
                                                                                                               false,
                                                                                                               serverProtocol,
                                                                                                               false));

                            Assert.NotNull(e.InnerException);
                            Assert.Contains("SSL_ERROR_SSL", e.InnerException.Message);
                            Assert.NotNull(e.InnerException.InnerException);
                            Assert.Contains("protocol", e.InnerException.InnerException.Message);
                        }
                }

            listener.Stop();
        }
Exemplo n.º 2
0
        private void OnAccept(Task <TcpClient> result)
        {
            TcpClient client = null;

            // Accept current connection
            try
            {
                client = result.Result;
            }
            catch
            {
            }

            // If we have a connection, then process it
            if (client != null)
            {
                OnClientAccepted(client);

                ClientState state;

                // Start authentication for SSL?
                if (_useSsl)
                {
                    state = new ClientState(client, _sslEncryptionPolicy);
                    _log.WriteLine("Server: starting SSL authentication.");


                    SslStream        sslStream   = null;
                    X509Certificate2 certificate = TestConfiguration.GetServerCertificate();

                    try
                    {
                        sslStream = (SslStream)state.Stream;

                        _log.WriteLine("Server: attempting to open SslStream.");
                        sslStream.AuthenticateAsServerAsync(certificate, false, _sslProtocols, false).ContinueWith(t => OnAuthenticate(t, state), TaskScheduler.Default);
                    }
                    catch (Exception ex)
                    {
                        _log.WriteLine("Server: Exception: {0}", ex);

                        state.Dispose(); // close connection to client
                    }
                }
                else
                {
                    state = new ClientState(client);

                    // Start listening for data from the client connection
                    try
                    {
                        state.Stream.BeginRead(state.ReceiveBuffer, 0, state.ReceiveBuffer.Length, OnReceive, state);
                    }
                    catch
                    {
                    }
                }
            }

            // Listen for more client connections
            try
            {
                _listener.AcceptTcpClientAsync().ContinueWith(t => OnAccept(t), TaskScheduler.Default);
            }
            catch
            {
            }
        }
Exemplo n.º 3
0
        public async Task SslStream_RandomSizeWrites_OK(int bufferSize, int readBufferSize, int writeBufferSize, bool useAsync)
        {
            byte[] dataToCopy   = RandomNumberGenerator.GetBytes(bufferSize);
            byte[] dataReceived = new byte[dataToCopy.Length + readBufferSize]; // make the buffer bigger to have chance to read more

            var clientOptions = new SslClientAuthenticationOptions()
            {
                TargetHost = "localhost"
            };

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

            var serverOptions = new SslServerAuthenticationOptions();

            serverOptions.ServerCertificateContext = SslStreamCertificateContext.Create(Configuration.Certificates.GetServerCertificate(), null);

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

                            await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2);

                            Task writer = Task.Run(() =>
                            {
                                Memory <byte> data = new Memory <byte>(dataToCopy);
                                while (data.Length > 0)
                                {
                                    int writeLength = Math.Min(data.Length, writeBufferSize);
                                    if (useAsync)
                                    {
                                        server.WriteAsync(data.Slice(0, writeLength)).GetAwaiter().GetResult();
                                    }
                                    else
                                    {
                                        server.Write(data.Span.Slice(0, writeLength));
                                    }

                                    data = data.Slice(Math.Min(writeBufferSize, data.Length));
                                }

                                server.ShutdownAsync().GetAwaiter().GetResult();
                            });

                            Task reader = Task.Run(() =>
                            {
                                Memory <byte> readBuffer = new Memory <byte>(dataReceived);
                                int totalLength          = 0;
                                int readLength;

                                while (true)
                                {
                                    if (useAsync)
                                    {
                                        readLength = client.ReadAsync(readBuffer.Slice(totalLength, readBufferSize)).GetAwaiter().GetResult();
                                    }
                                    else
                                    {
                                        readLength = client.Read(readBuffer.Span.Slice(totalLength, readBufferSize));
                                    }

                                    if (readLength == 0)
                                    {
                                        break;
                                    }

                                    totalLength += readLength;
                                    Assert.True(totalLength <= bufferSize);
                                }

                                Assert.Equal(bufferSize, totalLength);
                                AssertExtensions.SequenceEqual(dataToCopy.AsSpan(), dataReceived.AsSpan().Slice(0, totalLength));
                            });

                            await TestConfiguration.WhenAllOrAnyFailedWithTimeout(writer, reader);
                        }
        }
        public async Task SslStream_UntrustedCaWithCustomCallback_OK(bool usePartialChain)
        {
            var rnd   = new Random();
            int split = rnd.Next(0, certificates.serverChain.Count - 1);

            var clientOptions = new  SslClientAuthenticationOptions()
            {
                TargetHost = "localhost"
            };

            clientOptions.RemoteCertificateValidationCallback =
                (sender, certificate, chain, sslPolicyErrors) =>
            {
                // add our custom root CA
                chain.ChainPolicy.CustomTrustStore.Add(certificates.serverChain[certificates.serverChain.Count - 1]);
                chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
                // Add only one CA to verify that peer did send intermediate CA cert.
                // In case of partial chain, we need to make missing certs available.
                if (usePartialChain)
                {
                    for (int i = split; i < certificates.serverChain.Count - 1; i++)
                    {
                        chain.ChainPolicy.ExtraStore.Add(certificates.serverChain[i]);
                    }
                }

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

                return(result);
            };

            var serverOptions = new SslServerAuthenticationOptions();
            X509Certificate2Collection serverChain;

            if (usePartialChain)
            {
                // give first few certificates without root CA
                serverChain = new X509Certificate2Collection();
                for (int i = 0; i < split; i++)
                {
                    serverChain.Add(certificates.serverChain[i]);
                }
            }
            else
            {
                serverChain = certificates.serverChain;
            }

            serverOptions.ServerCertificateContext = SslStreamCertificateContext.Create(certificates.serverCert, certificates.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);
                        }
        }
        private async Task ConnectWithRevocation_WithCallback_Core(
            X509RevocationMode revocationMode,
            bool?offlineContext = false)
        {
            string offlinePart = offlineContext.HasValue ? offlineContext.GetValueOrDefault().ToString().ToLower() : "null";
            string serverName  = $"{revocationMode.ToString().ToLower()}.{offlinePart}.server.example";

            (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams();

            CertificateAuthority.BuildPrivatePki(
                PkiOptions.EndEntityRevocationViaOcsp | PkiOptions.CrlEverywhere,
                out RevocationResponder responder,
                out CertificateAuthority rootAuthority,
                out CertificateAuthority intermediateAuthority,
                out X509Certificate2 serverCert,
                subjectName: serverName,
                keySize: 2048,
                extensions: TestHelper.BuildTlsServerCertExtensions(serverName));

            SslClientAuthenticationOptions clientOpts = new SslClientAuthenticationOptions
            {
                TargetHost = serverName,
                RemoteCertificateValidationCallback = CertificateValidationCallback,
                CertificateRevocationCheckMode      = revocationMode,
            };

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                X509Certificate2 temp = new X509Certificate2(serverCert.Export(X509ContentType.Pkcs12));
                serverCert.Dispose();
                serverCert = temp;
            }

            await using (clientStream)
                await using (serverStream)
                    using (responder)
                        using (rootAuthority)
                            using (intermediateAuthority)
                                using (serverCert)
                                    using (X509Certificate2 issuerCert = intermediateAuthority.CloneIssuerCert())
                                        await using (SslStream tlsClient = new SslStream(clientStream))
                                            await using (SslStream tlsServer = new SslStream(serverStream))
                                            {
                                                intermediateAuthority.Revoke(serverCert, serverCert.NotBefore);

                                                SslServerAuthenticationOptions serverOpts = new SslServerAuthenticationOptions();

                                                if (offlineContext.HasValue)
                                                {
                                                    serverOpts.ServerCertificateContext = SslStreamCertificateContext.Create(
                                                        serverCert,
                                                        new X509Certificate2Collection(issuerCert),
                                                        offlineContext.GetValueOrDefault());

                                                    if (revocationMode == X509RevocationMode.Offline)
                                                    {
                                                        // Give the OCSP response a better chance to finish.
                                                        await Task.Delay(200);
                                                    }
                                                }
                                                else
                                                {
                                                    serverOpts.ServerCertificate = serverCert;
                                                }

                                                Task serverTask = tlsServer.AuthenticateAsServerAsync(serverOpts);
                                                Task clientTask = tlsClient.AuthenticateAsClientAsync(clientOpts);

                                                await TestConfiguration.WhenAllOrAnyFailedWithTimeout(clientTask, serverTask);
                                            }
Exemplo n.º 6
0
        public static X509Certificate2 GetClientCertificate()
        {
            X509Certificate2Collection certCollection = TestConfiguration.GetClientCertificateCollection();

            return(GetCertWithPrivateKey(certCollection));
        }
Exemplo n.º 7
0
        public async Task SslStream_ServerLocalCertificateSelectionCallbackReturnsNull_Throw()
        {
            VirtualNetwork network = new VirtualNetwork();

            var selectionCallback = new LocalCertificateSelectionCallback((object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] issuers) =>
            {
                return(null);
            });

            using (var clientStream = new VirtualNetworkStream(network, isServer: false))
                using (var serverStream = new VirtualNetworkStream(network, isServer: true))
                    using (var client = new SslStream(clientStream, false, AllowAnyServerCertificate))
                        using (var server = new SslStream(serverStream, false, null, selectionCallback))
                            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
                            {
                                await Assert.ThrowsAsync <NotSupportedException>(async() =>
                                                                                 await TestConfiguration.WhenAllOrAnyFailedWithTimeout(client.AuthenticateAsClientAsync(certificate.GetNameInfo(X509NameType.SimpleName, false)), server.AuthenticateAsServerAsync(certificate))
                                                                                 );
                            }
        }
Exemplo n.º 8
0
        public async Task NegotiateStream_StreamToStream_Authentication_EmptyCredentials_Fails()
        {
            string targetName = "testTargetName";

            // Ensure there is no confusion between DefaultCredentials / DefaultNetworkCredentials and a
            // NetworkCredential object with empty user, password and domain.
            NetworkCredential emptyNetworkCredential = new NetworkCredential("", "", "");

            Assert.NotEqual(emptyNetworkCredential, CredentialCache.DefaultCredentials);
            Assert.NotEqual(emptyNetworkCredential, CredentialCache.DefaultNetworkCredentials);

            VirtualNetwork network = new VirtualNetwork();

            using (var clientStream = new VirtualNetworkStream(network, isServer: false))
                using (var serverStream = new VirtualNetworkStream(network, isServer: true))
                    using (var client = new NegotiateStream(clientStream))
                        using (var server = new NegotiateStream(serverStream))
                        {
                            Assert.False(client.IsAuthenticated);
                            Assert.False(server.IsAuthenticated);

                            Task[] auth = new Task[2];

                            auth[0] = AuthenticateAsClientAsync(client, emptyNetworkCredential, targetName);
                            auth[1] = AuthenticateAsServerAsync(server);

                            await TestConfiguration.WhenAllOrAnyFailedWithTimeout(auth);

                            // Expected Client property values:
                            Assert.True(client.IsAuthenticated);
                            Assert.Equal(TokenImpersonationLevel.Identification, client.ImpersonationLevel);
                            Assert.Equal(true, client.IsEncrypted);
                            Assert.Equal(false, client.IsMutuallyAuthenticated);
                            Assert.Equal(false, client.IsServer);
                            Assert.Equal(true, client.IsSigned);
                            Assert.Equal(false, client.LeaveInnerStreamOpen);

                            IIdentity serverIdentity = client.RemoteIdentity;
                            Assert.Equal("NTLM", serverIdentity.AuthenticationType);
                            Assert.Equal(true, serverIdentity.IsAuthenticated);
                            Assert.Equal(targetName, serverIdentity.Name);

                            // Expected Server property values:
                            Assert.True(server.IsAuthenticated);
                            Assert.Equal(TokenImpersonationLevel.Identification, server.ImpersonationLevel);
                            Assert.Equal(true, server.IsEncrypted);
                            Assert.Equal(false, server.IsMutuallyAuthenticated);
                            Assert.Equal(true, server.IsServer);
                            Assert.Equal(true, server.IsSigned);
                            Assert.Equal(false, server.LeaveInnerStreamOpen);

                            IIdentity clientIdentity = server.RemoteIdentity;
                            Assert.Equal("NTLM", clientIdentity.AuthenticationType);

                            // TODO #5241: Behavior difference:
                            Assert.Equal(false, clientIdentity.IsAuthenticated);
                            // On .Net Desktop: Assert.Equal(true, clientIdentity.IsAuthenticated);

                            IdentityValidator.AssertHasName(clientIdentity, new SecurityIdentifier(WellKnownSidType.AnonymousSid, null).Translate(typeof(NTAccount)).Value);
                        }
        }
Exemplo n.º 9
0
        public async Task SslStream_StreamToStream_Alpn_NonMatchingProtocols_Fail()
        {
            TcpListener listener = new TcpListener(IPAddress.Loopback, 0);

            try
            {
                listener.Start();
                using (TcpClient client = new TcpClient())
                {
                    Task <TcpClient> serverTask = listener.AcceptTcpClientAsync();
                    await client.ConnectAsync(IPAddress.Loopback, ((IPEndPoint)listener.LocalEndpoint).Port);

                    using (TcpClient server = await serverTask)
                        using (SslStream serverStream = new SslStream(server.GetStream(), leaveInnerStreamOpen: false))
                            using (SslStream clientStream = new SslStream(client.GetStream(), leaveInnerStreamOpen: false))
                                using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
                                {
                                    SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions
                                    {
                                        ApplicationProtocols = new List <SslApplicationProtocol> {
                                            SslApplicationProtocol.Http2
                                        },
                                        ServerCertificate = certificate,
                                    };
                                    SslClientAuthenticationOptions clientOptions = new SslClientAuthenticationOptions
                                    {
                                        ApplicationProtocols = new List <SslApplicationProtocol> {
                                            SslApplicationProtocol.Http11
                                        },
                                        RemoteCertificateValidationCallback = AllowAnyServerCertificate,
                                        TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false),
                                    };

                                    // Test alpn failure only on platforms that supports ALPN.
                                    if (BackendSupportsAlpn)
                                    {
                                        Task t1 = Assert.ThrowsAsync <IOException>(() => clientStream.AuthenticateAsClientAsync(clientOptions, CancellationToken.None));
                                        try
                                        {
                                            await serverStream.AuthenticateAsServerAsync(serverOptions, CancellationToken.None);

                                            Assert.True(false, "AuthenticationException was not thrown.");
                                        }
                                        catch (AuthenticationException) { server.Dispose(); }

                                        await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1);
                                    }
                                    else
                                    {
                                        Task t1 = clientStream.AuthenticateAsClientAsync(clientOptions, CancellationToken.None);
                                        Task t2 = serverStream.AuthenticateAsServerAsync(serverOptions, CancellationToken.None);

                                        await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2);

                                        Assert.Equal(default(SslApplicationProtocol), clientStream.NegotiatedApplicationProtocol);
                                        Assert.Equal(default(SslApplicationProtocol), serverStream.NegotiatedApplicationProtocol);
                                    }
                                }
                }
            }
            finally
            {
                listener.Stop();
            }
        }
Exemplo n.º 10
0
        public async Task SslStream_TargetHostName_Succeeds(bool useEmptyName)
        {
            string tagetName = useEmptyName ? string.Empty : Guid.NewGuid().ToString("N");

            (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 = tagetName
                                };
                                clientOptions.RemoteCertificateValidationCallback =
                                    (sender, certificate, chain, sslPolicyErrors) =>
                                {
                                    SslStream stream = (SslStream)sender;
                                    if (useEmptyName)
                                    {
                                        Assert.Equal('?', stream.TargetHostName[0]);
                                    }
                                    else
                                    {
                                        Assert.Equal(tagetName, stream.TargetHostName);
                                    }

                                    return(true);
                                };

                                SslServerAuthenticationOptions serverOptions = new SslServerAuthenticationOptions();
                                serverOptions.ServerCertificateSelectionCallback =
                                    (sender, name) =>
                                {
                                    SslStream stream = (SslStream)sender;
                                    if (useEmptyName)
                                    {
                                        Assert.Equal('?', stream.TargetHostName[0]);
                                    }
                                    else
                                    {
                                        Assert.Equal(tagetName, stream.TargetHostName);
                                    }

                                    return(certificate);
                                };

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

                                if (useEmptyName)
                                {
                                    Assert.Equal('?', client.TargetHostName[0]);
                                    Assert.Equal('?', server.TargetHostName[0]);
                                }
                                else
                                {
                                    Assert.Equal(tagetName, client.TargetHostName);
                                    Assert.Equal(tagetName, server.TargetHostName);
                                }
                            }
        }
Exemplo n.º 11
0
 public ServerAsyncAuthenticateTest()
 {
     _log = TestLogging.GetInstance();
     _serverCertificate = TestConfiguration.GetServerCertificate();
 }