Coral Doe
Coral Doe

Reputation: 1941

The client WCF cannot connect to the server WCF without having the server certificate on local machine

The scenario is this: there are 2 WCF Web Services, one a client (WCFClient), one a server (WCFServer), deployed on different machines. I needed certificate communication between the two of them.

On the server WCF I have set the binding to use certificates as client credential type.

<security mode="Message">
      <message clientCredentialType="Certificate" />
</security>

Also, in the behaviour section, among other settings, I have

<serviceBehaviors>
      <behavior name="Server.ServiceBehavior">                  
          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </clientCertificate>
            <serviceCertificate findValue="Server"
            storeLocation="LocalMachine"
            storeName="TrustedPeople"
            x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
</serviceBehaviors>

On the client WCF Service I added this endpoint behaviour

<endpointBehaviors>
   <behavior name="CustomBehavior">
     <clientCredentials>
       <clientCertificate findValue="Client" 
                          x509FindType="FindBySubjectName" 
                          storeLocation="LocalMachine" 
                          storeName="TrustedPeople" />
       <serviceCertificate>            
         <authentication certificateValidationMode="PeerTrust"/>
       </serviceCertificate>
     </clientCredentials>
   </behavior>
 </endpointBehaviors>

When I wanted to test my services, I had an error message:

The service certificate is not provided for target 'http://blablabla...'. Specify a service certificate in ClientCredentials.

So I started checking things out on the Internet. After trying many things, the only thing that actually worked is adding this on my client:

<serviceCertificate>
         <defaultCertificate findValue="Server"
                             storeLocation="LocalMachine"
                             storeName="TrustedPeople"
                             x509FindType="FindBySubjectName" />
         <authentication certificateValidationMode="PeerTrust"/>
       </serviceCertificate>

As you might think, yes, this means I need the Server certificate on my client machine. Which is clearly a very bad thing. It works for my testing purposes, but it is an unacceptable for deployment.

I would want to understand what really could cause that error message and what the solution may be.

Later edit: In this project the client must not have the server certificate (even without having the private key). This is the specification of the system and it's quite difficult (in bureaucracy terms) to go beyond this. There will be multiple clients, each with the client WCF service running, and each should know nothing more that their own certificate. The server will know the server certificate and all the clients certificate.

Upvotes: 3

Views: 2123

Answers (3)

Coral Doe
Coral Doe

Reputation: 1941

I actually forgot about this question, but at that time I have found the solution.

My actual problem was that I was using a basicHttpBinding for the communication I wanted to secure. basicHttpBinding implies ussing that serviceCredential part. http://msdn.microsoft.com/en-us/library/ms731338(v=vs.85).aspx

Because of the system requirements I had, I changed the binding to wsHttpBinding. Now I don't need to put the server certificate on the client machine.

Upvotes: 0

Yaron Naveh
Yaron Naveh

Reputation: 24436

why is it bad to have the service certificate on the client machine? it is only the public portion of it, not the private key.

if you use wshttpbinding you can set negotiateServiceCredential=true in which case the client will get the server cert dynamically. The price is a little bit of performance hit, and this endpoint will not be interoperable to non .net clients.

Upvotes: 1

Jim Flood
Jim Flood

Reputation: 8487

Looking here it reads,

When considering authentication, you may be used to thinking primarily of the client identity. However, in the context of WCF, authentication typically refers to mutual authentication. Mutual authentication not only allows positive identification of the clients, but also allows clients to positively identify the WCF services to which they are connected. Mutual authentication is especially important for Internet-facing WCF services, because an attacker may be able to spoof the WCF service and hijack the client’s calls in order to reveal sensitive data.

The service credentials to be used depend largely on the client authentication scheme you choose. Typically, if you are using non-Windows client authentication such as username or certificate authentication, a service certificate is used for both service authentication and message protection. If you are using Windows client authentication, the Windows credentials of the process identity can be used for both service authentication and message protection.

It looks to me that you do need the server certificate on the client machine, and that this is a good thing, not a bad thing. Note that you do not need (and should not put) the server's private key on the client machine. The private key is not contained in a certificate -- only the public key is.

Having the server certificate on the client machine means only having the server's public key on the client machine. The benefit is that the client now knows that it is talking to the real server.

I'm not familiar with WCF services, but this seems fine as far as the use of certificates.

Upvotes: 3

Related Questions