how to store secret key in/for system extension

Hi. I have a private cryptographic key that I want to generate and store for use by the system extension only (a network extension NETransparentProxyProvider). The ideal properties I want is:

  • only accessible by extension
  • never leave extension
  • not be accessible by root user or other apps

Here is what I have tried so far (by/within the system extension):

  • app data container / local storage: this works, but is accessible by root user
  • app data shared container (storage): this works, but also acccessible by root user
  • system keyring: works, but also accesible by root user

System extension by itself does not seem to be able to store/load secrets in app protected keyring.

The host application however can store in app protected keyring.... So I though, let's use an app group (as access group) and have it like this shared between host and (system) extension... but nop... (system) extension cannot access the secret...

Ok... so than I thought:

  • manual low-level XPC calls.... Also that doesn't work, got something almost to work but seemed to require an entire 3rd (launchd/daemon) service.... way to complex for what I want... also seems that as a root user I can use debug tools to also access it

There is however the SendMessage/HandleMessage thing available for TransparentProxy.... that does work... but

(1) also doesn't seem the most secure (2) the docs clearly state cannot rely on that for this state as the system extension can be started while the host app is not active.... (e.g. at startup)

So that is not a solution either....

I went in so many different directions and rabbit holes in the last days.... this feels like a lot harder than it should be? How do other VPN/Proxy like solutions store secrets that are unique to an extension???? I am hoping there is something available here that I am simply missing despite all my effort... any guidance greatly appreciated...

Thanks so much for the post.

Have you considered to use the keychain https://developer.apple.com/documentation/security/keychain-services the intersection of System Extensions, the Keychain/Security framework (which is heavily user-session oriented), and the NetworkExtension framework.

I would personally recommend to look at Data Protection Keychain with Entitlement Enforcement. To guarantee that a private key never leaves the extension and cannot be extracted, you must generate the key.

When your extension reboots or reconnects, you query the keychain for the reference. Because you are using kSecUseDataProtectionKeychain = true and an access group. I would recommend you to look into that as well https://developer.apple.com/documentation/security/ksecusedataprotectionkeychain

You asked how other VPNs do this. Usually, I believe they do not generate the key inside the extension.

Since your requirement is to generate the key uniquely for the extension I recommend to looks at the By using Secure Enclave (kSecAttrTokenIDSecureEnclave) combined with the Data Protection Keychain and a Keychain Access Group. https://developer.apple.com/documentation/security/ksecattrtokenidsecureenclave

Hope this gives you an overview of what you need to implement without knowing your requirements in detail. I’m sure if you can provide those requirements more engineers will be happy to provide their opinion.

Good luck.

Albert
  Worldwide Developer Relations.

how to store secret key in/for system extension
 
 
Q