Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Certificate Chain, verify programmatically

I'm trying to use certificates programmatically, rather than using the store. I'm creating X509Certificate2's with filename and password.

This works fine when I have manually added the root certificate to the Certificate Store in Trusted People. However, I'd rather not have to do that on every deployment - I'd rather deal with it programmatically too.

When I remove the root certificate from the Certificate Store I get an exception.

Everything I have read seems to say that I have to manually added the root certificate to the Certificate Store, or the Trust Chain won't work.

Question: Is there a programmatic way to set up the Trust Chain, so I don't have to do it manually?

The code looks like:

        var serverCert = new X509Certificate2("FullPathToMyCertificate.cer", "Password");
        Client.ClientCredentials.ServiceCertificate.DefaultCertificate = serverCert;

The exception, which occures when I try to use the Client, is:

System.IdentityModel.Tokens.SecurityTokenValidationException 

The X.509 certificate CN=notrealcertname, OU=TPA, OU=BMP, OU=Projects, O=Somebody, C=US is not in the trusted people store. 
The X.509 certificate CN=notrealcertname, OU=TPA, OU=BMP, OU=Projects, O=Somebody, C=US chain building failed. 
The certificate that was used has a trust chain that cannot be verified. 
Replace the certificate or change the certificateValidationMode. 
A certificate chain could not be built to a trusted root authority.
like image 961
Steve Avatar asked Aug 25 '11 19:08

Steve


1 Answers

The used component verifies the chain by default - when the chain can't be verified you get that exception. IF you want to do everything including verification of the chain in code then you need to implement "custom validation" and integrate that into the WCF Host:

Client.ServiceCertificate.Authentication.CertificateValidationMode =
              X509CertificateValidationMode.Custom;
Client.ServiceCertificate.Authentication.CustomCertificateValidator =
    new MyCertificateValidator();

Another option would be to disable validation altogether (NOT for production !!!)

Client.ServiceCertificate.Authentication.CertificateValidationMode =
              X509CertificateValidationMode.None;

EDIT - after comment:

For validating the chain yourself you should take a look at X509Chain and X509Store - to get an idea how such a chain verification could be implemented take a look at Mono's implementation of the Verify... basically you use the Find method to search a X509Certificate2Collection for the parent and so on... verification criteria with a custom validation is up to you (valid signature, not expired...).

some reference links at MSDN:

  • http://msdn.microsoft.com/en-us/library/system.servicemodel.security.x509servicecertificateauthentication.certificatevalidationmode.aspx

  • http://msdn.microsoft.com/en-us/library/system.identitymodel.selectors.x509certificatevalidator.aspx

  • http://msdn.microsoft.com/en-us/library/ms733806.aspx

like image 143
Yahia Avatar answered Oct 11 '22 01:10

Yahia