dotnet / android

.NET for Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#
MIT License
1.92k stars 526 forks source link

Javax.Net.Ssl.SSLHandshakeException: TLSV1_ALERT_NO_APPLICATION_PROTOCOL #8542

Closed jfversluis closed 3 months ago

jfversluis commented 10 months ago

Issue moved from dotnet/maui#19092


From @LongJohnBlackbeard on Tuesday, November 28, 2023 10:37:10 PM

Description

Created a MAUI Blazor Hybrid application for a R&D project that makes HTTPS REST calls to a on prem ERP API layer that uses TLSv1.2 or 1.3. When running the project the windows machine works fine but gives SSL errors when run on an android emulator or a physical device. Most issues and stackoverflow posts i've seen related to this regard locally hosted APIs and more often than not the solution is to bypass SSL checks. I am not calling a local API but a ERP servers test environment, I make calls to this server in many other applications with no issues.

I have removed auth or url links from code below.

Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:allowBackup="true" android:icon="@mipmap/appicon" android:supportsRtl="true" android:usesCleartextTraffic="true"></application>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-sdk android:targetSdkVersion="34" android:minSdkVersion="33" />
</manifest>

Service

public class JDEService : IJDEService
    {
        private HttpClientHandler httpHandler;

        public JDEService()
        {
            httpHandler = new HttpClientHandler();
        }

        public async Task<List<WORoutings>> GetWORouting(int WorkOrderNumber)
        {

            var baseURL = "*********************************";            
            var httpClient = new HttpClient(httpHandler);
            List<WORoutings> routings = new List<WORoutings>();            
            var auth = Convert.ToBase64String(ASCIIEncoding.UTF8.GetBytes(<AUTH STUFF HERE>));
            httpClient.DefaultRequestHeaders.Add(<AUTH STUFF HERE>);
            try
            {
                var response = await httpClient.GetAsync($"{baseURL}<URLHERE>");
                var message = await response.Content.ReadAsStringAsync();

                if (response.IsSuccessStatusCode)
                {

                    var json = JsonConvert.DeserializeObject<WORoutingRoot>(response.Content.ReadAsStringAsync().Result);
                    routings = json.SF_DREQ_F3112_GetWORouting.rowset;
                    return routings;
                }
                else
                {
                    throw new Exception($"ERROR: {response.StatusCode} \n Message: {response.ReasonPhrase}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + "\n" + ex.InnerException + "\n" + ex.StackTrace);
            }

            return routings;
        }
    }

Steps to Reproduce

Create .NET MAUI Blazor Hybrid Application Create Interface and Service to make HTTPS calls to a API layer enforcing TLSv1.2 or 1.3 Run the application on ann android device or emulator

Link to public reproduction project repository

No response

Version with bug

8.0.3

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android 13 API 33

Did you find any workaround?

Have not been able to get it to work on Android

Relevant log output

[DOTNET] javax.net.ssl.SSLHandshakeException: Read error: ssl=0x7ad5ffc45418: Failure in SSL library, usually a protocol error
[DOTNET] error:10000460:SSL routines:OPENSSL_internal:TLSV1_ALERT_NO_APPLICATION_PROTOCOL (external/boringssl/src/ssl/tls_record.cc:594 0x7ad61fc78358:0x00000001)
[DOTNET]    at com.android.org.conscrypt.SSLUtils.toSSLHandshakeException(SSLUtils.java:363)
[DOTNET]    at com.android.org.conscrypt.ConscryptEngine.convertException(ConscryptEngine.java:1134)
[DOTNET]    at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:919)
[DOTNET]    at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:747)
[DOTNET]    at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:712)
[DOTNET]    at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:858)
[DOTNET]    at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.-$$Nest$mprocessDataFromSocket(Unknown Source:0)
[DOTNET]    at com.android.org.conscrypt.ConscryptEngineSocket.doHandshake(ConscryptEngineSocket.java:241)
[DOTNET]    at com.android.org.conscrypt.ConscryptEngineSocket.startHandshake(ConscryptEngineSocket.java:220)
[DOTNET]    at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:196)
[DOTNET]    at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:153)
[DOTNET]    at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
[DOTNET]    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
[DOTNET]    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
[DOTNET]    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
[DOTNET]    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
[DOTNET]    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
[DOTNET]    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
[DOTNET]    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
[DOTNET]    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
[DOTNET]    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30)
[DOTNET] Caused by: javax.net.ssl.SSLProtocolException: Read error: ssl=0x7ad5ffc45418: Failure in SSL library, usually a protocol error
[DOTNET] error:10000460:SSL routines:OPENSSL_internal:TLSV1_ALERT_NO_APPLICATION_PROTOCOL (external/boringssl/src/ssl/tls_record.cc:594 0x7ad61fc78358:0x00000001)
[DOTNET]    at com.android.org.conscrypt.NativeCrypto.ENGINE_SSL_read_direct(Native Method)
[DOTNET]    at com.android.org.conscrypt.NativeSsl.readDirectByteBuffer(NativeSsl.java:569)
[DOTNET]    at com.android.org.conscrypt.ConscryptEngine.readPlaintextDataDirect(ConscryptEngine.java:1095)
[DOTNET]    at com.android.org.conscrypt.ConscryptEngine.readPlaintextData(ConscryptEngine.java:1079)
[DOTNET]    at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:876)
[DOTNET]    ... 18 more
[DOTNET] 
[DOTNET]    at Xamarin.Android.Net.AndroidMessageHandler.<>c__DisplayClass133_0.<ConnectAsync>b__0() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 536
[DOTNET]    at System.Threading.Tasks.Task.InnerInvoke()
[DOTNET]    at System.Threading.Tasks.Task.<>c.<.cctor>b__281_0(Object obj)
[DOTNET]    at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
[DOTNET] --- End of stack trace from previous location ---
[DOTNET]    at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
[DOTNET]    at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
[DOTNET] --- End of stack trace from previous location ---
[DOTNET]    at Xamarin.Android.Net.AndroidMessageHandler.DoProcessRequest(HttpRequestMessage request, URL javaUrl, HttpURLConnection httpConnection, CancellationToken cancellationToken, RequestRedirectionState redirectState) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 591
[DOTNET]    at Xamarin.Android.Net.AndroidMessageHandler.DoSendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 456
[DOTNET]    at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
[DOTNET]    at MauiApp1.Services.JDEService.GetWORouting(Int32 WorkOrderNumber) in C:\Users\dtujo\source\repos\MauiApp1\MauiApp1\Services\JDEService.cs:line 28
jfversluis commented 10 months ago

Issue moved from dotnet/maui#19092


From @jfversluis on Wednesday, November 29, 2023 10:07:13 AM

I think there have been issues about this before and if anything this probably belongs on this repo: https://github.com/xamarin/xamarin-android

@jonpryor ?

jfversluis commented 10 months ago

Issue moved from dotnet/maui#19092


From @msftbot[bot] on Wednesday, November 29, 2023 12:25:19 PM

Hi @LongJohnBlackbeard. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

jfversluis commented 10 months ago

Issue moved from dotnet/maui#19092


From @mattleibow on Wednesday, November 29, 2023 12:25:57 PM

Does this work on Windows?

If not, then we can move to runtime, otherwise this is an Android issue.

jfversluis commented 10 months ago

Issue moved from dotnet/maui#19092


From @LongJohnBlackbeard on Wednesday, November 29, 2023 1:31:56 PM

Does this work on Windows?

If not, then we can move to runtime, otherwise this is an Android issue.

Worked in windows but not in android emulator or android physical device.

simonrozsival commented 7 months ago

@LongJohnBlackbeard I'm not able to reproduce the issue. I was able to make HTTP requests to servers with TLS v1.3. TLS v1.3 should be supported on Android on API levels 29+. Can you please try running the following code?

var httpClient = new HttpClient(new AndroidMessageHandler());
var response = await httpClient.GetAsync("https://www.howsmyssl.com/a/check");
var message = await response.Content.ReadAsStringAsync();
var supportsTls13 = message.Contains("\"tls_version\":\"TLS 1.3\"");
Console.WriteLine(supportsTls13);
tuyen-vuduc commented 4 months ago

A simple .NET Android app cannot call to a local hosted .NET API app. Any workarounds?

simonrozsival commented 4 months ago

@LongJohnBlackbeard have you been able to resolve this issue? I have tried reproducing it again and I'm still not able to observe the same failure. I would need more information to be able to do something about this issue.

@tuyen-vuduc my first thought is that you need to correctly setup port forwarding using adb (see https://developer.android.com/tools/adb#forwardports). Please open a new issue and provide more details if this doesn't help.

tuyen-vuduc commented 4 months ago

@simonrozsival I worked around by utilizing ngrok. I didn't try ADB option yet.

dotnet-policy-service[bot] commented 3 months ago

Hi @jfversluis. Due to inactivity, we will be closing this issue. Please feel free to re-open this issue if the issue persists. For enhanced visibility, if over 7 days have passed, please open a new issue and link this issue there. Thank you.