Как проверить, что сертификат имеет конкретный ЦС в его цепочке сертификатов при использовании WCF

У меня есть требование, чтобы сертификат x509, который клиент представляет во время сеанса WCF, имел в своей цепочке определенный центр сертификации.

Я знаю, что могу программно проверить цепочку сертификатов с помощью ChainElements [index].

Но я не уверен, как это сделать, все еще интегрируясь с WCF с использованием файлов конфигурации.

В настоящее время WCF настраивается в файле конфигурации, см. Ниже:

<services>
  <service name="SampleService" behaviorConfiguration="wsHttpBehavior">
    <endpoint name="SampleEndPoint"
              address="http://localhost:70000/SampleService.svc"
              binding="wsHttpBinding"
              bindingConfiguration="wsHttpBinding"
              contract="SampleApp.ISampleService">
    </endpoint>
  </service>
</services>

<bindings>
  <wsHttpBinding>
    <binding name="wsHttpBinding">
      <reliableSession enabled="true" ordered="true" />
      <security>
        <message clientCredentialType="Certificate" />
      </security> 
    </binding>
  </wsHittpBinding>
</bindings>

<behaviors>
  <serviceBehaviors>
    <serviceMetadata httpGetEnabled="true" />
    <serviceDebug includeExceptionDetailInFaults="false" />
    <serviceCredentials>
      <serviceCertificate findValue="aa aa aa" 
                          storeLocation="LocalMachine" 
                          storeName="My" 
                          x509FindType="FindBySerialNumber" />
    </serviceCredentials>
  <serviceBehaviors>
</behaviors>

Могу ли я что-нибудь сделать в файле конфигурации, чтобы сообщить ему, чтобы предоставленный клиентский сертификат содержал конкретный центр сертификации. Или мне нужно подключиться к каналу WCF для этого? Это вообще возможно?


person SBurris    schedule 06.07.2012    source источник


Ответы (1)


Этого можно добиться с помощью расширяемости WCF (Введение в расширяемость).

В качестве конкретного примера (как: создать службу, которая использует настраиваемый валидатор сертификатов )

Используя эту информацию и информацию, которую я собрал из этого сообщения StackoverFlow, я создал службу, которая проверяет действительность сертификата, а также подтверждает, что он был получен от определенного центра сертификации.

Код:

public class CustomX509CertificateValidator : X509CertificateValidator
  {
    public override void Validate(System.Security.Cryptography.X509Certificates.X509Certificate2 certificate)
    {
      var ch = new X509Chain();

      //RevocationMode Enumeration
      //http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509revocationmode.aspx
      ch.ChainPolicy.RevocationMode = X509RevocationMode.Online;

      //RevocationFlag Enumeration
      //http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509revocationflag.aspx
      ch.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;

      //The time span that elapsed during online revocation verification or downloading the 
      //certificate revocation list (CRL)
      ch.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(1000);

      //VerificationFlags Enumeration
      //http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509verificationflags.aspx 
      ch.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;

      //The time that the certificate was verified expressed in local time
      ch.ChainPolicy.VerificationTime = DateTime.Now;

      ch.Build(certificate);

      //Check to see if the CA is a specific one
      if (ch.ChainElements[ch.ChainElements.Count - 1].Certificate.IssuerName.Name != "CN=Something, OU=PKI...,")
      {
        throw new SecurityTokenValidationException("Certificate was not issued by a trusted issuer");
      }

      foreach (X509ChainStatus s in ch.ChainStatus)
      {
        string str = s.Status.ToString();
        Console.WriteLine("str: " + str);
      }

      //Check to see if the current certificate is revoced in the current system (does this not happen in the above?
      X509Store store = new X509Store(StoreName.Disallowed, StoreLocation.LocalMachine);
      store.Open(OpenFlags.ReadOnly);
      bool isRevoked = store.Certificates.Contains(certificate);
      store.Close();

      if (isRevoked)
      {
        throw new SecurityTokenValidationException("Certificate is revoked");
      }

      if (certificate.Verify() == false)
      {
        throw new SecurityTokenValidationException("Certificate cannot be verified");
      }
    }
  }

web.config

<behaviors>
  <serviceBehaviors>
    <behavior name="secureHttpBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
      <serviceCredentials>
        <serviceCertificate  findValue="00 b7 70" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySerialNumber"/>
        <clientCertificate>
          <authentication certificateValidationMode="Custom"               
                          customCertificateValidatorType="WcfWebServer.CustomX509CertificateValidator, WcfWebServer"/>
        </clientCertificate>
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>
person SBurris    schedule 11.07.2012