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
- Windows: Update godot-mono-builds to fix https://github.com/godotengine/godot/issues/36958 — committed to godotengine/build-containers by akien-mga 3 years ago
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 calledMobileTlsProvider
used by the C# built-in web requests. AMobileTlsProvider
is obtained viaMonoTlsProviderFactory
, which provides an implementation ofMobileTlsProvider
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 ifMONO_FEATURE_BTLS
is defined when MonoTlsProviderFactory.cs is compiled. Example:The above function points to a C function that returns true if
--enable-btls
is passed toautogen.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
No BTLS in the official Godot binary
Note: Fixed in Godot 4 which uses .NET 6 (https://github.com/godotengine/godot/pull/64089#issuecomment-1208887960)
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.