title: Custom X509CertificateValidator with BasicHttpSecurityMode.Transport?
body: <p>Is there an easy way to tie custom X509 cert validation to BasicHttpBinding (or CustomHttpBinding for the same matter, which will implement transport-only security)?</p>
  
  <p><strong>EDIT1:</strong> I added a ServerCertificateValidationCallback to the code for the sake of showing that it doesn't fire up either</p>
  
  <p>Here's what I'm trying to do: </p>
  
  <p>1) wrote custom X509CertificateValidator:</p>
  
  <pre><code>public class MyX509Validator : X509CertificateValidator
  {
      public override void Validate(X509Certificate2 certificate)
      {
          Console.WriteLine("Incoming validation: subj={0}, thumb={1}",
                  certificate.Subject, certificate.Thumbprint);
      }
  }
  </code></pre>
  
  <p>2) created host:</p>
  
  <pre><code>var soapBinding = new BasicHttpBinding() { Namespace = "http://test.com" };
  soapBinding.Security.Mode = BasicHttpSecurityMode.Transport;
  soapBinding.Security.Transport.ClientCredentialType =
              HttpClientCredentialType.Certificate;
  
  var sh = new ServiceHost(typeof(Service1), uri);
  sh.AddServiceEndpoint(typeof(IService1), soapBinding, "");
  sh.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine,
             StoreName.My, X509FindType.FindBySubjectName, "localhost");
  sh.Credentials.ClientCertificate.Authentication.CertificateValidationMode =
             System.ServiceModel.Security.X509CertificateValidationMode.Custom;
  sh.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = 
             new MyX509Validator();
  System.Net.ServicePointManager.ServerCertificateValidationCallback += 
             delegate(object sender, X509Certificate certificate, 
                      X509Chain chain, SslPolicyErrors sslPolicyErrors)
             {
                  Console.WriteLine("Incoming validation: subj={0}, thumb={1}",
                      certificate.Subject, certificate.GetIssuerName());
                  return true;
             };
  sh.Open();
  </code></pre>
  
  <p>3) Created WCF Client:</p>
  
  <pre><code>var binding = new BasicHttpBinding();
  binding.Security.Mode = BasicHttpSecurityMode.Transport;
  binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
  var cli = new ServiceReference2.Service1Client(binding, 
             new EndpointAddress("https://localhost:801/Service1"));
  cli.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, 
             StoreName.My, X509FindType.FindBySubjectName, "localhost");
  cli.HelloWorld();
  </code></pre>
  
  <p>Authentication works fine, but <code>MyX509Validator.Validate()</code> never gets called. I have suspicion that <code>X509CertificateValidator</code> only works on message security, not on transport. Is that right? Is there something I could do to override transport-level cert validation?</p>