Open steveisok opened 3 years ago
[ ] Non-system-default certificate validation
- Any
RemoteCertificateValidationCallback
will only get an opportunity to validate certificates that have already been accepted by the system's built-in trust manager.- This means that the use cases of the callback for self-signed certificates or custom trust will not work.
This makes testing against a local ASP.NET Core web app that is using a self-signed development certificate difficult.
Couldn't this be supported by creating a custom SSLSocketFactory? If RemoteCertificateValidationCallback
is configured then there is a factory that trusts all certificates. Cert details are then passed to the callback so it can make a decision about whether the cert is allowed or not.
SO answer about it - https://stackoverflow.com/a/6378872 Blog post - http://howardism.org/Technical/Java/SelfSignedCerts.html
@JamesNK we made the decision early on to make this a purely JNI integration. Android doesn't support creating Java classes out of JNI, which I believe makes a custom trust manager not possible.
This is something we could look at trying to support in net7.
There are a number of options suggested in the SO thread that don't involve creating new Java classes. However, I don't know Java and Android HTTP APIs so I don't know what approaches are valid.
@JamesNK said:
This makes testing against a local ASP.NET Core web app that is using a self-signed development certificate difficult.
I started a discussion topic on how to connect from Android emulators to a local ASP.NET Web API running on Windows: https://github.com/dotnet/maui/discussions/8131
Please check that out and let us know if you have any feedback on any of the solutions presented.
Any update on this? We are hard-blocked on this to migrate RDM Android from Xamarin to .NET 6 since it breaks SQL Server connections, and it's unfortunately a feature that many of our users consider critical. What can we do to help expedite the process? While I don't particularly like the idea, would it be possible to work around the issue temporarily by building the .NET runtime from source with the changes from this branch? Is there enough implemented to fix the SQL server connection issue?
Any update on this?
For https://github.com/dotnet/SqlClient/issues/1656, I suspect https://github.com/dotnet/runtime/pull/78849 would fix things for you. Unfortunately, that fix won't be available until the February update of .NET 7 and .NET 6.
You could build from source yourself, but I think it'll be rather painful updating all the places you need to. There isn't any real guidance on how to do that.
Marking the remainder of this issue as Future like https://github.com/dotnet/runtime/issues/45737
I'm hitting an issue with being able to use Android's Certificate picker (KeyChain.ChoosePrivateKeyAlias
), and reusing the certificate with SocketsHttpHandler. Since installed certificates can't export the private key, I can't really convert it to a .NET certificate.
With the old Android client handlers, you would override ConfigureCustomSSLSocketFactory
and returning the SSLSocketFactory to use the chosen certificate.
Would this issue also address this need?
Has anything regarding this been done in .NET 8? Specifically I need to know if I can use a custom TLS certificate verification callback yet. In .NET 6 / 7 the only way to accomplish this is by having a system trusted certificate setup ahead of time (usually via network_security.config or whatever it is called), but in a P2P model this fails because often certs are generated on the fly purely to get the encryption portion. This means they are rejected without any remedy to explicitly trust them programmatically (the callback is simply not called and the certs are marked as untrusted)
Wait reading back I see
Non-system-default certificate validation
Any RemoteCertificateValidationCallback will only get an opportunity to validate certificates that have already been accepted by the system's built-in trust manager.
This means that the use cases of the callback for self-signed certificates or custom trust will not work.
So this is never going to be supported?
Any news on this ?
@borrrden @CedreLo hey! we shipped support for RemoteCertificateValidationCallback
on Android in .NET 8 (#77386). You should also be able to use HttpClientHandler. ServerCertificateCustomValidationCallback
and SocketsHttpHandler.SslOptions.RemoteCertificateValidationCallback
.
I'll update this issue to reflect this, sorry for the confusion. Let me know if you run into any issues with the custom certificate validation.
Great news!
as soon as visual studio will support ..NET8, i will switch to .NET8
To clarify, will this also work with SslStream
using the validation callback passed into the constructor? That is the use case we are currently using. The linked issue indicates yes.
@borrrden yes, SslStream
will now use the validation callback you pass into the constructor.
as soon as visual studio will support ..NET8, i will switch to .NET8
@CedreLo Visual Studio 2022 version 17.8 has full support for .NET8: https://devblogs.microsoft.com/visualstudio/visual-studio-17-8-now-available/
@simonrozsival Will we now also be able to use the certificates installed on the device? Like the ones coming from KeyChain.ChoosePrivateKeyAlias
? We can create the X509Certificate with the Java Pointer to the Java certificate just fine, but the private key isn't directly available for .NET to use, and need to use the underlying Java APIs to authenticate the stream. (So far I've only been able to use certificates that are loaded from a file on disk and has full access to the private key, but that's not generally how customers deploy their PKI certificates, since it creates a risk of exporting the private key).
@dotMorten I think there currently isn't a good way to access the certificates installed on device without using the Java APIs directly. Have you already opened an issue with the use case? If not, could you please open one? We could then discuss if that's something to look into in .NET 9.
@simonrozsival For some reason I missed your comment, and for a while thought the issue was the same as this one - I've added a separate issue: https://github.com/dotnet/runtime/issues/99874
Since we're not able to ship Openssl w/ Android, we need to implement as much as we can with the Android API's.
Implementation
-avd <emulatorName> -memory 3072 -wipe-data -delay-adb -skip-adb-auth -no-boot-anim -no-window -no-audio -gpu swiftshader_indirect -logcat-output '/tmp/<emulatorName>-logcat.log'
System.Security.Cryptogaphy
System.Net.Security
HttpClient
setsApplicationProtocols
only if intending to use HTTP/2+CipherSuitesPolicy
throws PNSE on Windows, so this is nice to have, but not criticalRemoteCertRequired
) - #51187SslStreamPal.QueryContextChannelBinding
- #51316CertificateValidationPal.GetRequestCertificateAuthorities
Not supported
The following are not supported on Android. They should be documented, marked with
UnsupportedOSPlatform
, and/or throwPlatformNotSupportedException
as appropriate.System.Security.Cryptogaphy
RC2
algorithmCreateDecryptor
andCreateEncryptor
currently throw PNSE,Create
does notIncrementalHash.GetCurrentHash
using HMACAllowUnknownCertificateAuthority
,IgnoreInvalidName
,IgnoreInvalidPolicy
,IgnoreTimeNotValid
X509Chain.Build
will return false and havePartialChain
status with no certificatesX509RevocationMode
:Offline
treated asOnline
X509RevocationFlag
:EntireChain
treated asExcludeRoot
PKIXRevocationChecker
(API level <24)System.Net.Security
Any- resolved in .NET 8RemoteCertificateValidationCallback
will only get an opportunity to validate certificates that have already been accepted by the system's built-in trust manager.This means that the use cases of the callback for self-signed certificates or custom trust will not work.- resolved in .NET 8EncryptionPolicy.NoEncryption
(onSslClientAuthenticationOptions.EncryptionPolicy
orSslServerAuthenticationOptions.EncryptionPolicy
)HttpClientHandler.SslProtocols
,SslClientAuthenticationOptions.EnabledSslProtocols
, orSslServerAuthenticationOptions.EnabledSslProtocols
):SslProtocols.Ssl2
- not supportedSslProtocols.Ssl3
- not supportedSslProtocols.Tls13
- only on some versions of Android (>= API level 29)SslClientAuthenticationOptions.TargetHost
)Future improvements
The following should be considered after the initial implementation. If it is determined they are desired, they can be split into their own issues.
CryptographicException
.System.Security.Cryptogaphy
KeyStore
CertPathValidatorException.getReason
(API level <24)CertificateException
types to determine a better statusSystem.Net.Security
TrustManager
. Android doesn't allow defining a class via JNI, so doing this would involve actually creating/shipping a Java class.KeyStore
and useTrustManagerFactory
to create and initialize a trust manager with it.Clean-up
Other