Xamarin-macios: [WatchOS] ServicePointManager.ServerCertificateValidationCallback not working in WatchOS

Created on 23 Apr 2019  路  5Comments  路  Source: xamarin/xamarin-macios

Steps to Reproduce

I am trying to switch my app implementation to support TLS1.2 and connect to an endpoint protected by a self-signed certificate (it is local network, we care only about encrypting the traffic not ensuring that the server is really the expected one).

  1. Added ServicePointManager.ServerCertificateValidationCallback registration in WatchOS handler
  2. Connect to an endpoint protected by a self-signed certificate
  3. The ServicePointManager.ServerCertificateValidationCallback does not get called -> request failed

Expected Behavior

The handler is called and I am able to return 'true' and 'accept' the certificate

Actual Behavior

The handler is never called.

Environment

Microsoft Visual Studio Enterprise 2019
Version 16.0.2
VisualStudio.16.Release/16.0.2+28803.202
Microsoft .NET Framework
Version 4.7.03190

Installed Version: Enterprise

Visual C++ 2019   00435-60000-00000-AA861
Microsoft Visual C++ 2019

ADL Tools Service Provider   1.0
This package contains services used by Data Lake tools

Application Insights Tools for Visual Studio Package   9.0.20307.1
Application Insights Tools for Visual Studio

ASP.NET and Web Tools 2019   16.0.12311.10635
ASP.NET and Web Tools 2019

ASP.NET Web Frameworks and Tools 2019   16.0.12311.10635
For additional information, visit https://www.asp.net/

Azure App Service Tools v3.0.0   16.0.12311.10635
Azure App Service Tools v3.0.0

Azure Data Lake Node   1.0
This package contains the Data Lake integration nodes for Server Explorer.

Azure Data Lake Tools for Visual Studio   2.3.7000.2
Microsoft Azure Data Lake Tools for Visual Studio

Azure Functions and Web Jobs Tools   16.0.12311.10635
Azure Functions and Web Jobs Tools

Azure Stream Analytics Tools for Visual Studio   2.3.7000.2
Microsoft Azure Stream Analytics Tools for Visual Studio

C# Tools   3.0.0-beta4-19170-01+1deafee3682da88bf07d1c18521a99f47446cee8
C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Common Azure Tools   1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

Extensibility Message Bus   1.1.77 (master@24013d5)
Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

Fabric.DiagnosticEvents   1.0
Fabric Diagnostic Events

Microsoft Azure HDInsight Azure Node   2.3.7000.2
HDInsight Node under Azure Node

Microsoft Azure Hive Query Language Service   2.3.7000.2
Language service for Hive query

Microsoft Azure Service Fabric Tools for Visual Studio   2.5
Microsoft Azure Service Fabric Tools for Visual Studio

Microsoft Azure Stream Analytics Language Service   2.3.7000.2
Language service for Azure Stream Analytics

Microsoft Azure Stream Analytics Node   1.0
Azure Stream Analytics Node under Azure Node

Microsoft Azure Tools   2.9
Microsoft Azure Tools for Microsoft Visual Studio 0x10 - v2.9.0.0

Microsoft Continuous Delivery Tools for Visual Studio   0.4
Simplifying the configuration of Azure DevOps pipelines from within the Visual Studio IDE.

Microsoft JVM Debugger   1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

Microsoft Library Manager   1.0
Install client-side libraries easily to any web project

Microsoft MI-Based Debugger   1.0
Provides support for connecting Visual Studio to MI compatible debuggers

Microsoft Visual C++ Wizards   1.0
Microsoft Visual C++ Wizards

Microsoft Visual Studio Tools for Containers   1.1
Develop, run, validate your ASP.NET Core applications in the target environment. F5 your application directly into a container with debugging, or CTRL + F5 to edit & refresh your app without having to rebuild the container.

Microsoft Visual Studio VC Package   1.0
Microsoft Visual Studio VC Package

Mono Debugging for Visual Studio   16.0.300 (573eda3)
Support for debugging Mono processes with Visual Studio.

Node.js Tools   1.5.10301.2 Commit Hash:9c34eb81d73db6babeb71674feb1cb437dba9f2f
Adds support for developing and debugging Node.js apps in Visual Studio

NuGet Package Manager   5.0.0
NuGet Package Manager in Visual Studio. For more information about NuGet, visit http://docs.nuget.org/.

ProjectServicesPackage Extension   1.0
ProjectServicesPackage Visual Studio Extension Detailed Info

ResourcePackage Extension   1.0
ResourcePackage Visual Studio Extension Detailed Info

ResourcePackage Extension   1.0
ResourcePackage Visual Studio Extension Detailed Info

Snapshot Debugging Extension   1.0
Snapshot Debugging Visual Studio Extension Detailed Info

SQL Server Data Tools   16.0.61903.25110
Microsoft SQL Server Data Tools

ToolWindowHostedEditor   1.0
Hosting json editor into a tool window

TypeScript Tools   16.0.10306.2001
TypeScript Tools for Microsoft Visual Studio

Visual Basic Tools   3.0.0-beta4-19170-01+1deafee3682da88bf07d1c18521a99f47446cee8
Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Visual F# Tools 10.4 for F# 4.6   16.0.0.0.  Commit Hash: 809f41207b74a1356208f11b8fa3a15233734050.
Microsoft Visual F# Tools 10.4 for F# 4.6

Visual Studio Code Debug Adapter Host Package   1.0
Interop layer for hosting Visual Studio Code debug adapters in Visual Studio

Visual Studio Tools for Containers   1.0
Visual Studio Tools for Containers

Visual Studio Tools for Kubernetes   1.0
Visual Studio Tools for Kubernetes

VisualStudio.Mac   1.0
Mac Extension for Visual Studio

Xamarin   16.0.0.515 (d16-0@a3502d929)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin Designer   4.17.4.418 (remotes/origin/d16-0@3d086e814)
Visual Studio extension to enable Xamarin Designer tools in Visual Studio.

Xamarin Templates   16.1.47 (31f664d)
Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.

Xamarin.Android SDK   9.2.0.5 (HEAD/292d27fa)
Xamarin.Android Reference Assemblies and MSBuild support.
    Mono: mono/mono/2018-08-rc@5ad371dab1b
    Java.Interop: xamarin/java.interop/d16-0@c987483
    LibZipSharp: grendello/LibZipSharp/master@44de300
    LibZip: nih-at/libzip/rel-1-5-1@b95cf3f
    MXE: xamarin/mxe/xamarin@b9cbb535
    ProGuard: xamarin/proguard/master@905836d
    SQLite: xamarin/sqlite/3.26.0@325e91a
    Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-0@0a7edd6


Xamarin.iOS and Xamarin.Mac SDK   12.8.0.0 (0aa8452)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

Build Logs

Example Project (If Possible)

bug iOS

Most helpful comment

Hello @mandel-macaque

Thanks a lot for your detailed explanations.

Routing the requests through the phone and using the WatchConnectivity is a no-go for us since the live transfer happens only when both phone app and watch app are active. Our watch app was designed to work standalone, to allow the user to perform other tasks (he's on a ladder) having both hands free.
The requests must be sent ASAP and not when the system decides.

We'll try to redesign our system to support encrypting the transferred payloads over http instead of using a 'real' https connection.

Thank you!

All 5 comments

I just saw there's also no chance to supply my own (INSUrlSessionDelegate)selfSignedDelegate to the NSUrlSessionHandler (only the configuration) and somehow "validate" the certificate there :(

Looking at the unittests in this repo it seems that the ServerCertificateValidationCallback is indeed not supported on the watchos platform :(

Hm, I am left with only two options, as watchos does not basically support self-signed certificates :

  1. Ditch the watch app and use our self signed certificate (valid for 10yrs) for all the other platforms.
  2. Buy a proper certificate, which expires after 2 years causing the offline desktop application hosting my server to stop working with the app (there is no easy way to 'refresh' those certificates on machines which are almost never going online)

@ThumbGen the main issue we have is that the watch does not allow custom socket connections, and therefore, we do have issues implementing what you need. You could perform the requests from the phone, which gives you all the capabilities (This is a limitation imposed by Apple, nothing that we can change in our side).

Having said that, we do not have ATM (since if is work in progress and we are waiting for the changes in corefx as you can see on https://github.com/xamarin/xamarin-macios/pull/5733) support for self signed certificates in the NSUrlSessionHandler. The code in the repo is under an MIT license and you do have an implementation in the PR I proposed.

If the MIT license is not a problem, you could grab the changes in my PR, which will unblock you and you can continue development. The reasons why we did not accept my PR are:

  1. It will bring the security dlls from mono making the app larger. Something that from a SDK point of view is not good, but might not be a problem on your side.
  2. It does not match the new corefx ideas.

Having that handler, you can create a new instance of the HttpClient by something like:

var client = new HttpClient (new MyNSUrlSessionHandler ()); // grabbing the code from https://github.com/xamarin/xamarin-macios/pull/5733

and use that client to perform all the requests _from the iPhone app._ You can use the Watch Connectivity (sample can be found here: https://developer.xamarin.com/samples/monotouch/watchOS/WatchConnectivity/) to do it and remove any limitations you have atm.

I do recommend to watch issue https://github.com/xamarin/xamarin-macios/issues/4170 which I will be working on as soon as upstream let us know the new way the API will deal with the custom certificates.

Thanks @mandel-macaque !

So I believe we can close this as a duplicate of https://github.com/xamarin/xamarin-macios/issues/4170

Please reopen if there is some subtly that makes this issue unique that I've missed. Thank you for a very detailed report.

Hello @mandel-macaque

Thanks a lot for your detailed explanations.

Routing the requests through the phone and using the WatchConnectivity is a no-go for us since the live transfer happens only when both phone app and watch app are active. Our watch app was designed to work standalone, to allow the user to perform other tasks (he's on a ladder) having both hands free.
The requests must be sent ASAP and not when the system decides.

We'll try to redesign our system to support encrypting the transferred payloads over http instead of using a 'real' https connection.

Thank you!

Was this page helpful?
0 / 5 - 0 ratings