SslStream.AuthenticateAsServer挂起 [英] SslStream.AuthenticateAsServer hangs

查看:246
本文介绍了SslStream.AuthenticateAsServer挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用VS 10和.NET Framework 4.0,我编写了三个c#单元测试来检查不同服务器/客户端协议设置的SslStream行为。

  private void InternalTestSsl(SslProtocols serverProtocols,SslProtocols clientProtocols)
{
X509Certificate2证书= RetrieveServerCertificate();
var server = new TcpListener(new IPEndPoint(IPAddress.Any,20000));
server.Start();
try
{
//创建并执行服务器操作任务
var serverTask = new Task(()=>
{
TcpClient connectionToClient = server.AcceptTcpClient();
var sslStream = new SslStream(connectionToClient.GetStream(),false,(a,b,c,d)=> true,(a,b,c,d,e) =>证书);
sslStream.AuthenticateAsServer(certificate,false,serverProtocols,true);
Assert.IsTrue(sslStream.IsAuthenticated);
});
serverTask.Start();

//为客户端操作创建并执行任务
var clientTask = new Task(()=>
{
var clientConnection = new TcpClient();
clientConnection.Connect(new IPEndPoint(IPAddress.Loopback,20000));
var sslStream = new SslStream(clientConnection.GetStream(),false,(a,b,c,d)=> true ,((a,b,c,d,e)=> null);
sslStream.AuthenticateAsClient(Environment.MachineName,null,clientProtocols,true);
Assert.IsTrue(sslStream.IsAuthenticated);
});
clientTask.Start();

//等待服务器和客户端任务都完成,检查结果
if(!serverTask.Wait(TimeSpan.FromSeconds(1)))
{
抛出新的异常(服务器任务没有及时结束。);
}
if(!clientTask.Wait(TimeSpan.FromSeconds(1)))
{
抛出新的异常(客户端任务未及时结束。);
}
}
最后
{
server.Stop();
}
}

[TestMethod]
public void TestTlsTls()
{
InternalTestSsl(SslProtocols.Tls,SslProtocols.Tls);
}

[TestMethod]
公共无效TestTlsSsl3()
{
InternalTestSsl(SslProtocols.Tls,SslProtocols.Ssl3);
}

[TestMethod]
公共无效TestSsl3Tls()
{
InternalTestSsl(SslProtocols.Ssl3,SslProtocols.Tls);
}

TestTlsTls通过,因为服务器和客户端都定义了要使用的相同协议(仅TLS)。 TestTlsSsl3的失败也是完全可以理解的(抛出AuthenticationException异常是因为服务器希望使用TLS,但是客户端希望只使用SSL3。)



I期望测试 TestSsl3Tls由于相同的AuthenticationException而失败,但是我的自定义异常服务器任务未及时终止。被解雇。调试时,我看到只有客户端任务会收到AuthenticationException,而serverTask仍在AuthenticateAsServer调用中。交换我的Wait命令的结果相反: TestSsl3Tls的AuthenticationException, TestTlsSsl3的客户端没有及时结束。



正常的行为是只是在一侧抛出AuthenticationException,另一侧等待(可能是尝试进行新的身份验证或断开连接)?

解决方案

我不知道您的问题是否正常的答案,但是我认为这是一个错误,最近我遇到了同样的问题,并且由于无法控制客户端安全协议,我的服务器一直处于冻结状态。 / p>

我通过处理sslstream来解决它,这在AuthenticateAsServer中导致异常,因此允许我的服务器继续运行。



这是代码片段

  //等待服务器和客户端任务均完成,检查结果
是否(!serverTask.Wait(TimeSpan.FromSeconds(1)))
{
sslStream.Di spose(); //此行将导致服务器任务(AuthenticateAsServer)发生异常,该异常使服务器可以继续...
}

由于您的问题使我成为冻结问题的根源,尽管我会分享我的解决方案...


Using VS 10 with .NET framework 4.0, I have written three c# unit tests to check the SslStream behaviour for different server / client protocol settings.

  private void InternalTestSsl(SslProtocols serverProtocols, SslProtocols clientProtocols)
  {
     X509Certificate2 certificate = RetrieveServerCertificate();
     var server = new TcpListener(new IPEndPoint(IPAddress.Any, 20000));
     server.Start();
     try
     {
        // create and execute a task for server operations
        var serverTask = new Task(() =>
        {
           TcpClient connectionToClient = server.AcceptTcpClient();
           var sslStream = new SslStream(connectionToClient.GetStream(), false, (a, b, c, d) => true, (a, b, c, d, e) => certificate);
           sslStream.AuthenticateAsServer(certificate, false, serverProtocols, true);
           Assert.IsTrue(sslStream.IsAuthenticated);
        });
        serverTask.Start();

        // create and execute a task for client operations
        var clientTask = new Task(() =>
        {
           var clientConnection = new TcpClient();
           clientConnection.Connect(new IPEndPoint(IPAddress.Loopback, 20000));
           var sslStream = new SslStream(clientConnection.GetStream(), false, (a, b, c, d) => true, (a, b, c, d, e) => null);
           sslStream.AuthenticateAsClient(Environment.MachineName, null, clientProtocols, true);
           Assert.IsTrue(sslStream.IsAuthenticated);
        });
        clientTask.Start();

        // wait for both server and client task to finish, check results
        if (!serverTask.Wait(TimeSpan.FromSeconds(1)))
        {
           throw new Exception("Server task did not end in time.");
        }
        if (!clientTask.Wait(TimeSpan.FromSeconds(1)))
        {
           throw new Exception("Client task did not end in time.");
        }
     }
     finally
     {
        server.Stop();
     }
  }

  [TestMethod]
  public void TestTlsTls()
  {
     InternalTestSsl(SslProtocols.Tls, SslProtocols.Tls);
  }

  [TestMethod]
  public void TestTlsSsl3()
  {
     InternalTestSsl(SslProtocols.Tls, SslProtocols.Ssl3);
  }

  [TestMethod]
  public void TestSsl3Tls()
  {
     InternalTestSsl(SslProtocols.Ssl3, SslProtocols.Tls);
  }

TestTlsTls passes as both server and client define the same protocols to be used (only TLS). The failure of TestTlsSsl3 is also completely understandable (an AuthenticationException is thrown because the server wants TLS to be used, but the client want´s to solely play SSL3).

I expected the test "TestSsl3Tls" to fail with the same AuthenticationException, but instead, my custom exception "Server task did not end in time." was fired. When debugging, I see that only the client task receives an AuthenticationException while the serverTask remains in the call of AuthenticateAsServer. Swapping my Wait commands results in the opposite: AuthenticationException for "TestSsl3Tls", "Client did not end in time" for "TestTlsSsl3".

Is that the normal behaviour, the AuthenticationException only being thrown on one side, the other side waiting (may be for a new authentication attempt or a disconnect)?

解决方案

I dont know the answer to your question whether this behaviour is normal, but in my opinion this is a bug and I recently had the same issue and since I could not control the client security protocol, my server ended up freezing all the time.

I solved it by Disposing the sslstream, which causes an Exception in the AuthenticateAsServer and thus allowed my server to continue.

here is the code fragment

    // wait for both server and client task to finish, check results
    if (!serverTask.Wait(TimeSpan.FromSeconds(1)))
    {
       sslStream.Dispose(); // this line will cause an exception in the server task (AuthenticateAsServer), which allows the server to continue ...
    }

Since your question led me to the root of my freezing issue, I though I will share my solution ...

这篇关于SslStream.AuthenticateAsServer挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆