Search code examples
c#wcfwcf-bindingwcf-security

Why does service allow clients with wrong (but trusted) certificates?


I set expected client certificate to "A":

        host.Credentials.ClientCertificate.SetCertificate("A", ...);
        host.Credentials.ServiceCertificate.SetCertificate("B", ...);

Binding:

new NetTcpBinding
                    {
                        Security =
                        {
                            Mode = SecurityMode.TransportWithMessageCredential,
                            Transport = { ProtectionLevel = ProtectionLevel.EncryptAndSign },
                            Message = { ClientCredentialType = MessageCredentialType.Certificate }
                        }
                    }

I expect the server to allow only clients with certificate "A". But instead it allows other trusted certificates too. I've changed client app.config to use "B" instead of "A" and it still works!

What's wrong in my setup?


Solution

  • the

    host.Credentials.ClientCertificate.SetCertificate("A", ...);
    

    does not mean that only clients with certificate A are allowed to connect.

    If you want to allow only some kinds of certificates, you need to inspect the CertificateValidator on the serverside.

    take a look: https://msdn.microsoft.com/en-us/library/aa354512%28v=vs.110%29.aspx

    if you have more questions feel free to ask me

    EDIT:

    public class CustomX509CertificateValidator : X509CertificateValidator
    {
      public override void Validate ( X509Certificate2 certificate )
      {
       // Only accept self-issued certificates for example
       if (certificate.Subject != certificate.Issuer)
         throw new Exception("Certificate is not self-issued");
       }
    }
    

    And then:

    serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
    serviceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = new CustomX509CertificateValidator();