godot: Unable to make HTTPS requests with C#'s built-in class (not HTTPRequest) (fixed in `master`)

Godot version: 3.2 stable

OS/device including version: Windows 10

Issue description: We have a C# library, that includes a Log service, which we use in most our projects (of any kind). This service runs in a thread an POST’s a bunch of strings to our server. Implementing this Log service works just fine on my Linux machine, but when i deploy on a Windows machine (or my coworker runs it in the editor on his Windows machine), the web request fails with Error: SecureChannelFailure (The authentication or decryption has failed.). Here’s a full stack trace:

at System.Net.WebConnection.CreateStream (System.Net.WebOperation operation, System.Boolean reused, System.Threading.CancellationToken cancellationToken) [0x0021a] in <8c9baba7add14c22be562e4c18e5738f>:0
  at System.Net.WebConnection.InitConnection (System.Net.WebOperation operation, System.Threading.CancellationToken cancellationToken) [0x00141] in <8c9baba7add14c22be562e4c18e5738f>:0
  at System.Net.WebOperation.Run () [0x0009a] in <8c9baba7add14c22be562e4c18e5738f>:0
  at System.Net.WebCompletionSource`1[T].WaitForCompletion () [0x00094] in <8c9baba7add14c22be562e4c18e5738f>:0
  at System.Net.HttpWebRequest.GetRequestStream () [0x00016] in <8c9baba7add14c22be562e4c18e5738f>:0
  at Playground.Sandbox.Utility.WebRequest.Post (System.String url, System.Collections.Generic.Dictionary`2[TKey,TValue] values) [0x000b6] in <efaba92892e84c979ad8940e61632f93>:0
  at Playground.Sandbox.Services.LogService`1[T].Upload () [0x001f8] in <efaba92892e84c979ad8940e61632f93>:0 : Error: SecureChannelFailure (The authentication or decryption has failed.)

If i remove the s from the url, and stop our server from redirecting to https, it works, so this definitely has to do with tls.

I have tried overriding the ServerCertificateValidationCallback with

ServicePointManager.ServerCertificateValidationCallback += (p1, p2, p3, p4) => true;

as per this stackoverflow post

I have also tried forcing tls 1.2:

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

According to monos documentation, you can import certificates with a tool called mozroots, but it does not seem to be bundled with Godot. Is there a way to use this tool from my code, so I don’t have to manually run it for every pc i deploy to?

Steps to reproduce: Make a https request from C#/mono on a Windows machine

Minimal reproduction project: New C# project, that creates an HTTP request to a https-url, using either System.Net.WebRequest or System.Net.WebClient.

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Comments: 24 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks, something seems to still be off. Continuing debugging in https://github.com/godotengine/godot-mono-builds/pull/47.

I think this issue is because of how the official Godot binaries are built. In Mono, there’s an abstract class called MobileTlsProvider used by the C# built-in web requests. A MobileTlsProvider is obtained via MonoTlsProviderFactory, which provides an implementation of MobileTlsProvider that will work with the system it’s running on. It seems to me like for Windows, Mono uses the BTLS system and without it can’t use TLS. BTLS is only available in Mono if MONO_FEATURE_BTLS is defined when MonoTlsProviderFactory.cs is compiled. Example:

#if MONO_FEATURE_BTLS
		[MethodImpl (MethodImplOptions.InternalCall)]
		internal extern static bool IsBtlsSupported ();
#endif

The above function points to a C function that returns true if --enable-btls is passed to autogen.sh. In my Mono 4.5 installation from the binary on their website, the BTLS code is still present when I look at it with DnSpy. In the Mono 4.5 from the Godot 3.3 official binary, however, the same code didn’t get included. C# HTTPS requests work when you build Godot with Mono yourself, I think because it copies the existing Mono installation which for most people comes from the official Mono binaries.

My Godot build image

No BTLS in the official Godot binary image

I just compiled Godot 3.2 with Mono myself. Also doing this before building:

cert-sync --user myCert.pem

Were myCert.pem is the certificate of the server I’m trying to connect to. This seems to fix it. (I got other errors now, but these are probably library related)

Yes, this is not a bug in a thitdparty library, but Godot and how it uses mono.