[appletls]: Use SecIdentityCreate() to avoid using the Mac keychain. (#4671)
authorMartin Baulig <mabaul@microsoft.com>
Tue, 11 Apr 2017 21:43:51 +0000 (17:43 -0400)
committerGitHub <noreply@github.com>
Tue, 11 Apr 2017 21:43:51 +0000 (17:43 -0400)
commit1eb27c1df8ed29d84ca935496ffd6c230447895a
tree66d55c747ae8e935f1ed1b0142a7554c755ea80e
parent1c987f5bd0590c5ad93f4674b59858990c291693
[appletls]: Use SecIdentityCreate() to avoid using the Mac keychain. (#4671)

* [appletls]: Use SecIdentityCreate() to avoid using the Mac keychain when we have a private key.

Reading Certificates from the Mac Keychain
==========================================

Reading the private key from the keychain is a new feature introduced with
AppleTls on XamMac and iOS. On Desktop Mono, this new feature has several
known issues and it also did not received any testing yet. We go back to the old
way of doing things, which is to explicitly provide an X509Certificate2 with a
private key.

Keychain Dialog Popups
======================

When using Xamarin.Mac or Xamarin.iOS, we try to search the keychain
for the certificate and private key.

On Xamarin.iOS, this is easy because each app has its own keychain.

On Xamarin.Mac, the .app package needs to be trusted via code-sign
to get permission to access the user's keychain. [FIXME: I still have to
research how to actually do that.] Without this, you will get a popup
message each time, asking you whether you want to allow the app to access
the keychain, but you can make these go away by selecting "Trust always".

On Desktop Mono, this is problematic because selecting "Trust always"
give the 'mono' binary (and thus everything you'll ever run with Mono)
permission to retrieve the private key from the keychain.

This code would also trigger constant keychain popup messages,
which could only be suppressed by granting full trust. It also makes it
impossible to run Mono in headless mode.

SecIdentityCreate
=================

To avoid these problems, we are currently using an undocumented API
called SecIdentityRef() to avoid using the Mac keychain whenever a
X509Certificate2 with a private key is used.

On iOS and XamMac, you can still provide the X509Certificate without
a private key - in this case, a keychain search will be performed (and you
may get a popup message on XamMac).
mcs/class/System/Mono.AppleTls/AppleCertificateHelper.cs
mcs/class/System/Mono.AppleTls/Certificate.cs
mcs/class/System/Mono.AppleTls/Enums.cs
mcs/class/System/Mono.AppleTls/ImportExport.cs
mcs/class/System/Mono.AppleTls/Items.cs
mcs/class/System/System.Net/MacProxy.cs