5

Question

Why will my HttpClient instance not use my provided client certificate for mutual auth?

Background

I'm using HttpClient to do mutual TLS. As the client, I'm adding a client certificate to a WebRequestHandler and then using that handler in the new HttpClient.

The certificate is not installed on my machine. I've successfully loaded it into the handler and can see it when debugging (the password is correct, too).

I'm testing against a couple of different test domains

Both testing apps are showing no cert is being sent.

Code

    var clientCert = new X509Certificate2("badssl.pem", "badssl.com");

    var webHandler = new WebRequestHandler();
    webHandler.ClientCertificates.Add(clientCert);
    var httpClient = new HttpClient(webHandler);

    var result = await (await httpClient.GetAsync(uri)).Content.ReadAsStringAsync();
Community
  • 1
  • 1
Justin Self
  • 6,137
  • 3
  • 33
  • 48
  • The certificate will not be sent unless it matches the list of CAs that the server sends over during the handshake process. So make sure it has the right root authority on it. Also make sure you're using a copy that actually contains the private key. – John Wu Dec 11 '18 at 04:02
  • Thanks, @JohnW. The issue was the private key, but I'm not convinced the root authority needs to match for the client cert based on my (limited) understanding of mutual TLS. My _very anecdotal_ experience shows a self signed cert was being sent when it was installed. – Justin Self Dec 11 '18 at 17:24
  • It depends on how the server is configured. During the handshake it can send back a list of CA's, and the client should respond only with certs that fall under them. But it can also send back an empty list, and the client can send whatever. It's details like these that make it so hard to troubleshoot. – John Wu Dec 11 '18 at 18:38

1 Answers1

3

The X509Certificate2 class doesn't look to be reading in the private key from the PEM cert.

    var clientCert = new X509Certificate2("badssl.com-client.pem", "badssl.com");
    if(!clientCert.HasPrivateKey)
        throw new ApplicationException("Cert doesn't contain private key");

Does throwing an error.

In the case of badssl.com, they do have a PKCS #12 cert available (aka PFX). I was able to get your code to work with that cert.

Adam Larsen
  • 1,121
  • 1
  • 8
  • 13