-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
X509Chain does not populate ChainElements (Android) #84202
Comments
Tagging subscribers to this area: @dotnet/ncl, @bartonjs, @vcsjones Issue DetailsDescriptionI am using That being said, now that the callback is finally being called, the Reproduction StepsI'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:
Expected behaviorThe Actual behavior
Regression?Not sure how to categorize this but at least with the mono workaround in place this works on the following platforms:
Known WorkaroundsUnknown at this time Configuration.NET 6 on Android API 26 x64 emulator Other informationNo response
|
Tagging subscribers to 'arch-android': @steveisok, @akoeplinger Issue DetailsDescriptionI am using That being said, now that the callback is finally being called, the Reproduction StepsI'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:
Expected behaviorThe Actual behavior
Regression?Not sure how to categorize this but at least with the mono workaround in place this works on the following platforms:
Known WorkaroundsUnknown at this time Configuration.NET 6 on Android API 26 x64 emulator Other informationNo response
|
cc: @simonrozsival |
I should also add that the .NET runtime does not seem aware of the network security config and still says that the result is "PartialChain". For more insight to how I am actually trying to use this here is a link to the actual production validation function. Given that it won't even make it here in the first place unless there are some Android workarounds, should I just not bother with the custom validation and just assume that the fact that it made it to the validation function at all means that the user wants to trust it? |
@borrrden Hi, thanks for reporting this issue. We've made some changes to how certificate validation works on Android and you won't need the workaround with the network security config in .NET 8 anymore and the validation callback will be called directly. The problem with X509Chain behaving differently from the other platforms hasn't been resolved so far though. @wfurt It doesn't seem it's currently possible to build an Lines 196 to 213 in 24fa97a
|
My understanding of Android is that This is reflected in our unit tests: |
In this case, due to the network security config, the chain should be valid but it still reports as partial chain. EDIT For informational purposes, the underlying Java API will validate the certificate correctly:
FURTHER EDIT I'm trying to get a chain to function with cert pinning but it seems like the
Which I've learned is because the certificate I want to pin is not self-signed (I am trying to pin an intermediate cert) |
Is there an alternative way to construct the chain so that I can examine it then? I'm trying to figure out if a programmatically provided certificate matches any cert in the chain. |
Can we get the certificates from the the security config @simonrozsival ? Note that the chain is nullable https://learn.microsoft.com/en-us/dotnet/api/system.net.security.remotecertificatevalidationcallback?view=net-6.0 We may simply not pass it but I don't think that would improve the situation here. |
@simonrozsival can you follow up on this when you have a moment? |
@wfurt My understanding is that certificates included via network security config should behave as if they were installed on the system and the certificate chain should be valid and the chain elements should be populated correctly. I'm not sure why Android doesn't trust the certificate in this case (and we therefore don't populate the chain elements). I believe we'll need to revisit how the X509Chain is built on Android. It is one of the features of the PAL that's not fully implemented (see #45741). I'll move the issue now to the Future milestone for now (same as #45741). |
yes, that would be preferable IMHO @simonrozsival. The question is if .NET has any access to those certificates. |
Certificates that devs bundle in the app so that they can use them in the network_security_config.xml should be accessible in code as any other file AFAIK, so devs should be able to build the chain themselves 🤔 is that what you meant, @wfut? |
yes. What we would need is to get the content via API or we would need to parse it ourselves and extract the certificates. |
I don't know if you found a workaround, and I am not sure if this applies to the exact same use case but here goes: The use case is the service I call with the HttpClient, returns 2 certificates, one LeafCertificate and an Intermediary certificate, where I needed to verify these with a root certificate. bool ServerCertificateCustomValidationCallback(HttpRequestMessage httpRequestMessage, X509Certificate? cert, X509Chain? cetChain, SslPolicyErrors sslPolicyErrors) On the HttpHandler. I implemented the following: if (cert == null) return false;
if (cetChain == null) return false;
var RootCert = new System.Security.Cryptography.X509Certificates.X509Certificate2(CertResources.RootCert);
cetChain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
cetChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
cetChain.ChainPolicy.CustomTrustStore.AddRange(cetChain.ChainPolicy.ExtraStore);
cetChain.ChainPolicy.CustomTrustStore.Add(RootCert);
var chainBuidlResult = cetChain.Build(cert); where CertResources is a resource file containing the .PEM Root CA certificate. |
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 useX509Chain.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
[Application(NetworkSecurityConfig = "@xml/network_security_config")]
TcpClient
to the server in question (_client.ConnectAsync(host, port)
)SslStream
->var sslStream = new SslStream(_client.GetStream(), false, ValidateServerCert);
ValidateServerCert
with simplyreturn true
or anything you wantsslStream.AuthenticateAsClientAsync(host, null, SslProtocols.Tls12, false)
ValidateServerCert
Expected behavior
The
chain
passed into the validation callback with the properChainElements
Actual behavior
ChainElements
is length 0Regression?
Not sure how to categorize this but at least with the mono workaround in place this works on the following platforms:
Known Workarounds
Unknown at this time
Configuration
.NET 6 on Android API 26 x64 emulator
Other information
No response
The text was updated successfully, but these errors were encountered: