1
Vote

How to validate the service certificate passed by client using code in WCF

description

Below is my scenario what I am trying to do and wanted to know if anyone had thoughts on how I can achieve this -

I am trying to create a Gateway for my different web services and this gateway would perform the authentication using X509 certificates. We would be using client and service certs where we give the public key of our service cert to the client. Now when the client connect to the service they would be passing their client cert and this public key of the service cert.

I wanted to check if we can validate the service cert passed by the client in the service using code?

Why I am trying to do this is when the certs expire not all clients are ready to change/ update them at the same time so I was thinking if I can configure my service to use 2 certs with different names so if a client is passing one or the other they are authorize to access the service. So i.e. for a period of time we would have 2 service certs active at the same time and different clients can update the certs at different times.

I am not able to this today as I can specify only one cert thru config file to the service.

I would appreciate any help on this or any ideas to achieve this differently also would be helpful.

Thanks

comments

Miron1 wrote Aug 8, 2014 at 7:30 PM

For native MVC3+ you will have to create an native IISGlobalModule module in C++.

It is not that difficult since the code is provided verbatim by Daniel Vasquez Lopez. at the following URL:

http://blogs.msdn.com/b/danielvl/archive/2012/07/25/how-to-allow-self-signed-client-certificates-in-iis.aspx

Please do use the code verbatim as this is domain knowledge that is very tricky, changing even one line of it, without precise understanding of impact of change, can result in unpredictable code behavior.

This module sole purpose is to suppress rejection of client's certificate passed to the IIS hosted service.

The service itself will need to implement an custom authentication module answering to AuthenticateRequestHandler where you basically validate incoming client's certificate.

And than the client side is really easy since ServerCertificateValidationCallback event handle is exposed by WebRequestHandler.

For WCF, either IIS hosted or custom hosted ( windows service ) you will have a choice to use web.config serviceCredentials/clientCertificate/authentication/@certificateValidationMode="Custom"

or custom code which will require to implement something like this.
            ServiceCredentials serviceCredentials = new ServiceCredentials();

            // cert
            // default values
            object findValue = null;
            StoreLocation storeLocation = StoreLocation.LocalMachine;
            StoreName storeName = StoreName.My;
            X509FindType findType = X509FindType.FindByThumbprint;

            SetupServiceServiceCertificateFinder(out storeLocation, out storeName, out findType, out  findValue);

            serviceCredentials.ServiceCertificate.SetCertificate(storeLocation, storeName, findType, findValue);

            // certificate validation callback
            serviceCredentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
            serviceCredentials.ClientCertificate.Authentication.CustomCertificateValidator = new ClientCertificateValidator();
            serviceCredentials.ClientCertificate.Authentication.RevocationMode = X509RevocationMode.Offline;
            this.Description.Behaviors.Add(serviceCredentials);

            this.Credentials.ServiceCertificate.SetCertificate(
                     StoreLocation.LocalMachine,
                     StoreName.My,
                      X509FindType.FindByThumbprint,
                      "my_cert"
                );
using InitializeRuntime to invoke the routine during service boot. This method is exposed by ServiceHost or to be exact an class you define to inherit from ServiceHost.

The interesting calls are :
"this.Description.Behaviors.Add(serviceCredentials);" , this is how you can configure service to what I am used to using web.config.
and of course

serviceCredentials.ClientCertificate.Authentication.CustomCertificateValidator = new ClientCertificateValidator();

defines class inherit from X509CertificateValidator, which overrides public abstract void Validate(X509Certificate2 certificate) with verification routine of your choice, if you would like to custom authenticate client's certificate.

You probably can find web.config based implementation on the internet after brief search.


-- legal disclamer
Please take it as my personal post.
No employer or any other entity are party to this post.