0

I am trying run a simple console app with 2-way SSL. I have the following C# code:

var certificate = X509Certificate2.CreateFromPemFile(_publicFilename, _privateFilename);

using (var handler = new HttpClientHandler())
{
    handler.ClientCertificateOptions = ClientCertificateOption.Manual;
    handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
    handler.ClientCertificates.Add(certificate);
    handler.SslProtocols = SslProtocols.Tls12;

    using (var client = new HttpClient(handler))
    {
        var postData = new StringContent("", UnicodeEncoding.UTF8, "application/json");
        var response = await client.PostAsync("URL", postData);

        string responseString = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseString);
    }
}

This fails during SSL handshake. And I get the following SChannel error on event viewer:

A fatal error occurred while creating a TLS client credential. The internal error state is 10013.

I found the following in wireshark when I run the C# console app:

enter image description here

However if I use the same certificates on postman, it works fine. Refer wireshark screenshot for postman request below:

enter image description here

On checking the signature algorithms of "Certificate Request, Server Hello Done". I get the following:

enter image description here

I do not understand SSL/cryptography etc that well. But as per this post : "https://github.com/dotnet/runtime/issues/33708#issuecomment-600650819" is my C# app unable to negotiate a cipher suite? Are the cipher suites mentioned in the above screenshot not supported by SChannel? I am completely lost here. Cant get a simple HTTP call due to SSL handshake fail.

Framework : .Net5.0 Operating System: Windows 10 Home (Build: 19042.985)

Please help.

  • TLS occurs before the HTTP Request.If you see a Request than TLS is working.If you do not see the request than TLS is failing. Right now it looks like TLS is failing. I just got done yesterday owrking with someone with almopst esxactly same co (https://stackoverflow.com/questions/67713971/httpclient-refusing-to-send-self-signed-client-certificate?force_isolation=true#comment119711321_67713971). It turned out problem was in his encryption code. I think in your issue the TLS is being done in Operating System and ignoring the certificate you are using. Try enabling Network trace (see link).e. – jdweng May 28 '21 at 10:41
  • My key is on sha256WithRSAEncryption. https://i.imgur.com/mpRHldt.png However will check if any of the properties in my certificate is throwing an exception. and get back to you. – Sreejith Krishnadas May 28 '21 at 10:51
  • @jdweng https://i.imgur.com/umJrBFn.png. Dont think any issue with my key here. Attached screenshot. – Sreejith Krishnadas May 28 '21 at 10:57
  • What is the issue is the key being used by the client is different from the key being used by the server. The keys have to be the same. New versions of Net default to operating system for doing TLS. You are doing TLS in Net. So what I think is happening is your key in Net is being ignored because the real key that is being used is from you stores because the operating system is doing the TLS. – jdweng May 28 '21 at 11:06
  • I am not sure what you mean by having the same key on both client and server. SSL works on asymmetric encryption right? – Sreejith Krishnadas May 28 '21 at 11:14
  • An encrypted message is sent from client to server. The server had to validate that the message is correct by using the same key that client used to encrypt. If the verification fails than the TLS fails. – jdweng May 28 '21 at 12:18

1 Answers1

0

is my C# app unable to negotiate a cipher suite?

The client does not negotiate a cipher suite. It just offers ciphers and the server picks one it supports. Since the server is continuing with the handshake after the ClientHello and since the client is the one closing the connection it is not a cipher problem.

While the alert protocol version from the client is confusing, it looks to me that the server requests a client certificate (CertificateRequest in the handshake) but the client cannot offer one for some unknown reason (none configured?) and thus closes the connection. Postman instead sees to send a client certificate back.

But this is mostly speculation based on redacted screenshots from Wireshark. One might be able to give more information when having the actual packet captures, i.e. the full data and not just screenshots.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Hi Steffen. Thank you for your answer. There is really nothing more in the packet captures apart from all the individiaul packets and its respective TCP ack. I have just summarized the important part here to highlight the actual issue. Is there something wrong with the certificate creation process or its use in the HttpClientHandler? I can confirm that using the certificate object I created in line one of the code I have been able to encrypt a dummy message using its public key and decrypt it back to the original message using its private key. So it seems the certificate is pretty fine. – Sreejith Krishnadas May 28 '21 at 06:53
  • @SreejithKrishnadas: There seems to be problems with your client certificate, see also the error *"A fatal error occurred while creating a TLS client credential. The internal error state is 10013."*. Nothing is known about the client certificate though, but maybe it uses some obsolete signature algorithm like MD5 or SHA-1 and thus it fails. – Steffen Ullrich May 28 '21 at 08:42
  • HI Please check this screenshot: https://i.imgur.com/mpRHldt.png. It says "sha256WithRSAEncryption". – Sreejith Krishnadas May 28 '21 at 08:57
  • I am also getting this "A fatal error occurred while creating a TLS client credential. The internal error state is 10013." in my event viewer. Have looked through pretty much all the sites google search could offer me on this. But pretty much stuck for the past one week. It seems to be some issue in SChannel maybe. However I hear there are alternate TLS implementations like BoringSSL by google. Is there any way I can use that in my c# .Net project? – Sreejith Krishnadas May 28 '21 at 09:00