Cannot access shared keychain from NE System Extension

Hello,


We actually managed to get all of the code signing and entitlements with our Developer ID all aligned properly such that our NE system extension is installed, activated, and our packet tunnel provider is started and code is executed in the extension. So far so good!


However, the outstanding problem that is tripping us up at the finish line is that we just can’t seem get the NE provider to read from a shared keychain. The main app is able to write a password type key to the keychain no problem (we can see it in the macOS Keychain app), but our extension reports a -25291 or -25300 depending upon what we are trying when trying to read in the value. The exact same keychain read/write implementation works fine in dev builds without using System Extensions, so I’m pretty sure there must be some specific configuration I am missing when it comes to keychain sharing with System Extensions.


We've tried with App Sandbox on and off, and there is no difference.


According to this doc a shared Keychain Access Group Entitlement configured in the main app and NE System Extension should be all that is required. This is what we are doing and I believe is why everything is working fine in builds without the system extension.


We’ve tried all of the combinations of things I can think of, specifically mixing and matching various app group and keychain group identifiers, unfortunately all with the same result.


I beleive we are possibly in bug territory, but given how precise Keychain configuration needs to be, I wanted to check with the community to see if anyone had run into this same issue and found a solution before I file a bug.


Thanks!

Accepted Reply

The problem here is that your app and your sysex run as two different users (the currently logged in use and root, respectively). Keychain access groups allow you to share items between two programs running as the same user, not across users.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

The problem here is that your app and your sysex run as two different users (the currently logged in use and root, respectively). Keychain access groups allow you to share items between two programs running as the same user, not across users.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

@eskimo ah, well that would certainly explain it.
Does this mean there is no way to employ a shared keychain with System Extensions without making the application run as root, which doesn't seem like the right solution. Or is it possible to make the system extension run at the user level (I doubt it)?


If neither of those are possible, what is the advised way to securely storing exchange credentials derived by the host app to be used by the NE provider for authentiation? Perhaps using IPC from app to provider and having the provider write to keychain?

Perhaps using IPC from app to provider and having the provider write to keychain?

Yes.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

OK great, that makes sense.


And what about storing secrets in NETunnelProviderProtocol.providerConfiguration dictionary? Are those KVPs persisted to the root system keychain in a secure way? I found documentation indicating credentials pushed within a VPN MDM profile are stored in the keychain, but the security guarantees for provider configuration isn't documented one way or the other that I could find... I assume it is not safe, encrpyted, or recommended to store secrets there, but I wanted to validate with you.


Thanks agian!

And what about storing secrets in

NETunnelProviderProtocol.providerConfiguration
dictionary? Are those KVPs persisted to the root system keychain in a secure way?

I do not know )-: The documentation you found hasn’t been updated since the introduction of system extensions, so it’s not clear whether it’s applicable.

Unfortunately I don’t have time to research this in the context of DevForums. If you want a definitive answer, open a DTS tech support incident and I, or my colleague Matt, will help you out officially.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Bumping this old thread - I have the same scenario, I created a VPN + Certificate payload, installed it, and now I have a VPN conf which I can access to only from the containing app, but I need to access it from the system-extension. As I read above it's not possible, I send messages between the extension and the app, and it worked fine for the SecCertificate, which I sent as a Data to the extension (using SecCertificateCopyData() and sendProviderMessage functions).

The problem is that at the extension I need also the SecKey, and I couldn't find any way to pass it from the containing app to the extension. I even tried to pass it via IPC, but it crashed ( "This coder only encodes objects that adopt NSSecureCoding").

Is there any way to pass SecKey to the Extension, or to access it directly from there?

Bumping this old thread

It seems that Matt is helping you in the new thread that you opened for this issue.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"