We've got a web app that has to communicate with a HTTP service using two-way SSL certificate authentication. The following is the relevant code
X509Certificate certificate = GetCertFromStore(StoreName.My, StoreLocation.LocalMachine, certName);
if (certificate != null)
{
Log.Debug($"Adding client cert {certificate.Subject}");
WebRequestHandler handler = new WebRequestHandler();
handler.ClientCertificates.Add(certificate);
handler.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.UseProxy = false;
using (var client = new HttpClient(handler))
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var postObj = new
{
// somestuff
};
var postBody = JsonConvert.SerializeObject(postObj);
var httpContent = new StringContent(postBody, Encoding.UTF8, "application/json");
HttpResponseMessage httpResponse = client.PostAsync(queryUrl, httpContent).Result;
if (httpResponse.IsSuccessStatusCode)
{
// codey code
}
else
{
Log.Error($"some error stuff.");
}
}
}
else
{
Log.Error($"Unable to find the certificate with name: {certName}");
}
At the moment we're using a self-signed certificate which we've provided to the third-party service provider and installed the relevant server certificate from them.
On a local development machine all works well - the connection is established and the service calls and responses go through correctly.
However, when we've deployed on an Azure VM (our test environment) the certificate exchange fails. Looking at a Wireshark trace we can see that server certificate is accepted, but it shows that there are 0 client certificates sent. We know the client certificate is being found in the store (because of the logging) and we can see from the Wireshark trace that the client certificate name is indeed listed in the 'Distinguished Names' of the server's certificate request.
Can't figure out how, even though the code is adding our expected client certificate to the WebRequestHandler it disappears during the handshake.