Home > other >  Custom X509CertificateValidator with TLS 1.2
Custom X509CertificateValidator with TLS 1.2

Time:01-28

I'm having a problem with a custom certificate validator when using TLS 1.2

I have set up a custom validator by inheriting from X509CertificateValidator and implementing the Validate() function.

However, for some reason Validate() function never gets called, and my client gets the error:

The caller was not authenticated by the service

The inner exception:

The request for security token could not be satisfied because authentication failed.

This works fine with TLS 1.0 (with that enabled, I can set a breakpoint in Validate() and it gets hit, but disabled, it doesn't.)

As advised by other questions, I have tried adding this both in the client and the server:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

...and this in the client's config file:

<AppContextSwitchOverrides value="Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols=false;Switch.System.Net.DontEnableSchUseStrongCrypto=false;;Switch.System.Net.DontEnableSystemDefaultTlsVersions=false" />

... and this in the server's web.config file:

<add key="AppContext.SetSwitch:Switch.System.Net.DontEnableSchUseStrongCrypto" value="false" />
<add key="AppContext.SetSwitch:Switch.System.Net.DontEnableSystemDefaultTlsVersions" value="false" />

Here is the code that creates the custom validator:

    protected override void ApplyConfiguration()   // Overrides ServiceHost.ApplyConfiguration()
    {

        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

        base.ApplyConfiguration();

        var binding = new MyAppHttpBinding();    // Custom object inheriting from CustomBinding - See below...

        AddServiceEndpoint(typeof(IMyService), binding);

        Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;

        var configuration = WebConfigurationManager.OpenWebConfiguration("~");
        var clientCertificate = configuration.GetCertificate("MyApp.ClientCertificate");
        var serviceCertificate = configuration.GetCertificate("MyApp.ServerCertificate");

        Credentials.ClientCertificate.Authentication.CustomCertificateValidator = new ThumbprintCertificateValidator(new[] { clientCertificate });
        Credentials.ServiceCertificate.Certificate = serviceCertificate;
    }

... and the Validate() function...

(Doesn't appear to hit this with just TLS 1.2)

   public void Validate(string thumbprint)
   {
        var valid = Thumbprints
            .Contains(thumbprint);

        if (!valid)
        {
            throw new SecurityTokenValidationException("Certificate thumbprint does not match any in certificate store.");
        }
    }

    /// <summary>
    /// Validates the certificate's thumbprint with those specified.
    /// </summary>
    public override void Validate(X509Certificate2 certificate)
    {
        var thumbprint = certificate.Thumbprint;

        Validate(thumbprint);
    }

Here is the initialisation code for MyAppHttpBinding called from its constructor

        var sslNegotiationBindingElement = SecurityBindingElement.CreateSslNegotiationBindingElement(true);

        sslNegotiationBindingElement.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;

        var secureConversationBindingElement = SecurityBindingElement.CreateSecureConversationBindingElement(sslNegotiationBindingElement);

        Elements.Add(new TransactionFlowBindingElement());
        Elements.Add(secureConversationBindingElement);
        Elements.Add(new TextMessageEncodingBindingElement());
        Elements.Add(new HttpTransportBindingElement());

CodePudding user response:

To use TLS, see the documentation enter image description here

  •  Tags:  
  • Related