-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
I am using SslStream with a remote certificate validation callback on many platforms. The only one that has an issue is .NET 6 Android (Xamarin Android is OK, FYI). I am already painfully aware of this issue which is currently kneecapping the custom certificate validation of our SDK, but I did find a way to work around that by forcing Android to trust my cert using network-security-config.
That being said, now that the callback is finally being called, the chain argument has 0 elements. On .NET 6 Console, it is properly populated with 3 elements. I also saw this happen on Xamarin / Mono back in the day but as a workaround I would take the received cert and use X509Chain.Build() to reconstruct the chain so that I could examine it. The problem is that on .NET 6 Android this also does not work. The resulting chain still has 0 elements.
Reproduction Steps
I'm unsure of how I could present this because it requires a server running https using a cert that is not trusted by stock Android, but assuming that such a server is running these are the steps to take:
-
Start server (In my case I have the server set up to serve the entire chain, but not sure if this is required or not)
-
Create a maui project (or .NET 6 Android at least)
-
Add the cert that the server is using (not sure if the whole chain is needed or not, but I used a PEM file with the three concatenated certificates inside) to
Resources/raw/cert.pem -
Add the following as
Resources/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="@raw/cert"/>
<certificates src="system"/>
</trust-anchors>
</base-config>
</network-security-config>
- Annotate the MauiApplication with the following:
[Application(NetworkSecurityConfig = "@xml/network_security_config")] - Open a
TcpClientto the server in question (_client.ConnectAsync(host, port)) - Wrap the TCP client in
SslStream->var sslStream = new SslStream(_client.GetStream(), false, ValidateServerCert); - Implement
ValidateServerCertwith simplyreturn trueor anything you want - Call
sslStream.AuthenticateAsClientAsync(host, null, SslProtocols.Tls12, false) - Inspect the third argument of
ValidateServerCert
Expected behavior
The chain passed into the validation callback with the proper ChainElements
Actual behavior
ChainElements is length 0
Regression?
Not sure how to categorize this but at least with the mono workaround in place this works on the following platforms:
- .NET 6 Windows Console
- .NET 6 WinUI
- .NET 6 iOS
- .NET 6 Mac Catalyst
- Xamarin iOS
- Xamarin Android
- .NET Framework 4.6.2
Known Workarounds
Unknown at this time
Configuration
.NET 6 on Android API 26 x64 emulator
Other information
No response