2017-03-29 1 views
0

.NET Framework 4.0에서 VS 10을 사용하여 세 가지 C# 단위 테스트를 작성하여 다른 서버/클라이언트 프로토콜 설정에 대한 SslStream 동작을 확인했습니다.SslStream.AuthenticateAsServer hang

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는 서버 및 클라이언트 모두에서 사용할 동일한 프로토콜 (TLS 만)을 정의하므로 통과합니다. TestTlsSsl3의 실패도 완전히 이해할 수 있습니다 (서버가 TLS를 원하지만 클라이언트가 SSL3 만 재생하기를 원하기 때문에 AuthenticationException이 발생합니다).

"TestSsl3Tls"테스트가 동일한 AuthenticationException과 함께 실패 할 것으로 예상했지만 내 "서버 태스크가 제 시간에 끝나지 않았습니다"예외가 발생했습니다. 해고되었다. 디버깅 할 때 serverTask가 AuthenticateAsServer를 호출하는 동안 클라이언트 태스크 만 AuthenticationException을 수신합니다. 내 Wait 명령을 바꾸면 "TestSls3Tls"에 대해 AuthenticationException이 발생하고 "TestTlsSsl3"에 대해 "클라이언트가 제 시간에 끝나지 않았습니다.

정상적인 동작 인 AuthenticationException은 한쪽에만 발생하고 다른 쪽은 대기 중입니다 (새로운 인증 시도 또는 연결 해제 일 수 있음)?

답변

1

당신의 질문에 대한 답변을 알지 못하지만, 제 생각에는 이것이 버그이며 최근에 같은 문제가 있었고 클라이언트 보안 프로토콜을 제어 할 수 없어서 서버가 모두 멈추었습니다 시간.

sslstream을 삭제하여 해결했습니다. 그러면 AuthenticateAsServer에 Exception이 발생하고 서버가 계속 허용됩니다. 여기

은, 그래도 난 내가 ... 내 솔루션을 공유 할 것입니다 귀하의 질문에 내 동결 문제의 루트를 알려준 이후의 코드

// 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 ... 
    } 

입니다