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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With