I am trying to port this python web client to C# .NET Core 3.1. I'm running on Windows 10x64 (build 19041). The linked github project contains a (secure) test web server sandbox you can develop against together with some client and server test self-cert certificates.
I am not very familiar with python (or SSL/TLS for that matter), but I can
If I run a python utility (sslyze) against the test server it indicates that it supports TLS1.3.
I have
imported the client.cert.pem into my personal certificate store and the ca.cert.pem into the trusted root certificate authority. (I wasn't sure if this was correct and perhaps I needed to unpack them, but they appear to have been imported successfully)
Added the following registry keys
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
When I try and run the C# code, I get the
"IOException: Unable to read data from the transport connection"
error on the response.Result line.
I'm struggling to make any headway, now.
I'd be really grateful for any pointers as to where to look next. Many thx IA.
Here's my code
class Program
{
private const string Thumbprint = "37af35e3f13c65ea0d7bbad148332924a1ce41d7";
private const string MailBox = "alice";
private const int Port = 8000;
private const string BaseAddress = "127.0.0.1";
private static HttpClient _client = null;
public static void Main(string[] args)
{
ConfigureHttpClient();
var response = Handshake();
Console.WriteLine($"Handshake succeeded: {response.StatusCode == HttpStatusCode.OK}");
}
private static HttpResponseMessage Handshake()
{
var uri = new Uri($"https://{BaseAddress}:{Port}/messageexchange/{MailBox}");
var response = _client.PostAsync(uri, null);
return response.Result;
}
private static void ConfigureHttpClient()
{
var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; },
CheckCertificateRevocationList = false,
SslProtocols = SslProtocols.Tls13
| SslProtocols.Tls12
| SslProtocols.Tls11
| SslProtocols.Tls
};
var certificate = GetCertificateByThumbprint(Thumbprint);
handler.ClientCertificates.Add(certificate);
_client = new HttpClient(handler);
}
//Returns a certificate by searching through all likely places
private static X509Certificate2 GetCertificateByThumbprint(string thumbprint)
{
X509Certificate2 certificate;
//foreach likely certificate store name
foreach (var name in new[] { StoreName.My, StoreName.Root })
{
//foreach store location
foreach (var location in new[] { StoreLocation.CurrentUser, StoreLocation.LocalMachine })
{
//see if the certificate is in this store name and location
certificate = FindThumbprintInStore(thumbprint, name, location);
if (certificate != null)
{
//return the resulting certificate
return certificate;
}
}
}
//certificate was not found
throw new Exception(string.Format("The certificate with thumbprint {0} was not found", thumbprint));
}
private static X509Certificate2 FindThumbprintInStore(string thumbprint,
StoreName name, StoreLocation location)
{
//creates the store based on the input name and location e.g. name=My
var certStore = new X509Store(name, location);
certStore.Open(OpenFlags.ReadOnly);
//finds the certificate in question in this store
var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint,
thumbprint, false);
certStore.Close();
if (certCollection.Count > 0)
{
//if it is found return
return certCollection[0];
}
else
{
//if the certificate was not found return null
return null;
}
}
}
Here's the full error stack
System.AggregateException HResult=0x80131500 Message=One or more errors occurred. (An error occurred while sending the request.)
Source=System.Private.CoreLib StackTrace: at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) at System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) at System.Threading.Tasks.Task
1.get_Result() at IfxMeshClient.Program.Handshake() in C:\Users...\IfxMeshClient\Program.cs:line 41 at IfxMeshClient.Program.Main(String[] args) in C:\Users...\IfxMeshClient\Program.cs:line 32Inner Exception 1: HttpRequestException: An error occurred while sending the request.
Inner Exception 2: IOException: Unable to read data from the transport connection: An established connection was aborted by the software in your host machine..
Inner Exception 3: SocketException: An established connection was aborted by the software in your host machine.
EDIT: I just wanted to add the output from sslyze as I wondered if it could be a cipher mismatch, but these ciphers appear to be available on my version of win10.
* TLS 1.3 Cipher Suites:
Attempted to connect using 5 cipher suites.
The server accepted the following 3 cipher suites:
TLS_CHACHA20_POLY1305_SHA256 256 ECDH: X25519 (253 bits)
TLS_AES_256_GCM_SHA384 256 ECDH: X25519 (253 bits)
TLS_AES_128_GCM_SHA256 128 ECDH: X25519 (253 bits)
The group of cipher suites supported by the server has the following properties:
Forward Secrecy OK - Supported
Legacy RC4 Algorithm OK - Not Supported
The server is configured to prefer the following cipher suite:
TLS_AES_256_GCM_SHA384 256 ECDH: X25519 (253 bits)
EDIT1: Not quite sure what to make of Fiddler output. I'm not sure if it confuses things since it refers to TLS12 and then suggests supported versions are TLS13
CONNECT 127.0.0.1:52985 HTTP/1.1
Host: 127.0.0.1:52985
A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below.
Version: 3.3 (TLS/1.2)
Random: F7 09 8F A8 9A 72 AF 33 93 29 90 48 E4 A2 E2 09 CE BD 7E 27 94 0A C9 53 D4 54 6C 35 0B DF E2 E9
"Time": 12/08/2059 21:41:27
SessionID: empty
Extensions:
supported_versions Tls1.3
signature_algs rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha1, ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_sha1, dsa_sha1, rsa_pkcs1_sha512, ecdsa_secp521r1_sha512
supported_groups x25519 [0x1d], secp256r1 [0x17], secp384r1 [0x18]
key_share 00 24 00 1D 00 20 95 34 AC 4A A5 6C D8 24 CD 50 29 2E F8 27 B4 59 D7 2C D8 C0 79 7B 14 79 B2 E8 28 6F 36 DE D4 48
post_handshake_auth
extended_master_secret empty
renegotiation_info 00
psk_key_exchange_modes 01 01
Ciphers:
[1302] TLS_AES_256_GCM_SHA384
[1301] TLS_AES_128_GCM_SHA256
...
and the response was
HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 13:21:35.087
Connection: close
fiddler.network.https> HTTPS handshake to 127.0.0.1 (for #6) failed. System.Security.Authentication.AuthenticationException A call to SSPI failed, see inner exception. < The message received was unexpected or badly formatted
Win32 (SChannel) Native Error Code: 0x80090326
Further the combination of the fiddler output as well as the sslyze output would seem to indicate there are common ciphers as well
TLS_AES_256_GCM_SHA384
TLS_AES_128_GCM_SHA256
Just to say that, my issue appears to have have been that although I had imported the pem into the certificate store, I had not created a pfx which incorporated the private key file.
See this SO post - Convert a CERT/PEM certificate to a PFX certificate
Having done that I did get more response from the server but was still getting an Http 403 and the underlying error was
Cannot determine the frame size or a corrupted frame was received
According to this post .NET 4.8 TLS 1.3 Issue on Windows 10, it may be an ongoing issue.
User contributions licensed under CC BY-SA 3.0