0
votes

The official Xamarin documentation for App Transport Layer Security (iOS, Android) states that the managed HttpClient implementation does only support TLS 1.0. It strongly recommends updating Xamarin Apps to native HttpClient implementations to support TLS 1.2. Visual Studio states this as well:

enter image description here

However, the documentation is contradictory. When describing the managed HttpClient implementation, it states something like:

It is not fully integrated with the OS (eg. limited to TLS 1.0).

The documentation later has contradicting statements like:

Beginning with Xamarin.Android 8.3, HttpClientHandler defaults to Boring SSL ... It supports TLS 1.2+.

Furthermore, this very helpful Xamarin blog post states that TLS 1.2 is indeed possible with the managed HttpClient implementation by choosing the SSL/TLS option "native TLS 1.2" (which is the default on iOS and cannot be changed on iOS).

Last, but not least, I tested the HttpClient of the current stable Xamarin version1 against https://www.nist.gov, which only supports TLS 1.2. I verified that the server only accepts TLS 1.2 with:

openssl s_client -connect nist.gov:443 -no_tls1_2

If the managed HttpClient implementation really does only support TLS 1.0, I would expect that the following connection fails:

var client = new HttpClient();
var result = await client.GetStringAsync("https://www.nist.gov");

However, the connection succeeds with the following settings:

  • iOS: HttpClient implementation Managed
  • Android: HttpClient implementation Managed (HttpClientHandler) or Default, and SSL/TLS implementation Native TLS 1.2.

This leads me to the following questions:

  1. Is the Xamarin documentation outdated when stating that the managed HttpClient implementation does only support TLS 1.0?
  2. Is my test against the https://www.nist.gov valid? Does it indeed show that the managed HttpClient implementation supports TLS 1.2? Or am I missing something?

1 Visual Studio 7.5.2 (build 40), Xamarin.iOS 11.12.0.4, Xamarin.Android 8.3.3.2

1
The managed provider does NOT support TLS1.2... not sure about your testing, but you can review the code in the Mono repo and there is no 1.2 support.SushiHangover
@SushiHangover Yes, I believe this is where the two settings SSL/TLS implementation and the HttpClient implementation come into play. To my understand, the managed HttpClient implementation can use the native SSL/TLS provider on Xamarin.Android and Xamarin.iOS, which support TLS 1.2. The managed TLS provider only supports TLS 1.0, but is not active in the current default Xamarin project settings. E.g. this blogpost talks about this, if my understanding is correct.Stephan Palmer

1 Answers

2
votes

If you use the "native" handler (Android or iOS) it is using the native APIs to implement the HttpClientHandler features and thus is "platform dependent" upon whether or not TLS1.2 would be supported, i.e. Android 5/API-21 does not natively support TLS1.2, most Android developers use a 3rd-party lib...

When you enabled "native SSL/TLS" is it using Google's BoringSSL (that is now included into your app bundle) and not the native platform APIs. Thus TLS1.2 is supported even with the "Managed" HttpClientHandler. This option allows the ".Net framework/Mono" to support the latest SSL/TLS on iOS & Android, such as .Net Sockets, WebClient, etc.. and of course HttpClient.

https://www.nist.gov Test:

Android Handler / Managed SSL    :  No exception
Managed Handler / Native SSL/TLS :  No exception
Android Handler / Native SSL/TLS :  No exception
Managed Handler / Managed SSL    :  Error: SecureChannelFailure 

SecureChannelFailure:

MonoDroid] UNHANDLED EXCEPTION:
[MonoDroid] System.Net.Http.HttpRequestException: An error occurred while sending the request ---> System.Net.WebException: Error: SecureChannelFailure (The authentication or decryption has failed.) --->
System.IO.IOException: The authentication or decryption has failed. --->
System.IO.IOException: Error while sending TLS Alert (Fatal:InternalError): System.IO.IOException: The authentication or decryption has failed. --->
System.IO.IOException: Unable to read data from the transport connection: Connection reset by peer. ---> 
System.Net.Sockets.SocketException: Connection reset by peer