When you use WCF transport and message security, you will inevitably have to deal with a service certificate. Here I am going to list a few problems you might have when using service certificate and their normal error messages
There is one exception in the use of service certificate, which is using message security with none authentication(anonymous) , the requirement of that certificate is quite relaxed. Because it is not using real TLS nego but SPNego protocol when there is no client authentication involved. I find it that any valid certificate will be accepted by client. Otherwise the service must match following conditions to be happily consumed by clients
- Must have matching subject name with the host name
The Subject name CN=XXXX must match with the host, otherwise validation will fail.
And error message could be like:
Identity check failed for outgoing message. The expected DNS identity of the remote endpoint was ‘xxxxx.com’ but the remote endpoint provided DNS claim ‘yyy.com’. If this is a legitimate remote endpoint, you can fix the problem by explicitly specifying DNS identity ‘yyy.com’ as the Identity property of EndpointAddress when creating channel proxy.
So the solution is also suggested here, try to explicitly specify DNS identity in client configuration
- Chain build error or Revocation check error
The root CA of service certificate should be trusted by client, and Revocation check should succeed if is needed.
And error message could be like:
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
The X.509 certificate CN=xxx.com chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. The revocation function was unable to check revocation for the certificate.
Some time it is guaranteed that chain trust is indeed in place, but not all certificates CRL is enabled, especially self signed certificates, there is no revocation check supported, but as a default, the client is always wanting to do Revocation check of service certificate.
You can solve this problem by providing a Good service certificate, when you do not have control on server side, as a workaround, it is suggested that you can change CertificationValidationMode or RevocationMode to bypass these deficiencies
In Code you can
WSHttpBinding binding = new WSHttpBinding(); binding.Security.Mode = SecurityMode.Message; binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate; using (ChannelFactory<WCFContract.ICalculator> scf = new ChannelFactory<WCFContract.ICalculator>(binding, namedServerUri + @"WSHttpService.svc ")) { // Specify a certificate to use for authenticating the client. scf.Credentials.ClientCertificate.SetCertificate( "CN=tempClientcert", StoreLocation.LocalMachine, StoreName.My); X509ServiceCertificateAuthentication myAuthProperties = scf.Credentials.ServiceCertificate.Authentication; // default is X509CertificateValidationMode.ChainTrust // myAuthProperties.CertificateValidationMode = // X509CertificateValidationMode.None; // default is online // myAuthProperties.RevocationMode = // X509RevocationMode.NoCheck; WCFContract.ICalculator channel = scf.CreateChannel(); var s = channel.Add(1, 2); }
Just be careful about the commented out lines in the code, you can turn off certificate validation / RevocationMode
- Private key issue
Service account has to have access to the private key of service certificate
Error message could be like:
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
The certificate ‘CN=xxxxx’ must have a private key. The process must have access rights for the private key.
Potentially you could have installed the certificate into CurrentUser store, even you grant the permission to the private key in that case, you still have access issues as CurrentUser store stores private keys under folders dependent on the user, always install certificates into LocalMachine even using them as client certificates, in this case, it is just granting private key permission through Manage private key… from MMC. Only one reason I can think of warrants installing certificate into CurrentUser, which is access service from browser. As a client of WCF service we almost try to use service in our own application.
As for client certificate, mostly it needs private key access on the client pc, the RootCA of client certificate must be in Server’s trusted authorities. There is a bug in client certificate authentication causing server trusted authorities list being truncated, therefore valid client certificate being denied