[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(); }
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 { } }
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); }
public static X509Certificate2 GetClientCertificate() { X509Certificate2Collection certCollection = TestConfiguration.GetClientCertificateCollection(); return(GetCertWithPrivateKey(certCollection)); }
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)) ); } }
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); } }
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(); } }
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); } } }
public ServerAsyncAuthenticateTest() { _log = TestLogging.GetInstance(); _serverCertificate = TestConfiguration.GetServerCertificate(); }