dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.16k stars 4.72k forks source link

Implement System.Security.Cryptography.Native.Android PAL #45741

Open steveisok opened 3 years ago

steveisok commented 3 years ago

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

System.Security.Cryptogaphy

System.Net.Security

Not supported

The following are not supported on Android. They should be documented, marked with UnsupportedOSPlatform, and/or throw PlatformNotSupportedException as appropriate.

System.Security.Cryptogaphy

System.Net.Security

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.

System.Security.Cryptogaphy

System.Net.Security

Clean-up

Other

JamesNK commented 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

steveisok commented 3 years ago

@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.

JamesNK commented 3 years ago

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.

Eilon commented 2 years ago

@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.

rgroenewoudt commented 1 year ago

Using SSLStream or Websockets on Android < 9 is also currently broken, which is a breaking change for people coming from the classic Xamarin

Using HTTPClient SSL also doesn't work in Android 5-6, which is also a breaking change.

awakecoding commented 1 year ago

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?

steveisok commented 1 year ago

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.

jkoritzinsky commented 1 year ago

Marking the remainder of this issue as Future like https://github.com/dotnet/runtime/issues/45737

dotMorten commented 1 year ago

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?

borrrden commented 11 months ago

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?

CedreLo commented 11 months ago

Any news on this ?

simonrozsival commented 11 months ago

@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.

CedreLo commented 11 months ago

Great news!

as soon as visual studio will support ..NET8, i will switch to .NET8

borrrden commented 11 months ago

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.

simonrozsival commented 11 months ago

@borrrden yes, SslStream will now use the validation callback you pass into the constructor.

akoeplinger commented 11 months ago

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/

dotMorten commented 11 months ago

@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).

simonrozsival commented 11 months ago

@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.

dotMorten commented 7 months ago

@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