-
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
[AndroidCrypto] Basic SSL stream implementation #50519
Conversation
TODO - calling AndroidCrypto.SSLStreamHandshake results in stack overflow
Now working with: new HttpClient().GetStringAsync("https://api.github.com/zen")
Tagging subscribers to this area: @dotnet/ncl, @vcsjones Issue DetailsGet basic (system-default-only) functionality working for SSL stream on Android.
This enables the basic scenario called out in #45739: using (var client = new HttpClient())
{
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("TestApp","1.0"));
string s = await client.GetStringAsync("https://api.github.com/zen");
s = await client.GetStringAsync("https://mail.google.com/mail");
} Any options other than system default (e.g. specifying The main difference with the implementation versus other platforms is that Android always verifies the certificates received during a handshake using the default trust manager.
Most tests are still failing, but some outerloop tests that hit an external server (where the certs are trusted by the system) and just use system defaults pass (e.g.
|
...raries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Ssl.cs
Outdated
Show resolved
Hide resolved
...raries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.Ssl.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Jeremy Barton <[email protected]>
src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Android.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Android.cs
Outdated
Show resolved
Hide resolved
I mostly skimmed through the shim code and PAL status transitions, hoping that @wfurt will do the deeper review there. |
src/libraries/Native/Unix/System.Security.Cryptography.Native.Android/pal_sslstream.c
Outdated
Show resolved
Hide resolved
jmethodID g_ByteBufferAllocate; | ||
jmethodID g_ByteBufferCompact; | ||
jmethodID g_ByteBufferFlip; | ||
jmethodID g_ByteBufferGet; | ||
jmethodID g_ByteBufferLimit; | ||
jmethodID g_ByteBufferPosition; | ||
jmethodID g_ByteBufferPutBuffer; | ||
jmethodID g_ByteBufferPutByteArray; | ||
jmethodID g_ByteBufferPutByteArrayWithLength; | ||
jmethodID g_ByteBufferRemaining; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to use some of the JNI NIO apis to make the byte buffers instead of calling the byte buffer methods through JNI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I stuck with the simplicity of going through these methods, since they handle all the mark / position / limit tracking. If we do the direct access through the JNI NIO support, we'd have to update those ourselves which would make things a bit more complex.
I'd prefer to go with the simpler way right now and note it as a possible future improvement/investigation that could improve perf.
src/libraries/Native/Unix/System.Security.Cryptography.Native.Android/pal_jni.h
Outdated
Show resolved
Hide resolved
src/libraries/Native/Unix/System.Security.Cryptography.Native.Android/pal_sslstream.c
Outdated
Show resolved
Hide resolved
@wfurt could you take a look, please? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Looks like good improvement.
The lack of validation callback is somewhat concerning. Most users would either stick to system default or use it to override decision on self-signed certificates or use it for custom trust. if I read the comments right, neither use case will really work. If this is difficult, we should document it properly.
It seems like SslProtocols could be implemented. I think it is ok if the platform does not support some older version.
I check HttpClient and it sets ApplicationProtocols only if intending to use HTTP/2+
So the base use case should be OK.
CipherSuitesPolicy throws PNSP on Windows so I would see that is nice to have but certainly not critical.
Thanks @wfurt! The context you provided around the different options is very helpful.
Yes, neither use of the callback for self-signed certificates or custom trust will really work. The only thing that would work (aside from just using the system default) is if a user wants to reject a certificate that is accepted by the system default. The current plan is to make sure it is properly documented.
Agreed - planning on doing SslProtocols once this change goes in. |
Merging, since all these changes are Android-only and the Android CI legs have gone through (and build infrastructure for Windows is still having stress). |
Get basic (system-default-only) functionality working for SSL stream on Android.
AndroidCrypto_SSLStream*
functions to managedThis enables the basic scenario called out in #45739:
Any options other than system default (e.g. specifying
ApplicationProtocols
,CipherSuitesPolicy
,SslProtocols
) still throwNotImplementedException
.The main difference with the implementation versus other platforms is that Android always verifies the certificates received during a handshake using the default trust manager.
RemoteCertificateValidationCallback
will only get an opportunity to validate certificates that have already been accepted by the system's built-in trust manager.Most tests are still failing, but some outerloop tests that hit an external server (where the certs are trusted by the system) and just use system defaults pass (e.g.
CertificateValidationRemoteServer
, somePostScenarioTest
)cc @jkoritzinsky @steveisok @AaronRobinsonMSFT @bartonjs @wfurt