title: How to force WCF client to send client certificate?
body: <p>I'm trying to access a publicly-hosted SOAP web service (not WCF) over https, and I'm getting an error that I've never seen before. First, here are the facts:</p>
  
  <ul>
  <li>This service requires client certificates. I have a certificate that is signed by the same CA as the server's certificate.</li>
  <li>I know that the URL is available, as I can hit it in Internet Explorer. IE brings up the "choose certificate" window, and if I pick it (and ignore the server-host-name-does-not-match-certificate error), it goes on and gives me an HTTP 500 error.</li>
  <li>If I open the site in Chrome, after picking the cert and ignoring the error, I get a normal error message about WSA Action = null.</li>
  <li>If I open the site in FireFox, after ignoring the error, I get a page about how the server couldn't validate my certificate. It never asked me to pick one, so that makes perfect sense.</li>
  </ul>
  
  <p>Now, the exception:</p>
  
  <pre><code>Error occurred while executing test 12302: System.ServiceModel.Security.SecurityNegotiationException: Could not establish secure channel for SSL/TLS with authority 'ihexds.nist.gov:9085'. ---&gt; System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
     at System.Net.HttpWebRequest.GetResponse()
     at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
  </code></pre>
  
  <p>I've traced the interaction with WireShark, but because I'm not an expert in the TLS protocol, I could be missing clues as to what's going on. Here, however, is what I do see:</p>
  
  <ol>
  <li>C -> S  Client Hello
  <ul>
  <li>Contains things like a random number, date/time, cypher suites supported, etc</li>
  </ul></li>
  <li>S -> C  Server Hello, Certificate, Certificate Request, Server Hello Done
  <ul>
  <li>Contains the server's certificate, and a request for a client certificate</li>
  </ul></li>
  <li>C -> S  Certificate, Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
  <ul>
  <li><em>HERE IS THE INTERESTING PART</em> -- The first part of this packet is the Certificate handshake, where I assume the client certificate would be, but there are no certificates present (Certificates Length: 0).</li>
  </ul></li>
  <li>S -> C  Alert (Level: Fatal, Description: Bad Certificate)
  <ul>
  <li>Well, yeah, there was no certificate sent.</li>
  </ul></li>
  </ol>
  
  <p>My binding is set up as follows:</p>
  
  <pre><code>&lt;binding name="https_binding"&gt;
      &lt;textMessageEncoding /&gt;
      &lt;httpsTransport useDefaultWebProxy="false" /&gt;
  &lt;/binding&gt;
  </code></pre>
  
  <p>My behavior is set up as follows:</p>
  
  <pre><code>&lt;behavior name="clientcred"&gt;
      &lt;clientCredentials&gt;
          &lt;clientCertificate findValue="69b6fbbc615a20dc272a79caa201fe3f505664c3" storeLocation="CurrentUser" storeName="My" x509FindType="FindByThumbprint" /&gt;
          &lt;serviceCertificate&gt;
              &lt;authentication certificateValidationMode="None" revocationMode="NoCheck" /&gt;
          &lt;/serviceCertificate&gt;
      &lt;/clientCredentials&gt;
      &lt;messageInspector /&gt;
  &lt;/behavior&gt;
  </code></pre>
  
  <p>My endpoint is set up to use both the binding and the behavior. Why does WCF refuse to send the certificate when it creates the https connection?</p>