This is an update on our efforts to upgrade the TLS stack in Mono.
You can skip to the summary at the end if you do not care about the sausage making details.
Currently, TLS is surfaced in a few places in the .NET APIs:
SslStream
class, which
is a general purpose class that can be used to turn
any bidirectional stream into an TLS-powered stream.
This class is what currently powers the web client in
Mono.HttpWebRequest
class, which
provides .NET's HTTP client. This in turn is the
foundation for the modern HttpClient
, both the WCF and
WebServices stacks as well as the quick and
dirty WebClient
API.HttpClient
is in particular interesting, as it
allows for different transports to be provided for it. The
default implementation in .NET 4.5 and Mono today is to use
an HttpWebRequest
-based implementation. But on
Windows 10, the implementation is replaced with one that uses
WinRT's HTTP client.
Microsoft is encouraging developers to
abandon HttpWebRequest
and instead
adopt HttpClient
as it both async-friendly and
can use the best available transport given on a specific
platform. More on this in a second.
Mono currently only supports TLS 1.0.
This is the stack that powers SslStream
and HttpWebRequest
.
Last year we started an effort to bring managed implementations of TLS 1.2 and TLS 1.1. Given how serious security has become and how many holes have been found in existing implementation, we built this with an extensive test suite to check for conformance and to avoid common exploits found in implementation mistakes of TLS. This effort is currently under development and you can see where it currently lives at mono-tls module.
This will give us complete TLS support for the entire stack, but this work is still going to take a few months to audit.
Most of the uses for TLS today is via the HTTP protocol,
and not over custom TLS streams. This means that it is more
important to get an HTTP client that supports a brand new TLS
stack, than it is to provide the SslStream
code.
We want to provide native HttpClient
handlers
for all of Mono's supported platforms: Android, iOS, Mac,
Linux, BSD, Unix and Windows.
On iOS: Today Xamarin.iOS already ships a native
handler,
the CFNetworkHandler
.
This one is powered by Apple's CFNetwork stack. In recent
years, Apple has improved their networking stack, and we now I
strongly recommend using Paul Bett's
fantastic ModernHttpClient
which uses iOS' brand new NSUrlSession and uses OkHttp on
Android.
On Android: in the short term, we recommend adopting ModernHttpClient from Paul Betts (bonus points: the same component works on iOS with no changes). In the long term, we will change the default handler to use the Android Java client.
In both cases, you end up with HTTP 2.0 capable clients for free.
But this still leaves Linux, Windows and other assorted operating systems without a regular transport.
For those platforms, we will be adopting the CoreFX handlers, which on Unix are powered by the libcurl library.
This still leaves HttpWebRequest
and
everything built on top of it running on top of our TLS
stack.
While this is not really TLS related, we wanted to bring Microsoft's implementations of those two classes to Mono, as they would fix many odd corner cases in the API, and address limitations in our stack that do not exist in Microsoft's implementation.
But the code is tightly coupled to native Windows APIs which makes the adoption of this code difficult.
We have built an adaptation layer that will allow us to bring Microsoft's code and use Mono's Managed TLS implementation.
Our original effort focused on a pure managed implementation of TLS because we want to ensure that the TLS stack would work on all available platforms in the same way. This also means that all of the .NET code that expects to control every knob of your secure connection to work (pinning certificates or validating your own chains for example).
That said, in many cases developers do not need this capabilities, and in fact, on Xamarin.iOS, we can not even provide the functionality, as the OS does not give users access to the certificate chains.
So we are going to be developing at least two
separate SslStream
implementations. For Apple
systems, we will be implementing a version on top of Apple's
SSL stack, and for other systems we will be developing an
implementation on top of Amazon's new SSL library, or the
popular OpenSSL variant of the day.
These have the advantage that we would not need to maintain the code, and we benefit from third parties doing all the hard security work and will be suitable for most uses.
For those rare uses that like to handle connections manually, you will have to wait for Mono's new TLS implementation to land.
Android, Mac and iOS users can get the latest TLS for HTTP
workloads
using ModernHttpClient.
Mac/iOS users can use the
built-in CFNetworkHandler
as well.
Soon: OpenSSL/AppleSSL based transports to be available in Mono (post Mono 4.2).
Soon: Advanced .NET SSL use case scenarios will be supported with Mono's new mono-tls stack
Soon: HttpWebRequest
and SslStream
stacks will be replaced in Mono
with Microsoft's implementations.
Posted on 27 Aug 2015