Best practices for providing password / private key to System Extension Packet Tunnel Extension

I am in the process of re-writing an existing macOS packet tunnel provider VPN implementation that uses an Application Extension to instead use a System Extension. The current app implementation stores the credentials for the VPN configuration in the keychain and provides a persistent reference via the NEVPNProtocol.passwordReference property to the packet tunnel provider implementation in the Application Extension.

After some trial and error and reading various other posts, I believe that this approach is not possible when the packet tunnel provider is in a System Extension because it will not have access to a shared app group or keychain group. Given that, it seems like the only option is to pass these credentials in the NETunnelProviderProtocol.providerConfiguration property instead. My concern is that this may not be a secure place to put credentials, but the documentation does not specify how it is secured.

So my question is what is the best practice for providing credentials from the host app to a packet tunnel provider in a System Extension if the keychain is not a viable option?

Accepted Reply

the documentation does not specify how it is secured.

You’re correct that providerConfiguration isn’t really the place to be storing secrets. What you could do instead is:
  1. Use XPC to pass the credentials to your sysex.

  2. This would then store them in the keychain and return you a handle of some form.

  3. You could then pass that handle to the provider via providerConfiguration.

Share and Enjoy

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

Replies

the documentation does not specify how it is secured.

You’re correct that providerConfiguration isn’t really the place to be storing secrets. What you could do instead is:
  1. Use XPC to pass the credentials to your sysex.

  2. This would then store them in the keychain and return you a handle of some form.

  3. You could then pass that handle to the provider via providerConfiguration.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Ok, I see that the SimpleFirewall example does some XPC so I'll take a look at that. Thanks.
I now have XPC working between the host app and the system extension based on the mach service defined in the extension's Info.plist. I am successfully sending the credentials to the system extension to persist. However, my keychain function calls are failing in a couple of ways depending on how I try and store the value.

If I omit the kSecAttrAccessGroup, kSecUseDataProtectionKeychain, and kSecAttrAccessible keys from my query dictionary, the function fails with a value of 100001, and additionally in the console I see Sandbox: com.datto.Secure(26851) deny(1) file-write-create /Library/Keychains/System.keychain.sb-ed9f0ab6-SLwQik (it has some details associated; if those are pertinent I can add them).

If I include the keys I mention above I get error -25291, which according to the header file is No keychain is available. You may need to restart your computer.. I'm assuming restarting won't help with this issue.

Is there some entitlement that would allow this system extension to create/write to some keychain? The User Selected File, Downloads Folder, Pictures Folder, Music Folder, and Movies Folder file access entitlements don't seem relevant, but there aren't any others listed.
First up, check out this post.

That covers the data protection (iOS-style) keychain. The situation with the file-based keychain is less clear. Let’s start with a quick question: Are you planning to deploy this NE sysex via the Mac App Store? Or independently, using Developer ID signing?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
  • FYI: I have added a code that works for me in that thread.

Add a Comment
That post makes it sound like the sysex has no access to an iOS style or file based keychain keychain. Is that right? How are they intended to store credentials? The above strategy seems like it won't work if that is the case.

The current preferred plan for this app is to deploy via the Mac App Store.

That post makes it sound like the sysex has no access to an iOS style
or file based keychain keychain. Is that right?

Not quite. On the data protection keychain front, that’s definitely not going to happen )-: With regards the file-based keychain, that should be feasible but it won’t work ‘out of the box’.

The current preferred plan for this app is to deploy via the Mac App
Store.

OK. My advice is that you open a DTS tech support incident and we can talk about this there.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Ok, I have submitted the DTS.

Struggling with the same problem. So what is the non-'out of the box' file-based keychain solution? In my case the app would be deployed using Developer ID signing.