Xamarin-macios: Certificate pinning using NSUrlSessionHandler

Created on 1 Jun 2018  路  24Comments  路  Source: xamarin/xamarin-macios

Steps to Reproduce

  1. Attempt to implement certificate pinning for NSUrlSessionHandler
  2. ??
  3. Cry 馃槶

Expected Behavior

I expected to be able to implement a delegate, such as NSUrlSessionDataDelegate, or event like ServicePointManager.ServerCertificateValidationCallback to check the certificate. Both for trusting self signed certificates and for pinning certificates. I am mostly interested in the latter.

Actual Behavior

NSUrlSessionHandlerDelegate is private and contains a bunch of the necessary logic for NSUrlSessionHandler to even function.

NSUrlSession which uses the delegate is a private readonly member variable, so it cannot easily be set either.

The only way to implement this for NSUrlSessionHandler is to yank the code from this repository and modify it. Which isn't really an optimal solution.

It is a similar story with Android, no out of the box hooks into the events for validating certificates, just like you get with the managed implementation and ServicePointManager.

Environment

=== Visual Studio Enterprise 2017 for Mac ===

Version 7.5.1 (build 22)
Installation UUID: f274f3d1-0b76-4491-bdf0-60aa84226638
Runtime:
    Mono 5.10.1.47 (2017-12/8eb8f7d5e74) (64-bit)
    GTK+ 2.24.23 (Raleigh theme)
    Xamarin.Mac 4.4.1.178 (master / eeaeb7e6)

    Package version: 510010047

=== NuGet ===

Version: 4.3.1.4445

=== .NET Core ===

Runtime: /usr/local/share/dotnet/dotnet
Runtime Version: 2.0.5
SDK: /usr/local/share/dotnet/sdk/2.1.4/Sdks
SDK Version: 2.1.4
MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/5.10.1/lib/mono/msbuild/15.0/bin/Sdks

=== Xamarin.Profiler ===

Version: 1.6.2
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Xamarin.Android ===

Version: 8.3.0.19 (Visual Studio Enterprise)
Android SDK: /Users/tomasci/Library/Developer/Xamarin/android-sdk-macosx
    Supported Android versions:
        6.0 (API level 23)
        7.0 (API level 24)
        7.1 (API level 25)
        8.0 (API level 26)
        8.1 (API level 27)

SDK Tools Version: 26.1.1
SDK Platform Tools Version: 27.0.1
SDK Build Tools Version: 27.0.3

Java SDK: /usr
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

=== Xamarin Inspector ===

Version: 1.4.0
Hash: b3f92f9
Branch: master
Build date: Fri, 19 Jan 2018 22:00:34 GMT
Client compatibility: 1

=== Apple Developer Tools ===

Xcode 9.3 (14154)
Build 9E145

=== Xamarin.Mac ===

Version: 4.4.1.178 (Visual Studio Enterprise)

=== Xamarin.iOS ===

Version: 11.10.1.178 (Visual Studio Enterprise)
Hash: 408d3574
Branch: d15-7
Build date: 2018-05-08 18:56:30-0400

=== Build Information ===

Release ID: 705010022
Git revision: 60442dd643a20c7a4ae1f8705b8d1de8972eee78
Build date: 2018-05-15 01:43:39+00
Xamarin addins: 4194ffe4868321e4c3477bd56aed579bda4c6fbb

=== Operating System ===

Mac OS X 10.13.4
Darwin 17.5.0 Darwin Kernel Version 17.5.0
    Fri Apr 13 19:32:32 PDT 2018
    root:xnu-4570.51.2~1/RELEASE_X86_64 x86_64

=== Enabled user installed addins ===

Gist Ide Information 1.1.0
MFractor 3.05.12
MvvmCross Template pack 2.0.1
Redth's Addins 1.0.9
Internet of Things (IoT) development (Preview) 7.5
enhancement iOS

Most helpful comment

@baulig @mandel-macaque will this also happen on the AndroidClientHandler?

Yes, it will happen in all native handlers.

@baulig What is your definition of "very shortly"? Do we talk week(s) / month(s) / year(s)?
Same question as @Cheesebaron : will it be the same for AndroidClientHandler?

It's supposed to land by the end of March.

All 24 comments

Thanks for the report. I will take a look ASAP on a possible solution that will not change the API in a breaking mode and will push it.

We have not had a user with this need, so we never implemented it.

As a work around, is it possible for you to try the other handlers and see if they provide what you need?

The managed handler works, since it fires the ServicePointManager.ServerCertificateValidationCallback callback.

I haven't tried the CFNetworkHandler, but I would guess it behaves similarly to NSUrlSessionHandler.

@Cheesebaron ok, great to know. Ideally, you can use the managed handler (in order not to block you in your work) while I provide a fix.

@mandel-macaque I would assume that besides us, there's a ton of other people interested in this. managed handler is not an option for us, as it does not support TLS1.2 on iOS (or does it now?) and the server only talks TLS1.2. Patching framework classes is a pain in the a**, as you constantly need to track and re-sync updates. Best way would be that the NSUrlSessionHandler would trigger ServicePointManager.ServerCertificateValidationCallback and implement it's error handling accordingly.

I am also interested in this. IMHO Certificate Pinning is a security feature that is going to get more attention in the future along with Client Certificates.

We are also having this issue. We need TLS 1.2 support (and therefor NSUrlSessionHandler), but also want to implement certificate pinning. To achieve this we want to override the NSUrlSessionHandlerDelegate:DidReceiveChallenge.

We also tried ServicePointManager.ServerCertificateValidationCallback, but this callback isn't triggered when using any other handler than the Managed one. When using the native ModernHttpClient handlers, the ServicePointManager.ServerCertificateValidationCallback is being called, but unfortunately ModernHttpClient isn't maintained anymore. It would be great to have NSUrlSessionHandler also trigger ServicePointManager.ServerCertificateValidationCallback.

I just found this which might be useful until Xamarin has the necessary overloads available (I haven't tested it out yet) : https://github.com/tranb3r/secure-httpclient

With security increasing in all levels of IT (due to new laws like GDPR in Europe, etc.), this would be a great (almost neceassary) feature to have in both Xamarin.Android & Xamarin.iOS. @mandel-macaque Is there still work in progress on this issue?

@dpserge let me revisit it and will get back to you asap.

Please take a look at the linked PR. Provides the fix that should make the NSUrlSessionHandler work as the managed one.

Just added a detailed reply to that PR. Short summary:

You do not want to use ServicePointManager.ServerCertificateValidationCallback here, that's not going to work. There is a new API called HttpClientHandler.ServerCertificateCustomValidationCallback. We do not support that yet, but will very shortly.

@baulig @mandel-macaque will this also happen on the AndroidClientHandler?

@baulig What is your definition of "very shortly"? Do we talk week(s) / month(s) / year(s)?
Same question as @Cheesebaron : will it be the same for AndroidClientHandler?

@baulig @mandel-macaque will this also happen on the AndroidClientHandler?

Yes, it will happen in all native handlers.

@baulig What is your definition of "very shortly"? Do we talk week(s) / month(s) / year(s)?
Same question as @Cheesebaron : will it be the same for AndroidClientHandler?

It's supposed to land by the end of March.

Is this supported already? Can we still count on it being available by the end of March?

Supporting ServicePointManager.ServerCertificateValidationCallback will still not allow me to do client certificate handling. As mentioned above, for this I would need to override NSUrlSessionHandlerDelegate:DidReceiveChallenge and pass in this custom object to NSUrlSessionHandler and HttpClient. This is currently not possible with HttpClient (or am I overlooking something?). As a workaround, I don't use the HttpClient from our platform independent project but work directly with NSUrlSession in the iOS project.
As per this stackoverflow post https://stackoverflow.com/a/47666092/1468438 there seems to be a new constructor for NSUrlSessionHandler to pass in a custom NSUrlSession, however the link to the sourcefile does not show anything in this matter.
Will we get a possibility to do client certificate handling with HttpClient?

@baulig is there a new ETA on ServerCertificateValidationCallback support?

I would also be interested to have this change included to be able to use self signed certs. And just a remark, please don't call ServerCertificateValidationCallback like it is done in ModernHttpClient, because there the certificate parameter is only set to the root certificate of the incoming request, and this is always null for self signed certs.

@baulig is this still likely to be fixed shortly? What timeframe will it be available

This was supposed to be available by March. We are in May and still no update on when it would be available. When can we expect this feature?

I couldn't find any documentation on using this. Is is documented somewhere?
Also, can you elaborate on the whole ServerCertificateCustomValidationCallback support coming? Looking at the PR, it is not getting used, so I'm a little confused if something changed.

I see https://github.com/mono/mono/issues/17125 was closed but I don't see any updates regarding this being implemented. Is this released? Is there another issue we should track?

What about handle NSURLAuthenticationMethodClientCertificate ?

Pure NSUrlSession sample: link;

Current implementation allow define callback only for AuthenticationMethodServerTrust:
https://github.com/spouliot/xamarin-macios/blob/2074f76843982f386fc813a01dc0bb2fa98bd272/src/Foundation/NSUrlSessionHandler.cs#L724

For other ways, we need to define the custom implementation of NSUrlSessionDelegate, but we can't do it, because (actual behavior of this issue):

NSUrlSessionHandlerDelegate is private and contains a bunch of the necessary logic for NSUrlSessionHandler to even function.

NSUrlSession which uses the delegate is a private read-only member variable, so it cannot easily be set either.

The only way to implement this for NSUrlSessionHandler is to yank the code from this repository and modify it. Which isn't really an optimal solution.

Do you have any plans for resolving this issue?

Hi everyone, can we get a response from someone from the mono/Xamarin team providing confirmation regarding this? It looks like iOS still doesn't work with ServerCertificateCustomValidationCallback and I'm completely lost on why.

Was this page helpful?
0 / 5 - 0 ratings