I am using .NET Core 2.1, Kestrel on Linux.
My web application acting as client makes a request as so (following guides dotted around, this seems to the way to go):
var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
X509Certificate2 cert = GetClientCertificate();
handler.ClientCertificates.Add(cert);
using (var client = new HttpClient(handler))
{
var myRequest= new myRequest()
{
foo = bar,
};
var response = await client.PostAsync(myUrl, myRequest, new JsonMediaTypeFormatter());
I have configured Kestrel as so:
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseKestrel(options =>
{
options.Listen(IPAddress.Any, 443, listenOptions =>
{
var httpsConnectionAdapterOptions = new HttpsConnectionAdapterOptions()
{
ClientCertificateMode = ClientCertificateMode.RequireCertificate,
SslProtocols = System.Security.Authentication.SslProtocols.Tls12,
ServerCertificate = GetSSLCertificate(),
ClientCertificateValidation = CertificateValidator.MyCustomerValidatorForLogging
};
listenOptions.UseHttps(httpsConnectionAdapterOptions);
});
}
)
.Build();
I added a custom validator (just to see what is going on, looks like this):
public static bool MyCustomerValidatorForLogging(X509Certificate2 certificate, X509Chain chain, SslPolicyErrors errors)
{
Log.Info("Received Request");
Log.Error(errors.ToString());
if (errors == SslPolicyErrors.None)
{
return true;
}
return false;
}
GetClientCertificate() is the certificate for client authentication SSL cert signed by an intermediate CA.
GetSSLCertificate() is the certificate for a standard server authentication SSL cert.
I have copied the issuing Sub CA and CA certs of the client authentication cert in to /usr/local/share/ca-certificates/ (the "store") and issued the "update-ca-certificates" command. I believe it is these certs that are used to verify the client cert.
When the server receives the request, the errors value is: "RemoteCertificateChainErrors" and rejects the request.
Anyone have any ideas please?
Turns out this is actually working! I just needed to get the correct certificates in place!
Specifically, I had to include the Root CA and Intermediate CA at the Server side.
The Client side, I had to include only the Root CA to verify.