3
votes

I'm getting the error mentioned in this question:

The X.509 certificate CN=Farm 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 processed, but terminated in a root certificate which is not trusted by the trust.

What I don't understand why I'm getting this error as the certificate I use for my request to the WCF service is added as shown below:

client.ClientCredentials.Peer.PeerAuthentication.CertificateValidationMode =     
    X509CertificateValidationMode.ChainTrust;        
client.ClientCredentials.ClientCertificate.SetCertificate(
    StoreLocation.CurrentUser,
    StoreName.My,
    X509FindType.FindBySerialNumber,
    "MyCertificatesSerialNumber" );

The certificate itself is a self-signed certificate in the store shown above. When I click on it to show the certification path, no errors are shown (the root certificate is also a self-signed certificate). The root certificate was manually imported into the trusted root certification authorities.

From the error message I would have expected that there was an error in the certification chain with one of my certificates, but there isn't. Any ideas?

Update

I'm using Internet Explorer 9 as my browser to access the webservice. Programmatically I'm using a C# console application.

3
See Step 2 blogs.msdn.com/b/jpsanders/archive/2009/09/16/… Make sure it's in the right store. If the WCF service is running in IIS then the "My" store will be the app pool identity, not you.ta.speot.is
@ta.speot.is Right now I'm trying to access the webservice from different system via a console application. Using the browser, I don't have any problems accessing the webservice, but running the console application (under the same logged on user account as the one for the browser) I get the error message. Even though the steps mentioned in your link shouldn't be relevant for my current set up, I added the certificates from my user to the respective computer's store, result is the same as before.Gorgsenegger
If your certificate is self-signed, how can it have a root? Also, which browser are you using? Firefox has its own trusted certificate store that is not shared by Windows. IE and Chrome use the Windows trust store.gtrig
@gtrig: I don't understand your question. Of course a self-signed certificate can have a root, you can see this in the certification path.Gorgsenegger
@Gorgsenegger: The certification path or chain is made up of the end (leaf) certificate and the certificate entity that signed it, and the certificate entity that signed that one, and so on, up to a self-signed root. If your certificate is self-signed, then no other certificate entity signed it, and no other certificates will appear in the path. If other certificates do appear in the path, then your certificate is not self-signed.gtrig

3 Answers

3
votes

I had exactly the same problem - my own trusted root CA which signed another certificate. No errors were shown in the certificate store.

It turned out that having a trusted root CA and a certificate is not sufficient! You also need a certificate revocation list! Take a look at this MSDN Link.

So simply create such a .crl and add it also to the trusted root certificate authorities and everything works fine!

makecert -crl -n "CN=CARoot" -r -sv CARoot.pvk CARoot.crl

or simply turn of the revocation list check:

...RevocationMode = X509RevocationMode.NoCheck;
2
votes

I had this problem - this is what I'd suggest:

On the server, make sure that the root cert is located on the "local computer" side of the computer, not "Current User". The other thing is that the SSL cert needs to be derived from the root cert. I eventually got it all to work using a script that included these lines:

rem creates root authority file and cert in localmachine\root and gives it the right to sign certs 
makecert.exe -a sha1 -n CN=RootCert RootCertName -sr LocalMachine -ss Root -sky signature -pe -r -sk MyNewKey -cy authority  

rem creates ssl cert, puts it in the currentuser\Personal store, signing it based on the root cert
makecert.exe  -n cn=HostURL SSLCertName -is root -ic RootCertName  -sky exchange -pe -sv SSLCertPrivateKeyName -eku 1.3.6.1.5.5.7.3.1

It's complicated, tedious stuff. You just have to keep at it.

1
votes

I faced a similar issue while trying to connect to a self hosted WCF service using net.tcp binding. I already had the self signed root CA certificate installed in the CurrentUser certificate store, client was using a certificate signed by the root CA cert.

Installing the root CA certificate in LocalComputer certificate store fixed the error "A certificate chain could not be built to a trusted root authority". My WCF Server process runs using current user account hence this step was not obvious.

The next error was "The revocation function was unable to check revocation for the certificate"

To fix this, I created an empty Certificate Revocation List for the root CA cert and then installed the CRL in the LocalComputer certificate store. (Please check this link for details : https://msdn.microsoft.com/en-us/library/ff648732.aspx)

I also set the revocation check mode to Offline for both server and client certificates.

defaultCredentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.Offline;
            defaultCredentials.ServiceCertificate.Authentication.CertificateValidationMode =
                X509CertificateValidationMode.ChainTrust;

Now I don't have to turn off certificate validation or use different validation mode for development (In my case production code will also use self signed certificates for the time being)