title: WCF Exception - The client certificate is not provided
body: <p>WCF Exception - The client certificate is not provided. Specify a client certificate in ClientCredentials.</p>
  
  <p>After reading most of what I have been able to find on this subject, and attempting many different options, I find I don’t have any more hair to pull, and hence this post.</p>
  
  <p>I wish to use SSL with a self-hosted WCF service, having security mode as TransportWithMessageCredential with HTTP transport. I am using 2 dev machines and testing over a LAN.</p>
  
  <p>As mentioned above, I have read and meticulously followed just about every example which demonstrates this, yet somehow still have issues with the certificates.</p>
  
  <p>As far as the certificates are concerned, I have tried a number of things.</p>
  
  <p>The main jist of what I did was to follow what is given in
  <a href="http://msdn.microsoft.com/en-us/library/ff647171.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/ff647171.aspx</a></p>
  
  <p>I also used “How to: Use Certificate Authentication and Message Security in WCF Calling from Windows Forms” in 
  <a href="http://msdn.microsoft.com/en-us/library/ff648360.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/ff648360.aspx</a> 
  as a basic guide.</p>
  
  <p>I first tested the service and client using basicHttpBinding over Http in order to verify things.</p>
  
  <p>I then made changes for wsHttpBinding, SSL, and Certificates.</p>
  
  <p>When I “Add Service Reference” on the client dev PC, I receive an error as follows:</p>
  
  <ul>
  <li>Window Titled -</li>
  </ul>
  
  <p>Security Alert</p>
  
  <p>Visual Studio has detected a problem with the site's security certificate.</p>
  
  <p>Issued By: RootCATest
  Issued to: TempCert
  Certificate is valid from---</p>
  
  <p>The security certificate issued by a company is not in the untrust list. It might be trustable.</p>
  
  <p>The security certificate date is valid.</p>
  
  <p>The security certificate for host 'TempCert' does not match the name of the page you are trying to view.</p>
  
  <ul>
  <li>Do you want to proceed? -</li>
  </ul>
  
  <p>If I click “Yes” to proceed, and run the client code, an InvalidOperationException occurs with the following message.</p>
  
  <p>“The client certificate is not provided. Specify a client certificate in ClientCredentials.”</p>
  
  <p>The Service config is as follows:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
  &lt;configuration&gt;
      &lt;system.serviceModel&gt;
          &lt;behaviors&gt;
              &lt;serviceBehaviors&gt;
                  &lt;behavior name="ServiceBehavior"&gt;
                      &lt;serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" /&gt;
                      &lt;serviceDebug includeExceptionDetailInFaults="true" /&gt;
                      &lt;serviceCredentials&gt;
                          &lt;serviceCertificate findValue="CN=TempCert" 
                                              storeLocation="LocalMachine"
                                              storeName="My" /&gt;
                      &lt;/serviceCredentials&gt;
                  &lt;/behavior&gt;
              &lt;/serviceBehaviors&gt;
          &lt;/behaviors&gt;
          &lt;bindings&gt;
            &lt;wsHttpBinding&gt;
              &lt;binding name="wsHttpEndpointBinding"&gt;
                &lt;security mode="TransportWithMessageCredential"&gt;
                  &lt;message clientCredentialType="Certificate" /&gt;
                &lt;/security&gt;
              &lt;/binding&gt;
            &lt;/wsHttpBinding&gt;
          &lt;/bindings&gt;      
          &lt;services&gt;
              &lt;service name="SBSWCFServiceHost.Operations" 
                       behaviorConfiguration="ServiceBehavior"&gt;
                  &lt;endpoint name="wsHttpEndpoint"
                            address=""
                            binding="wsHttpBinding"
                            bindingConfiguration="wsHttpEndpointBinding"
                            contract="SBSWCFServiceHost.IOperations" &gt;
                      &lt;identity&gt;
                          &lt;dns value="localhost" /&gt;
                      &lt;/identity&gt;
                  &lt;/endpoint&gt;                          
                  &lt;endpoint name="mexHttpEndpoint"
                            address="mex"
                            binding="mexHttpsBinding"
                            contract="IMetadataExchange" &gt;
                  &lt;/endpoint&gt;
                  &lt;host&gt;
                      &lt;baseAddresses&gt;
                          &lt;add baseAddress="https://10.0.0.103:8003/SBSWCFServiceHost/Operations/" /&gt;
                      &lt;/baseAddresses&gt;
                  &lt;/host&gt;
              &lt;/service&gt;
          &lt;/services&gt;
      &lt;/system.serviceModel&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>The client config is as follows:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
  &lt;configuration&gt;
      &lt;system.serviceModel&gt;
          &lt;behaviors&gt;
              &lt;endpointBehaviors&gt;
                  &lt;behavior name="EndpointBehavior"&gt;
                      &lt;clientCredentials&gt;
                          &lt;clientCertificate storeLocation="LocalMachine"
                                             storeName="My"
                                             x509FindType="FindByThumbprint"
                                             findValue="e4c87a961f796be6b6cab59c3760e43ffb6e941d"/&gt;
                      &lt;/clientCredentials&gt;
                &lt;/behavior&gt;
              &lt;/endpointBehaviors&gt;
          &lt;/behaviors&gt;      
          &lt;bindings&gt;
              &lt;wsHttpBinding&gt;
                  &lt;binding name="wsHttpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00"
                      receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
                      transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                      maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                      messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                      allowCookies="false"&gt;
                      &lt;readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                          maxBytesPerRead="4096" maxNameTableCharCount="16384" /&gt;
                      &lt;reliableSession ordered="true" inactivityTimeout="00:10:00"
                          enabled="false" /&gt;
                      &lt;security mode="TransportWithMessageCredential"&gt;
                          &lt;transport clientCredentialType="None" proxyCredentialType="None"
                              realm="" /&gt;
                          &lt;message clientCredentialType="Certificate" negotiateServiceCredential="true"
                              algorithmSuite="Default" /&gt;
                      &lt;/security&gt;
                  &lt;/binding&gt;
              &lt;/wsHttpBinding&gt;
          &lt;/bindings&gt;
          &lt;client&gt;
            &lt;endpoint address="https://10.0.0.103:8003/SBSWCFServiceHost/Operations/"
                binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint"
                contract="SBSWCFService.IOperations" name="wsHttpEndpoint"&gt;
                &lt;identity&gt;
                    &lt;dns value="localhost" /&gt;
                &lt;/identity&gt;
            &lt;/endpoint&gt;
          &lt;/client&gt;
      &lt;/system.serviceModel&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>The following is a Summary of the tasks I performed, based on the contents of numerous posts and documents.</p>
  
  <ol>
  <li><p>Created a self-signed CA certificate (named RootCATest) on the server, and placed it in the Trusted Root Certification Authorities Certificates folder of the Local Computer.</p></li>
  <li><p>Created a certificate which is signed by the RootCATest certificate (named TempCert), on the server, and placed it in the Personal Certificates folder of the Local Computer.</p></li>
  <li><p>Exported the TempCert certificate and private key.</p></li>
  <li><p>Copied the TempCert .cer and .pvk files to the client machine, and imported the TempCert Certificate into the Personal Certificates folder of the Local Computer.</p></li>
  <li><p>Executed  ICalcs.exe [private key path] /grant "NT AUTHORITY\NETWORK SERVICE":R on the server machine, using the path to the private key for the TempCert certificate.</p></li>
  <li><p>Executed   netsh http add sslcert ipport=o.o.o.o:8003 certhash=[TempCert thumbprint] appid=[{application id}] on the server machine</p></li>
  </ol>
  
  <p>I believe I am close to getting this working.</p>
  
  <p>It seems pretty obvious that the app is not happy with the TempCert certificate, yet I have not been able to resolve this, and am pretty much stuck.</p>
  
  <p>Any assistance with respect to any problems in the given configurations, the steps I have followed in order to put the correct certificates in place, and those used to add access permissions and the sslcert entry, will be greatly appreciated.</p>
  
  <p>Many thanks.</p>
  
  <p>After some further experimentation, I have noticed additional behavior.</p>
  
  <p>Steps taken are as follows:</p>
  
  <p>I deleted both client and server certificates, and recreated them in accordance with 
  ....codeproject.com/Articles/36683/9-simple-steps-to-enable-x-509-certificates-on-wcf</p>
  
  <p>I added the new sslcert using netsh. I then exported the client certificate from the server and
  imported it into the client store.</p>
  
  <p>I modified the service app.config with the new certificates info, and started the service.</p>
  
  <p>I modified the client app.config  as follows:</p>
  
  <pre><code>&lt;endpointBehaviors&gt;
    &lt;behavior name="EndpointBehavior"&gt;
      &lt;clientCredentials&gt;
        &lt;clientCertificate storeLocation="LocalMachine" storeName="My"  x509FindType="FindBySubjectName" findValue="WCFClient" /&gt;
        &lt;serviceCertificate&gt;
          &lt;authentication certificateValidationMode="PeerTrust" /&gt;
        &lt;/serviceCertificate&gt;
      &lt;/clientCredentials&gt;
    &lt;/behavior&gt;
  &lt;/endpointBehaviors&gt;
  </code></pre>
  
  <p>I updated the Service Reference. The update procedure once again issued a Security Alert as before.</p>
  
  <p>I then executed the client, and received this error:    </p>
  
  <p>"The client certificate is not provided. Specify a client certificate in ClientCredentials."</p>
  
  <p>I then set a breakpoint on "client = new WCFService.Client();" and checked the "client" instance.
  The value of client.ClientCredentials.ClientCertificate.Certificate = null.</p>
  
  <p>I then added the following in code after "client = new WCFService.Client();":</p>
  
  <pre><code>X509Store store = new X509Store("My", StoreLocation.LocalMachine);
  store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
  X509Certificate2Collection collection = (X509Certificate2Collection) store.Certificates;
  foreach (X509Certificate2 x509 in collection)
  {
  if (x509.Thumbprint == "236D7D4AD95753B8F22D3781D61AACB45518E1B5")
  {
      client.ClientCredentials.ClientCertificate.SetCertificate(
          x509.SubjectName.Name, store.Location, StoreName.My);
  }
  }
  </code></pre>
  
  <p>After execution of this code, client.ClientCredentials.ClientCertificate.Certificate contained the certificate.</p>
  
  <p>When then executing "client.Open();" , an exception is thrown with the following contents.</p>
  
  <p>The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
  The remote certificate is invalid according to the validation procedure.
  Could not establish trust relationship for the SSL/TLS secure channel with authority</p>
  
  <p>If anyone with knowledge of what may be happening here could shed some light on this I will be very grateful.</p>