На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Проверка сертификата клиента SslStream , ошибка RemoteCertificateNotAvailable
    Доброго времени суток.
    Создал корневой, серверный и клиентский сертификаты с помощью утилиты makecert. Установил их.
    Взял пример http://msdn.microsoft.com/en-us/library/system.net.security.sslstream(v=vs.80).aspx

    Код сервера
    ExpandedWrap disabled
              public static void RunServer(string certificate)
              {
                  X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                  store.Open(OpenFlags.ReadOnly);
                  X509CertificateCollection cert = store.Certificates.Find(X509FindType.FindBySubjectName, "Server", false);
                  serverCertificate = cert[0];
                  TcpListener listener = new TcpListener(IPAddress.Any, 443);
                  listener.Start();
                  while (true)
                  {
                      Console.WriteLine("Waiting for a client to connect...");
                      TcpClient client = listener.AcceptTcpClient();
                      ProcessClient(client);
                  }
              }
              static void ProcessClient(TcpClient client)
              {
                  SslStream sslStream = new SslStream(
                      client.GetStream(), false,
                      new RemoteCertificateValidationCallback(ValidateClientCertificate)); // <---- Добавил проверку сертификата клиента
                  try
                  {
                      sslStream.AuthenticateAsServer(serverCertificate, true, SslProtocols.Default, false);
                      DisplaySecurityLevel(sslStream);
                      DisplaySecurityServices(sslStream);
                      DisplayCertificateInformation(sslStream);
                      DisplayStreamProperties(sslStream);
       
                      sslStream.ReadTimeout = 5000;
                      sslStream.WriteTimeout = 5000;
                      Console.WriteLine("Waiting for client message...");
                      string messageData = ReadMessage(sslStream);
                      Console.WriteLine("Received: {0}", messageData);
       
                      byte[] message = Encoding.UTF8.GetBytes("Hello from the server.<EOF>");
                      Console.WriteLine("Sending hello message.");
                      sslStream.Write(message);
                  }
                  catch (AuthenticationException e)
                  {
                      Console.WriteLine("Exception: {0}", e.Message);
                      if (e.InnerException != null)
                      {
                          Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                      }
                      Console.WriteLine("Authentication failed - closing the connection.");
                      sslStream.Close();
                      client.Close();
                      return;
                  }
                  finally
                  {
                      sslStream.Close();
                      client.Close();
                  }
       
              public static bool ValidateClientCertificate(
            object sender,
            X509Certificate certificate,
            X509Chain chain,
            SslPolicyErrors sslPolicyErrors)
              {
                  SslPolicyErrors errors = sslPolicyErrors;
                  if (errors != SslPolicyErrors.None)
                  {
                      Console.WriteLine("Certificate error: {0} ", errors);
                  }
                  if (((errors & SslPolicyErrors.RemoteCertificateChainErrors) ==
                        SslPolicyErrors.RemoteCertificateChainErrors))
                  {
                      errors -= SslPolicyErrors.RemoteCertificateChainErrors;
                  }
       
                  if (((errors & SslPolicyErrors.RemoteCertificateNameMismatch) ==
                        SslPolicyErrors.RemoteCertificateNameMismatch))
                  {
                      errors -= SslPolicyErrors.RemoteCertificateNameMismatch;
                  }
       
                  if (errors == SslPolicyErrors.None)
                      return true;
       
                  Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
                  return false;
              }


    Код клиента
    ExpandedWrap disabled
              public static bool ValidateServerCertificate(
                    object sender,
                    X509Certificate certificate,
                    X509Chain chain,
                    SslPolicyErrors sslPolicyErrors)
              {
                  if (sslPolicyErrors == SslPolicyErrors.None)
                      return true;
                  return false;
              }
              public static void RunClient(string machineName, string serverName)
              {
                  X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                  store.Open(OpenFlags.ReadOnly);
                  X509CertificateCollection cert = store.Certificates.Find(X509FindType.FindBySubjectName, "Server", false);
                  TcpClient client = new TcpClient(machineName, 443);
                  Console.WriteLine("Client connected.");
                  SslStream sslStream = new SslStream(
                      client.GetStream(),
                      false,
                      new RemoteCertificateValidationCallback(ValidateServerCertificate),
                      null
                      );
                  try
                  {
                      sslStream.AuthenticateAsClient(serverName, cert, SslProtocols.Default, false);
                  }
                  catch (AuthenticationException e)
                  {
                      Console.WriteLine("Exception: {0}", e.Message);
                      if (e.InnerException != null)
                      {
                          Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                      }
                      Console.WriteLine("Authentication failed - closing the connection.");
                      client.Close();
                      return;
                  }
                  byte[] messsage = Encoding.UTF8.GetBytes("Hello from the client.<EOF>");
                  sslStream.Write(messsage);
                  sslStream.Flush();
                  string serverMessage = ReadMessage(sslStream);
                  Console.WriteLine("Server says: {0}", serverMessage);
                  client.Close();
                  Console.WriteLine("Client closed.");
              }

    Клиент проверяет сервер и подключается, а вот серверу никак не хочет подключать клиента. Чтобы я не пробовал - выдает постоянно ошибку RemoteCertificateNotAvailable - Удаленный сертификат недействителен согласно результатам проверки подлинности. Можете подсказать, что не так? куда копать?

    Добавлено
    Поторопился с постом, надо было просто добавить в код клиента и сервера
    ExpandedWrap disabled
      public static X509Certificate ValidateClientCertificate(
              object sender,
              string targetHost,
              X509CertificateCollection localCertificates,
              X509Certificate remoteCertificate,
              string[] acceptableIssuers)
              {
                  Console.WriteLine(" > Client is selecting a local certificate.");
                  if (acceptableIssuers != null &&
                      acceptableIssuers.Length > 0 &&
                      localCertificates != null &&
                      localCertificates.Count > 0)
                  {
                      // Use the first certificate that is from an acceptable issuer.
                      foreach (X509Certificate certificate in localCertificates)
                      {
                          string issuer = certificate.Issuer;
                          if (Array.IndexOf(acceptableIssuers, issuer) != -1)
                              return certificate;
                      }
                  }
                  if (localCertificates != null &&
                      localCertificates.Count > 0)
                      return localCertificates[0];
       
                  return null;
              }
      // SslStream создается теперь так
      ...
                  SslStream sslStream = new SslStream(
                      client.GetStream(),
                      false,
                      new RemoteCertificateValidationCallback(ValidateServerCertificate),
                     new LocalCertificateSelectionCallback(ValidateClientCertificate));
      ...
    Сообщение отредактировано: Malicious -
    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
    0 пользователей:


    Рейтинг@Mail.ru
    [ Script execution time: 0,0312 ]   [ 17 queries used ]   [ Generated: 19.03.24, 10:08 GMT ]