I have made a small console app in .NET Core for making REST/Http requests using .pfx/.p12 certificates during the validation process. The app works just fine when I provide it with a correct certificate with a correct password. But it crashes whenever I
- load an invalid certificate
- mistype the password associated to the certificate
- if I tell the application not to load a certificate even though a certificate is needed.
More specifically I get the following exceptions:
System.Net.Http.HttpRequestException: 'The SSL connection could not be established, see inner exception.'
AuthenticationException: Authentication failed, see inner exception.
Win32Exception: The message received was unexpected or badly formatted
I would much rather get the HTTP response corresponding to an invalid invocation, which seems to be what I get when I use SOAPUI.
I use the following method for making a HttpClientHandler:
private static HttpClientHandler GetClientHandler(string certificate, string password)
{
X509Certificate2 certPfx;
try {
certPfx = new X509Certificate2(certificate, password);
}
catch(CryptographicException e) {
Console.WriteLine($ "Error occured while trying to load certificate: {e.Message}");
return null;
}
var clientHandler = new HttpClientHandler();
clientHandler.SslProtocols = SslProtocols.Tls12;
clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
clientHandler.ClientCertificates.Add(certPfx);
clientHandler.ServerCertificateCustomValidationCallback += (HttpRequestMessage req, X509Certificate2 cert2, X509Chain chain, SslPolicyErrors err) = >true;
return clientHandler;
}
And I use the following code for making the POST request:
using(var client = handler != null ? new HttpClient(handler, true) : new HttpClient())
{
AddHeaders(client, headers);
var httpContent = new StringContent(request.ToString(), Encoding.UTF8, "application/xml");
Console.WriteLine("Response from service:");
Console.WriteLine("----------------------");
var response = await client.PostAsync(endpoint, httpContent);
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
Console.WriteLine("----------------------");
Console.WriteLine("----------------------");
}