title: How to call web service using client certificates / mutual authentication?
body: <p>I'm building a web service client using vb .net. The web service is secured with ssl, basic authentication and also requires client certificates. So I created a web reference in Visual Studio and provided the credentials:</p>
  
  <pre><code>Dim cred As New System.Net.NetworkCredential("usr", "passwd")
  Dim proxy As New SimpleFromLocal.simple
  proxy.Credentials = cred
  
  Console.WriteLine(proxy.helloWorld())
  </code></pre>
  
  <p>This works as expected, as long as I turn off mutual authentication on the server side.
  I added a client certificate like this:</p>
  
  <pre><code>Dim cert As X509Certificate = X509Certificate.CreateFromCertFile(certFile)
  proxy.ClientCertificates.Add(cert)
  </code></pre>
  
  <p>The certificate is loaded, but the web service call fails. I could post the exception, but it is in german, which is an issue on its own. It basically says: Authentication failed, because the remote site closed the connection.
  I tried debugging the ssl handshake on the server side and it looks like the client certificate is not transmitted.</p>
  
  <p>So what am I missing here? Is it required to install the client certificate on the local machine?</p>
  
  <p><strong>Edit:</strong> The error thrown:</p>
  
  <pre><code>System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---&gt; 
  System.IO.IOException: Authentication failed because the remote party has closed the transport stream. 
  at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
  at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
  at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
  at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
  at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
  at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
  at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
  at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
  at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
  at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
  at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
  at System.Net.TlsStream.CallProcessAuthentication(Object state)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
  at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
  at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
  at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
  at System.Net.ConnectStream.WriteHeaders(Boolean async)
  --- End of inner exception stack trace ---
  at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request)
  at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)
  at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
  at CCClient.SimpleFromLocal.simple.helloWorld() in C:\TP\CCClient\CCClient\Web References\SimpleFromLocal\Reference.vb:Zeile 90.
  at CCClient.Module1.clientWithProxy(NetworkCredential cred, String certFile)
  in C:\TP\CCClient\CCClient\Module1.vb:Zeile 53.
  </code></pre>