Ejemplo n.º 1
0
        public async Task SslStream_SameCertUsedForClientAndServer_Ok()
        {
            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var client = new SslStream(stream1, true, AllowAnyCertificate))
                using (var server = new SslStream(stream2, true, AllowAnyCertificate))
                    using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
                    {
                        // Using the same certificate for server and client auth.
                        X509Certificate2Collection clientCertificateCollection =
                            new X509Certificate2Collection(certificate);

                        Task t1 = server.AuthenticateAsServerAsync(certificate, true, false);
                        Task t2 = client.AuthenticateAsClientAsync(
                            certificate.GetNameInfo(X509NameType.SimpleName, false),
                            clientCertificateCollection, false);


                        await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2);

                        if (!PlatformDetection.IsWindows7 ||
                            Capability.IsTrustedRootCertificateInstalled())
                        {
                            // https://technet.microsoft.com/en-us/library/hh831771.aspx#BKMK_Changes2012R2
                            // Starting with Windows 8, the "Management of trusted issuers for client authentication" has changed:
                            // The behavior to send the Trusted Issuers List by default is off.
                            //
                            // In Windows 7 the Trusted Issuers List is sent within the Server Hello TLS record. This list is built
                            // by the server using certificates from the Trusted Root Authorities certificate store.
                            // The client side will use the Trusted Issuers List, if not empty, to filter proposed certificates.

                            Assert.True(client.IsMutuallyAuthenticated);
                            Assert.True(server.IsMutuallyAuthenticated);
                        }
                    }
        }
        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;
                        }
        }
        public async Task Read_CorrectlyUnlocksAfterFailure()
        {
            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            var clientStream = new ThrowingDelegatingStream(stream1);

            using (var clientSslStream = new SslStream(clientStream, false, AllowAnyServerCertificate))
                using (var serverSslStream = new SslStream(stream2))
                {
                    await DoHandshake(clientSslStream, serverSslStream);

                    // Throw an exception from the wrapped stream's read operation
                    clientStream.ExceptionToThrow = new FormatException();
                    IOException thrown = await Assert.ThrowsAsync <IOException>(() => ReadAsync(clientSslStream, new byte[1], 0, 1));

                    Assert.Same(clientStream.ExceptionToThrow, thrown.InnerException);
                    clientStream.ExceptionToThrow = null;

                    // Validate that the SslStream continues to be usable
                    for (byte b = 42; b < 52; b++) // arbitrary test values
                    {
                        await WriteAsync(serverSslStream, new byte[1] {
                            b
                        }, 0, 1);

                        byte[] buffer = new byte[1];
                        Assert.Equal(1, await ReadAsync(clientSslStream, buffer, 0, 1));
                        Assert.Equal(b, buffer[0]);
                    }
                }
        }
Ejemplo n.º 4
0
        public async Task SslStream_StreamToStream_ServerInitiatedCloseNotify_Ok()
        {
            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var client = new SslStream(stream1, true, AllowAnyServerCertificate))
                using (var server = new SslStream(stream2))
                    using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
                    {
                        var handshake = new Task[2];

                        handshake[0] = server.AuthenticateAsServerAsync(certificate);
                        handshake[1] = client.AuthenticateAsClientAsync(certificate.GetNameInfo(X509NameType.SimpleName, false));

                        await Task.WhenAll(handshake).TimeoutAfter(TestConfiguration.PassingTestTimeoutMilliseconds);

                        var readBuffer = new byte[1024];

                        await server.ShutdownAsync();

                        int bytesRead = await client.ReadAsync(readBuffer, 0, readBuffer.Length);

                        // close_notify received by the client.
                        Assert.Equal(0, bytesRead);

                        await client.ShutdownAsync();

                        bytesRead = await server.ReadAsync(readBuffer, 0, readBuffer.Length);

                        // close_notify received by the server.
                        Assert.Equal(0, bytesRead);
                    }
        }
Ejemplo n.º 5
0
        public async Task SslStream_StreamToStream_DataAfterShutdown_Fail()
        {
            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var client = new SslStream(stream1, true, AllowAnyServerCertificate))
                using (var server = new SslStream(stream2))
                    using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
                    {
                        var handshake = new Task[2];

                        handshake[0] = server.AuthenticateAsServerAsync(certificate);
                        handshake[1] = client.AuthenticateAsClientAsync(certificate.GetNameInfo(X509NameType.SimpleName, false));

                        await Task.WhenAll(handshake).TimeoutAfter(TestConfiguration.PassingTestTimeoutMilliseconds);

                        var buffer = new byte[1024];

                        Assert.True(client.CanWrite);

                        await client.ShutdownAsync();

                        Assert.False(client.CanWrite);

                        await Assert.ThrowsAsync <InvalidOperationException>(() => client.ShutdownAsync());

                        await Assert.ThrowsAsync <InvalidOperationException>(() => client.WriteAsync(buffer, 0, buffer.Length));
                    }
        }
Ejemplo n.º 6
0
        public async Task SslStream_StreamToStream_HandshakeAlert_Ok()
        {
            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var client = new SslStream(stream1, true, AllowAnyServerCertificate))
                using (var server = new SslStream(stream2, true, FailClientCertificate))
                    using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
                    {
                        Task serverAuth = server.AuthenticateAsServerAsync(certificate);
                        await client.AuthenticateAsClientAsync(certificate.GetNameInfo(X509NameType.SimpleName, false));

                        byte[] buffer = new byte[1024];

                        // Schannel semantics require that Decrypt is called to receive an alert.
                        await client.WriteAsync(buffer, 0, buffer.Length);

                        var exception = await Assert.ThrowsAsync <IOException>(() => client.ReadAsync(buffer, 0, buffer.Length));

                        Assert.IsType <Win32Exception>(exception.InnerException);
                        var win32ex = (Win32Exception)exception.InnerException;

                        // The Schannel HResults for each alert are documented here:
                        // https://msdn.microsoft.com/en-us/library/windows/desktop/dd721886(v=vs.85).aspx
                        Assert.Equal(SEC_E_CERT_UNKNOWN, unchecked ((uint)win32ex.NativeErrorCode));

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

                        await Assert.ThrowsAsync <AuthenticationException>(() => server.WriteAsync(buffer, 0, buffer.Length));

                        await Assert.ThrowsAsync <AuthenticationException>(() => server.ReadAsync(buffer, 0, buffer.Length));
                    }
        }
Ejemplo n.º 7
0
        public async Task NegotiateStream_StreamToStream_Successive_CancelableReadsWrites()
        {
            if (!SupportsCancelableReadsWrites)
            {
                return;
            }

            byte[] recvBuf = new byte[s_sampleMsg.Length];

            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var clientStream = new DelayStream(stream1))
                using (var serverStream = new DelayStream(stream2))
                    using (var client = new NegotiateStream(clientStream))
                        using (var server = new NegotiateStream(serverStream))
                        {
                            await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                                AuthenticateAsClientAsync(client, CredentialCache.DefaultNetworkCredentials, string.Empty),
                                AuthenticateAsServerAsync(server));

                            clientStream.DelayMilliseconds = int.MaxValue;
                            serverStream.DelayMilliseconds = int.MaxValue;

                            var  cts = new CancellationTokenSource();
                            Task t   = WriteAsync(client, s_sampleMsg, 0, s_sampleMsg.Length, cts.Token);
                            Assert.False(t.IsCompleted);
                            cts.Cancel();
                            await Assert.ThrowsAnyAsync <OperationCanceledException>(() => t);

                            cts = new CancellationTokenSource();
                            t   = ReadAsync(server, s_sampleMsg, 0, s_sampleMsg.Length, cts.Token);
                            Assert.False(t.IsCompleted);
                            cts.Cancel();
                            await Assert.ThrowsAnyAsync <OperationCanceledException>(() => t);
                        }
        }
        public async Task Write_CorrectlyUnlocksAfterFailure()
        {
            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            var clientStream = new ThrowingDelegatingStream(stream1);

            using (var clientSslStream = new SslStream(clientStream, false, AllowAnyServerCertificate))
                using (var serverSslStream = new SslStream(stream2))
                {
                    await DoHandshake(clientSslStream, serverSslStream);

                    // Throw an exception from the wrapped stream's write operation
                    clientStream.ExceptionToThrow = new FormatException();
                    IOException thrown = await Assert.ThrowsAsync <IOException>(() => WriteAsync(clientSslStream, new byte[1], 0, 1));

                    Assert.Same(clientStream.ExceptionToThrow, thrown.InnerException);
                    clientStream.ExceptionToThrow = null;

                    // Validate that the SslStream continues to be writable. However, the stream is still largely
                    // unusable: because the previously encrypted data won't have been written to the underlying
                    // stream and thus not received by the reader, if we tried to validate this data being received
                    // by the reader, it would likely fail with a decryption error.
                    await WriteAsync(clientSslStream, new byte[1] {
                        42
                    }, 0, 1);
                }
        }
Ejemplo n.º 9
0
        public async Task DisposeAsync_Connected_ClosesStream()
        {
            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            var trackingStream1 = new CallTrackingStream(stream1);
            var trackingStream2 = new CallTrackingStream(stream2);

            var clientStream = new SslStream(trackingStream1, false, delegate { return(true); });
            var serverStream = new SslStream(trackingStream2, false, delegate { return(true); });

            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
            {
                await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                    clientStream.AuthenticateAsClientAsync(certificate.GetNameInfo(X509NameType.SimpleName, false)),
                    serverStream.AuthenticateAsServerAsync(certificate));
            }

            Assert.Equal(0, trackingStream1.TimesCalled(nameof(Stream.DisposeAsync)));
            await clientStream.DisposeAsync();

            Assert.NotEqual(0, trackingStream1.TimesCalled(nameof(Stream.DisposeAsync)));

            Assert.Equal(0, trackingStream2.TimesCalled(nameof(Stream.DisposeAsync)));
            await serverStream.DisposeAsync();

            Assert.NotEqual(0, trackingStream2.TimesCalled(nameof(Stream.DisposeAsync)));
        }
Ejemplo n.º 10
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);
                        }
        }
Ejemplo n.º 11
0
        public async Task NegotiateStream_StreamToStream_Authenticated_DisposeAsync(int delay)
        {
            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            await using (var client = new NegotiateStream(new DelayStream(stream1, delay)))
                await using (var server = new NegotiateStream(new DelayStream(stream2, delay)))
                {
                    Assert.False(client.IsServer);
                    Assert.False(server.IsServer);

                    Assert.False(client.IsAuthenticated);
                    Assert.False(server.IsAuthenticated);

                    Assert.False(client.IsMutuallyAuthenticated);
                    Assert.False(server.IsMutuallyAuthenticated);

                    Assert.False(client.IsEncrypted);
                    Assert.False(server.IsEncrypted);

                    Assert.False(client.IsSigned);
                    Assert.False(server.IsSigned);

                    await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                        AuthenticateAsClientAsync(client, CredentialCache.DefaultNetworkCredentials, string.Empty),
                        AuthenticateAsServerAsync(server));
                }
        }
        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(TestAuthenticateAsync, clientOptions));
                                Task t2 = Assert.ThrowsAsync <InvalidOperationException>(() => server.AuthenticateAsServerAsync(TestAuthenticateAsync, serverOptions));

                                await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2);
                            }
        }
        public async Task NegotiateStream_EndReadEndWriteInvalidParameter_Throws()
        {
            byte[] recvBuf = new byte[s_sampleMsg.Length];
            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var client = new NegotiateStream(stream1))
                using (var server = new NegotiateStream(stream2))
                {
                    await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                        client.AuthenticateAsClientAsync(CredentialCache.DefaultNetworkCredentials, string.Empty),
                        server.AuthenticateAsServerAsync());

                    await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                        Task.Factory.FromAsync(client.BeginWrite,
                                               (asyncResult) =>
                    {
                        NegotiateStream authStream = (NegotiateStream)asyncResult.AsyncState;
                        AssertExtensions.Throws <ArgumentNullException>(nameof(asyncResult), () => authStream.EndWrite(null));

                        IAsyncResult result = new MyAsyncResult();
                        AssertExtensions.Throws <ArgumentException>(nameof(asyncResult), () => authStream.EndWrite(result));
                    },
                                               s_sampleMsg, 0, s_sampleMsg.Length, client),
                        Task.Factory.FromAsync(server.BeginRead,
                                               (asyncResult) =>
                    {
                        NegotiateStream authStream = (NegotiateStream)asyncResult.AsyncState;
                        AssertExtensions.Throws <ArgumentNullException>(nameof(asyncResult), () => authStream.EndRead(null));

                        IAsyncResult result = new MyAsyncResult();
                        AssertExtensions.Throws <ArgumentException>(nameof(asyncResult), () => authStream.EndRead(result));
                    },
                                               recvBuf, 0, s_sampleMsg.Length, server));
                }
        }
        public async Task NegotiateStream_StreamContractTest_Success()
        {
            (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams();
            using (clientStream)
                using (serverStream)
                    using (var client = new NegotiateStream(clientStream))
                        using (var server = new NegotiateStream(serverStream))
                        {
                            Assert.False(client.CanSeek);
                            Assert.False(client.CanRead);
                            Assert.False(client.CanTimeout);
                            Assert.False(client.CanWrite);
                            Assert.False(server.CanSeek);
                            Assert.False(server.CanRead);
                            Assert.False(server.CanTimeout);
                            Assert.False(server.CanWrite);

                            Assert.Throws <InvalidOperationException>(() => client.ReadTimeout);
                            Assert.Throws <InvalidOperationException>(() => client.WriteTimeout);
                            Assert.Throws <NotSupportedException>(() => client.Length);
                            Assert.Throws <NotSupportedException>(() => client.Position);
                            Assert.Throws <NotSupportedException>(() => client.Seek(0, new SeekOrigin()));

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

                            Assert.True(client.CanRead);
                            Assert.True(client.CanWrite);
                            Assert.True(server.CanRead);
                            Assert.True(server.CanWrite);
                        }
        }
        public async Task NegotiateStream_EndAuthenticateInvalidParameter_Throws()
        {
            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var client = new NegotiateStream(stream1))
                using (var server = new NegotiateStream(stream2))
                {
                    await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                        Task.Factory.FromAsync(client.BeginAuthenticateAsClient, (asyncResult) =>
                    {
                        NegotiateStream authStream = (NegotiateStream)asyncResult.AsyncState;
                        AssertExtensions.Throws <ArgumentNullException>(nameof(asyncResult), () => authStream.EndAuthenticateAsClient(null));

                        IAsyncResult result = new MyAsyncResult();
                        AssertExtensions.Throws <ArgumentException>(nameof(asyncResult), () => authStream.EndAuthenticateAsClient(result));

                        authStream.EndAuthenticateAsClient(asyncResult);
                    }, CredentialCache.DefaultNetworkCredentials, string.Empty, client),

                        Task.Factory.FromAsync(server.BeginAuthenticateAsServer, (asyncResult) =>
                    {
                        NegotiateStream authStream = (NegotiateStream)asyncResult.AsyncState;
                        AssertExtensions.Throws <ArgumentNullException>(nameof(asyncResult), () => authStream.EndAuthenticateAsServer(null));

                        IAsyncResult result = new MyAsyncResult();
                        AssertExtensions.Throws <ArgumentException>(nameof(asyncResult), () => authStream.EndAuthenticateAsServer(result));

                        authStream.EndAuthenticateAsServer(asyncResult);
                    }, server));
                }
        }
 public void NegotiateStream_NullServicePrincipalName_Throws()
 {
     (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
     using (var client = new NegotiateStream(stream1))
         using (var server = new NegotiateStream(stream2))
         {
             AssertExtensions.Throws <ArgumentNullException>("servicePrincipalName", () => client.AuthenticateAsClient(CredentialCache.DefaultNetworkCredentials, null));
         }
 }
 public void NegotiateStream_NullCredential_Throws()
 {
     (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
     using (var client = new NegotiateStream(stream1))
         using (var server = new NegotiateStream(stream2))
         {
             AssertExtensions.Throws <ArgumentNullException>("credential", () => client.AuthenticateAsClient(null, TargetName));
         }
 }
Ejemplo n.º 18
0
 private async Task WithVirtualConnection(Func <SslStream, SslStream, Task> serverClientConnection, RemoteCertificateValidationCallback clientCertValidate)
 {
     (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams();
     using (SslStream server = new SslStream(serverStream, leaveInnerStreamOpen: false),
            client = new SslStream(clientStream, leaveInnerStreamOpen: false, clientCertValidate))
     {
         await serverClientConnection(server, client);
     }
 }
Ejemplo n.º 19
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);

            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var client = new NegotiateStream(stream1))
                using (var server = new NegotiateStream(stream2))
                {
                    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(IsEncryptedAndSigned, client.IsEncrypted);
                    Assert.False(client.IsMutuallyAuthenticated);
                    Assert.False(client.IsServer);
                    Assert.Equal(IsEncryptedAndSigned, client.IsSigned);
                    Assert.False(client.LeaveInnerStreamOpen);

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

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

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

                    Assert.False(clientIdentity.IsAuthenticated);
                    // On .NET Desktop: Assert.True(clientIdentity.IsAuthenticated);

                    IdentityValidator.AssertHasName(clientIdentity, new SecurityIdentifier(WellKnownSidType.AnonymousSid, null).Translate(typeof(NTAccount)).Value);
                }
        }
 public void NegotiateStream_DisposedState_Throws()
 {
     (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
     using (var client = new NegotiateStream(stream1))
         using (var server = new NegotiateStream(stream2))
         {
             client.Dispose();
             Assert.Throws <ObjectDisposedException>(() => client.AuthenticateAsClient());
         }
 }
        public void NegotiateStream_InvalidPolicy_Throws()
        {
            var policy = new ExtendedProtectionPolicy(PolicyEnforcement.Never);

            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var client = new NegotiateStream(stream1))
                using (var server = new NegotiateStream(stream2))
                {
                    // If ExtendedProtection is on, either CustomChannelBinding or CustomServiceNames must be set.
                    AssertExtensions.Throws <ArgumentException>(nameof(policy), () => server.AuthenticateAsServer(policy));
                }
        }
Ejemplo n.º 22
0
 public void NegotiateStream_StreamToStream_Flush_Propagated()
 {
     (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
     using (var stream = new CallTrackingStream(stream1))
         using (var negotiateStream = new NegotiateStream(stream))
             using (stream2)
             {
                 Assert.Equal(0, stream.TimesCalled(nameof(Stream.Flush)));
                 negotiateStream.Flush();
                 Assert.NotEqual(0, stream.TimesCalled(nameof(Stream.Flush)));
             }
 }
Ejemplo n.º 23
0
 public async Task SslStream_NestedAuth_Throws()
 {
     (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
     using (var ssl = new SslStream(stream1))
         using (stream2)
         {
             // Start handshake.
             Task task = ssl.AuthenticateAsClientAsync("foo.com", null, SslProtocols.Tls12, false);
             // Do it again without waiting for previous one to finish.
             await Assert.ThrowsAsync <InvalidOperationException>(() => ssl.AuthenticateAsClientAsync("foo.com", null, SslProtocols.Tls12, false));
         }
 }
Ejemplo n.º 24
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));
                        }
                    }
        }
        public async Task SslStream_StreamToStream_Dispose_Throws()
        {
            if (this is SslStreamStreamToStreamTest_SyncBase)
            {
                // This test assumes operations complete asynchronously.
                return;
            }

            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var clientSslStream = new SslStream(DelegateDelegatingStream.NopDispose(stream1), false, AllowAnyServerCertificate))
            {
                var serverSslStream = new SslStream(DelegateDelegatingStream.NopDispose(stream2));
                await DoHandshake(clientSslStream, serverSslStream);

                var  serverBuffer   = new byte[1];
                Task serverReadTask = ReadAsync(serverSslStream, serverBuffer, 0, serverBuffer.Length);
                await WriteAsync(serverSslStream, new byte[] { 1 }, 0, 1)
                .WaitAsync(TestConfiguration.PassingTestTimeout);

                // Shouldn't throw, the context is disposed now.
                // Since the server read task is in progress, the read buffer is not returned to ArrayPool.
                serverSslStream.Dispose();

                // Read in client
                var clientBuffer = new byte[1];
                await ReadAsync(clientSslStream, clientBuffer, 0, clientBuffer.Length);

                Assert.Equal(1, clientBuffer[0]);

                await WriteAsync(clientSslStream, new byte[] { 2 }, 0, 1);

                // We're inconsistent as to whether the ObjectDisposedException is thrown directly
                // or wrapped in an IOException.  For Begin/End, it's always wrapped; for Async,
                // it's only wrapped on .NET Framework.
                if (this is SslStreamStreamToStreamTest_BeginEnd || PlatformDetection.IsNetFramework)
                {
                    await Assert.ThrowsAsync <ObjectDisposedException>(() => serverReadTask);
                }
                else
                {
                    IOException serverException = await Assert.ThrowsAsync <IOException>(() => serverReadTask);

                    Assert.IsType <ObjectDisposedException>(serverException.InnerException);
                }

                await Assert.ThrowsAsync <ObjectDisposedException>(() => ReadAsync(serverSslStream, serverBuffer, 0, serverBuffer.Length));

                // Now, there is no pending read, so the internal buffer will be returned to ArrayPool.
                serverSslStream.Dispose();
                await Assert.ThrowsAsync <ObjectDisposedException>(() => ReadAsync(serverSslStream, serverBuffer, 0, serverBuffer.Length));
            }
        }
Ejemplo n.º 26
0
        public async Task NegotiateStream_StreamToStream_Authentication_TargetName_Success()
        {
            string targetName = "testTargetName";

            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var client = new NegotiateStream(stream1))
                using (var server = new NegotiateStream(stream2))
                {
                    Assert.False(client.IsAuthenticated);
                    Assert.False(server.IsAuthenticated);
                    Assert.False(client.IsMutuallyAuthenticated);
                    Assert.False(server.IsMutuallyAuthenticated);

                    Task[] auth = new Task[2];

                    auth[0] = AuthenticateAsClientAsync(client, CredentialCache.DefaultNetworkCredentials, 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(IsEncryptedAndSigned, client.IsEncrypted);
                    Assert.False(client.IsMutuallyAuthenticated);
                    Assert.False(client.IsServer);
                    Assert.Equal(IsEncryptedAndSigned, client.IsSigned);
                    Assert.False(client.LeaveInnerStreamOpen);

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

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

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

                    Assert.True(clientIdentity.IsAuthenticated);

                    IdentityValidator.AssertIsCurrentIdentity(clientIdentity);
                }
        }
Ejemplo n.º 27
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.º 28
0
        public async Task SslStream_UntrustedCaWithCustomCallback_Throws(bool customCallback)
        {
            string errorMessage;
            var    clientOptions = new  SslClientAuthenticationOptions()
            {
                TargetHost = "localhost"
            };

            if (customCallback)
            {
                clientOptions.RemoteCertificateValidationCallback =
                    (sender, certificate, chain, sslPolicyErrors) =>
                {
                    // Add only root CA to verify that peer did send intermediate CA cert.
                    chain.ChainPolicy.CustomTrustStore.Add(certificates.serverChain[certificates.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);
                };

                errorMessage = "RemoteCertificateValidationCallback";
            }
            else
            {
                // On Windows we hand whole chain to OS so they can always see the root CA.
                errorMessage = PlatformDetection.IsWindows ? "UntrustedRoot" : "PartialChain";
            }

            var serverOptions = new SslServerAuthenticationOptions();

            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);

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

                            Assert.Contains(errorMessage, e.Message);
                            // Server side should finish since we run custom callback after handshake is done.
                            await t2;
                        }
        }
        public async Task SslStream_StreamToStream_Authentication_Success(X509Certificate serverCert = null, X509Certificate clientCert = null)
        {
            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var client = new SslStream(stream1, false, AllowAnyServerCertificate))
                using (var server = new SslStream(stream2, false, delegate { return(true); }))
                {
                    await DoHandshake(client, server, serverCert, clientCert);

                    Assert.True(client.IsAuthenticated);
                    Assert.True(server.IsAuthenticated);
                }

            clientCert?.Dispose();
            serverCert?.Dispose();
        }
        public async Task NegotiateStream_DoubleAuthentication_Throws()
        {
            (Stream stream1, Stream stream2) = TestHelper.GetConnectedStreams();
            using (var client = new NegotiateStream(stream1))
                using (var server = new NegotiateStream(stream2))
                {
                    await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                        client.AuthenticateAsClientAsync(),
                        server.AuthenticateAsServerAsync());

                    await TestConfiguration.WhenAllOrAnyFailedWithTimeout(
                        Assert.ThrowsAsync <InvalidOperationException>(() => client.AuthenticateAsClientAsync()),
                        Assert.ThrowsAsync <InvalidOperationException>(() => server.AuthenticateAsServerAsync()));
                }
        }