Skip to content

[Android] WebRequest causes SSL exception on Android API <= 23 on .NET 8 #94230

@Redth

Description

@Redth

Description

There's SSL failures on .NET Android app code when using WebRequest.Create instead of HttpClient API's in .NET 8.0 when running on API levels 23 or older. This previously worked in .NET 7.

Reproduction Steps

Working:

using var client = new HttpClient();
var content = await client.GetStringAsync("https://webcode.me");
Console.WriteLine(content);

Failing:

WebRequest webRequest = WebRequest.Create("https://webcode.me");
webRequest.Method = "GET";
using (var webResponse = webRequest.GetResponse() as HttpWebResponse)
{
    using (var inStream = webResponse.GetResponseStream())
    {
        using (var reader = new StreamReader(inStream))
        {
            var responseString = reader.ReadToEnd();
            Console.WriteLine(responseString);
        }
    }
}

Run this code in a net8.0-android app on API Level 23 or older (so Android 6.0 or older).
You can validate it works by running on API Level 24 or newer (Android 7.0 or newer).

Expected behavior

No exceptions

Actual behavior

Exception (see stack trace below).

Regression?

Yes, this appears to be a regression from .NET 7

Known Workarounds

No response

Configuration

No response

Other information

Stack trace for failure:

[DOTNET] System.Net.WebException: The SSL connection could not be established, see inner exception.
[DOTNET]  ---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
[DOTNET]  ---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
[DOTNET]  ---> Interop+AndroidCrypto+SslException: Exception of type 'Interop+AndroidCrypto+SslException' was thrown.
[DOTNET]    --- End of inner exception stack trace ---
[DOTNET]    at System.Net.Security.SslStream.<ForceAuthenticationAsync>d__150`1[[System.Net.Security.AsyncReadWriteAdapter, System.Net.Security, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
[DOTNET]    at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
[DOTNET]    --- End of inner exception stack trace ---
[DOTNET]    at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
[DOTNET]    at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
[DOTNET]    at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
[DOTNET]    at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem)
[DOTNET]    at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1[[System.Net.Http.HttpConnection, System.Net.Http, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].WaitWithCancellation(CancellationToken cancellationToken)
[DOTNET]    at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1[[System.Net.Http.HttpConnection, System.Net.Http, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].WaitWithCancellationAsync(Boolean async, CancellationToken cancellationToken)
[DOTNET]    at System.Net.Http.HttpConnectionPool.HttpConnectionWaiter`1[[System.Net.Http.HttpConnection, System.Net.Http, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].WaitForConnectionAsync(HttpRequestMessage request, HttpConnectionPool pool, Boolean async, CancellationToken requestCancellationToken)
[DOTNET]    at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
[DOTNET]    at System.Net.Http.HttpMessageHandlerStage.Send(HttpRequestMessage request, CancellationToken cancellationToken)
[DOTNET]    at System.Net.Http.Metrics.MetricsHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
[DOTNET]    at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
[DOTNET]    at System.Net.Http.HttpMessageHandlerStage.Send(HttpRequestMessage request, CancellationToken cancellationToken)
[DOTNET]    at System.Net.Http.SocketsHttpHandler.Send(HttpRequestMessage request, CancellationToken cancellationToken)
[DOTNET]    at System.Net.Http.HttpMessageInvoker.Send(HttpRequestMessage request, CancellationToken cancellationToken)
[DOTNET]    at System.Net.Http.HttpClient.Send(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
[DOTNET]    at System.Net.HttpWebRequest.SendRequest(Boolean async)
[DOTNET]    at System.Net.HttpWebRequest.GetResponse()
[DOTNET]    --- End of inner exception stack trace ---
[DOTNET]    at System.Net.HttpWebRequest.GetResponse()
[DOTNET]    at HttpsSampleApp.MainActivity.<OnCreate>b__1_1(Object sender, EventArgs args) in C:\Users\user\Downloads\HttpsSampleApp\HttpsSampleApp\MainActivity.cs:line 40

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions