I'm using RestSharp to send a client certificate to my local IIS for testing purposes. The client sends Certificate A:
var client = new RestClient(myHost)
{
ClientCertificates = new X509Certificate2Collection(store.Certificates.Find(X509FindType.FindByThumbprint, myClientThumbprint, true))
};
var request = new RestRequest(myResource, Method.GET);
var response = client.Execute(request);
On my server, I have a DelegatingHandler
hooked into my pipeline, successfully being called here:
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
X509Certificate2 certificate = request.GetClientCertificate();
// ...
}
I published my project locally, configured IIS to accept client certificates, and I've also setup my server to use SSL with a different certificate, Certificate B.
Both Certificates A & B are installed in Local Computer\My
and both have private and public components.
When I execute my request from my client application with Certificate A for client authentication, my server's request.GetClientCertificate()
turns up the server's SSL Certificate B instead of the client's authentication Certificate A. If I disable SSL, then the retrieved certificate is null
.
I tried tweaking my Web.Config to include sslFlags:
<system.webServer>
<security>
<access sslFlags="SslNegotiateCert"/>
</security>
</system.webServer>
And I've also tried setting sslFlags="Ssl, SslNegotiateCert"
.
Both certificates were created by a trusted CA, but just in case, I created my own trusted CA and used that to self-sign a public/private cert to use for my client certificate.
In every case, the supposed "client certificate" is retrieved as either null or the server's SSL cert. Certificate A is definitely found by my client. When I decrypt HTTPS traffic with Fiddler, I see a tunnel identifying the use of Certificate B from the server, but no indication that Certificate A is being passed. (Which is not to say that it's not -- just that I can't verify that it is.)
Am I missing something obvious, eg the nature of my certificates individually or together? Or is there some additional configuration IIS needs to permit client certificate passing?
EDIT: Trying to isolate components, I removed my RestSharp code on my test client, replacing it with:
var req = (HttpWebRequest)WebRequest.Create(myHost + "/" + myResource);
req.ClientCertificates.Add(myClientCertificate);
req.Method = "GET";
var resp = req.GetResponse();
In Fiddler, I see the following HTTP tunnel:
HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 09:53:50.370
Connection: close
Encrypted HTTPS traffic flows through this CONNECT tunnel. HTTPS Decryption is enabled in Fiddler, so decrypted sessions running in this tunnel will be shown in the Web Sessions list.
Secure Protocol: Tls
Cipher: Aes256 256bits
Hash Algorithm: Sha1 160bits
Key Exchange: ECDHE_RSA (0xae06) 256bits
== Client Certificate ==========
[Subject]
CN=(server's SSL certificate)
[Issuer]
CN=...
(and so on)
...
== Server Certificate ==========
(same as the above 'client' certificate)
Again, I've confirmed in VS that my request has my client certificate to send to the server.