4

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?

PKCS12
  • 407
  • 15
  • 41
  • 1
    This means there is an error when you are validating your SSL Certificates RemoveCertificateChainErrors is an array which contains the errors. When the RemoteCertificateChainErrors occurs, you can retrieve the ChainStatus and to get detailed inforamtion. – Abubakar Iftikhar Jun 10 '19 at 07:40

2 Answers2

0

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.

PKCS12
  • 407
  • 15
  • 41
  • What do you mean that you had to include the Root CA on the cilent side? Did you have to attach the Root CA cert to the client request as well? I'm running into something similar I think... – Peter Tirrell Dec 10 '19 at 15:51
  • Because my client side is running Linux, I had to add to the Trust, the Root CA - it will send a request with root public key and not just the leaf. If you're running MS Windows and the request is from this then you must ensure the CA has the root cert. – PKCS12 Dec 10 '19 at 17:10
0

we also faced the same issue, for Linux ubuntu OS with Apache Server. we solved it by attaching the SSL cert. with Apache Config.

Pabitro
  • 36
  • 5