Network system extension : invalid signature or entitlements

This forum has been very helpful so far. Lets do this again.


Okay, I have a Network system extension that successfully builds and runs on my offline dev machine with SIP disabled and a test provisioning profile that for whitelisted devices. NOTE this is a network system extension with a companion app (not an endpoint security extension that I've posted about previously)


So the next step is to get a distribution provisioning profile for the system extension so I can deploy over my beta testers that have SIP enabled. I generate these "Distribution Developer ID" provisoning profiles (provisioned for any device) for both the companion app and its embedded system extension. I transfer these over to my development machine, apply the provisioning profiles, build the app and test it to find that it works on this dev machine.


I then transfer the built components over to a machine with SIP enabled and run the app. I get the error Code Signature Invalid !


I've read through https://developer.apple.com/library/archive/technotes/tn2318/_index.html


However when I check the signature of the app and the embedded extension with `codesign -d --entitlements - [PATH]` (to app and extension) everything looks fine. Furthermore, checking the provisiong profile of both with `security cms -D -i [PROFILE_PATH]` everything seems fine.


What is going on ? why is this so ridiculously opaque and complicated ?

Answered by DTS Engineer in 409046022

I guess the first question is do you notarize your app prior to running it?

Right. I completely forgot about that requirement )-: If you’re using Developer ID signing with SIP, you must notarise.

Share and Enjoy

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

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

Hi Rob,


Which network extension entitlements are you requesting ?


They are different depending on whether you are signing with a Developer Id or not.


When signing with a developer id they take the suffix


-systemextension


So for a DNSProxyNE signed with a Developer Id the required entitlement is


dns-proxy-systemextension


Currently Xcode doesn't seem to know about this !

Thanks for the info. I'm using a content filter provider filtering on flows. Are you telling me that I require an additional entitlement of "content-filter-provider-systemextension" ?


BR

When signing with a Developer Id you need a different entitlement for each type of network extension


So instead of


content-filter-provider


you need


content-filter-provider-systemextension


See here for the official documentation


https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_networking_networkextension

Adding this entitlement I'm still experiencing issues. When attempting to start the extension, I get "The operation couldn’t be completed. (OSSystemExtensionErrorDomain error 8.)" Is there a way of getting more information from this ?

typedef NS_ERROR_ENUM(OSSystemExtensionErrorDomain, OSSystemExtensionErrorCode) {

OSSystemExtensionErrorUnknown = 1,

OSSystemExtensionErrorMissingEntitlement,

OSSystemExtensionErrorUnsupportedParentBundleLocation,

OSSystemExtensionErrorExtensionNotFound,

OSSystemExtensionErrorExtensionMissingIdentifier,

OSSystemExtensionErrorDuplicateExtensionIdentifer,

OSSystemExtensionErrorUnknownExtensionCategory,

OSSystemExtensionErrorCodeSignatureInvalid,

OSSystemExtensionErrorValidationFailed,

OSSystemExtensionErrorForbiddenBySystemPolicy,

OSSystemExtensionErrorRequestCanceled,

OSSystemExtensionErrorRequestSuperseded,

OSSystemExtensionErrorAuthorizationRequired,

} NS_ENUM_AVAILABLE_MAC(10.15);


so 8 would be


OSSystemExtensionErrorCodeSignatureInvalid


Did you update your provisioning profile when you changed the entitlements ?

I wonder if there's some entitlement requirements that are either conflicing or missing. For the sake of completeness, below is a redacted version of the profiles and entitlements I'm using for an app with an embedded content filter system extension.


NOTE this is a debug build.

App entitlements, output from `codesign -d --entitlements - [APP_PATH].app`

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

<dict>

<key>com.apple.application-identifier</key>

<string>[TEAM_ID].[APP_ID]</string>

<key>com.apple.developer.networking.networkextension</key>

<array>

<string>content-filter-provider-systemextension</string>

<string>packet-tunnel-provider-systemextension</string>

<string>app-proxy-provider-systemextension</string>

<string>dns-proxy-systemextension</string>

</array>

<key>com.apple.developer.system-extension.install</key>

<true/>

<key>com.apple.developer.team-identifier</key>

<string>[TEAM_ID]</string>

<key>com.apple.security.application-groups</key>

<array>

<string>[TEAM_ID].[APP_PREFIX]</string>

</array>

<key>com.apple.security.files.user-selected.read-only</key>

<true/>

<key>com.apple.security.get-task-allow</key>

<true/>

</dict>

</plist>


App provisioning profile, output from `security cms -D -i embedded.provisioningprofile`


<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

<dict>

<key>AppIDName</key>

<string>[NAME]</string>

<key>ApplicationIdentifierPrefix</key>

<array>

<string>[TEAM_ID]</string>

</array>

<key>CreationDate</key>

<date>[DATE]</date>

<key>Platform</key>

<array>

<string>OSX</string>

</array>

<key>IsXcodeManaged</key>

<false/>

<key>DeveloperCertificates</key>

<array>

<data>[DATA]</data>

</array>

<key>Entitlements</key>

<dict>


<key>com.apple.developer.system-extension.install</key>

<true/>


<key>com.apple.developer.networking.networkextension</key>

<array>

<string>packet-tunnel-provider-systemextension</string>

<string>app-proxy-provider-systemextension</string>

<string>content-filter-provider-systemextension</string>

<string>dns-proxy-systemextension</string>

</array>


<key>com.apple.application-identifier</key>

<string>[TEAM_ID].[APP_ID]</string>


<key>keychain-access-groups</key>

<array>

<string>[TEAM_ID].*</string>

</array>


<key>com.apple.developer.team-identifier</key>

<string>[TEAM_ID]</string>

</dict>

<key>ExpirationDate</key>

<date>[EXPIRE_DATE]</date>

<key>Name</key>

<string>[NAME]</string>

<key>ProvisionsAllDevices</key>

<true/>

<key>TeamIdentifier</key>

<array>

<string>[TEAM_ID]</string>

</array>

<key>TeamName</key>

<string>[TEAM_NAME]</string>

<key>TimeToLive</key>

<integer>6570</integer>

<key>UUID</key>

<string>[UUID]</string>

<key>Version</key>

<integer>1</integer>

</dict>

</plist>


Embedded system extension entitlements :

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

<dict>

<key>com.apple.application-identifier</key>

<string>[TEAM_ID].[APP_ID]</string>

<key>com.apple.developer.networking.networkextension</key>

<array>

<string>content-filter-provider-systemextension</string>

<string>packet-tunnel-provider-systemextension</string>

<string>app-proxy-provider-systemextension</string>

<string>dns-proxy-systemextension</string>

</array>

<key>com.apple.developer.team-identifier</key>

<string>[TEAM_ID]</string>

<key>com.apple.security.app-sandbox</key>

<false/>

<key>com.apple.security.application-groups</key>

<array>

<string>[TEAM_ID].[APP_PREFIX]</string>

</array>

<key>com.apple.security.get-task-allow</key>

<true/>

</dict>

</plist>


Embedded system extension profile:


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

<dict>

<key>AppIDName</key>

<string>[NAME]</string>

<key>ApplicationIdentifierPrefix</key>

<array>

<string>[TEAM_ID]</string>

</array>

<key>CreationDate</key>

<date>[DATE]</date>

<key>Platform</key>

<array>

<string>OSX</string>

</array>

<key>IsXcodeManaged</key>

<false/>

<key>DeveloperCertificates</key>

<array>

<data>[DATA]</data>

</array>


<key>Entitlements</key>

<dict>


<key>com.apple.developer.system-extension.install</key>

<true/>


<key>com.apple.developer.networking.networkextension</key>

<array>

<string>packet-tunnel-provider-systemextension</string>

<string>app-proxy-provider-systemextension</string>

<string>content-filter-provider-systemextension</string>

<string>dns-proxy-systemextension</string>

</array>


<key>com.apple.application-identifier</key>

<string>[TEAM_ID].[APP_ID]</string>


<key>keychain-access-groups</key>

<array>

<string>[TEAM_ID].*</string>

</array>


<key>com.apple.developer.team-identifier</key>

<string>[TEAM_ID]</string>

</dict>

<key>ExpirationDate</key>

<date>[DATE]</date>

<key>Name</key>

<string>[NAME]</string>

<key>ProvisionsAllDevices</key>

<true/>

<key>TeamIdentifier</key>

<array>

<string>[TEAM_ID]</string>

</array>

<key>TeamName</key>

<string>[TEAM_NAME]</string>

<key>TimeToLive</key>

<integer>6570</integer>

<key>UUID</key>

<string>[UUID]</string>

<key>Version</key>

<integer>1</integer>

</dict>

</plist>


I hope this helps to debug this issue.

Hi Rob,


The only differences I can see from the configuration that works for me is the


com.apple.security.get-task-allow


entitlements and that the extension has the


com.apple.security.app-sandbox


set to false.


What happens if you remove the


com.apple.security.get-task-allow


entitlements and set


com.apple.security.app-sandbox


to true ?

For both the system extension and its companion app ?


Why would you want a system extension to be sandboxed ? Seems like you'd only ever want these to be run as root

I guess it depends on what your system extension is doing.


For something like a DNSProxy NE probably the only thing you need to be able to do is open connections to a preferred DNS server which can be enabled be requesting the


com.apple.security.network.client


entitlement whilest remaining sand-boxed.

Thank you very much for all your help. I've tried explicitly setting get-task-allow > false and adding sandboxing. I get the same error.


I think this may be related to a problem I'm having while building. Building the project through xcode finishes successfully (in debug and release) but automatically adds the "get-task-allow" entitlement, which is required for the xcode debugger to hook into it.


Building a release configuration through the utility `xcodebuild` fails on the `codesign` task with "invalid or unsupported format for signiture".


Note that my dev machine is offline and I have the correct developer application certificate and key in the keychain.

Hi Rob,


You should be able to stop the


get-task-allow


entitlement from automatically being added by setting


Code Signing Inject Base Entitlements


in the Signing section of Build Settings to No for debug builds

This is useful to know, thank you. Unfortunately I'm still experiencing the same codesigning issue "The operation couldn’t be completed. (OSSystemExtensionErrorDomain error 8.)"


Note I've checked that indeed the get-task-allowed entitlement had disappeared. com.apple.security.app-sandbox was true.


Any other ideas ?


Best Regards.

Well, that’s interesting. Error 8 corresponds to

OSSystemExtensionErrorCodeSignatureInvalid
, which is returned if the system extension daemon receives a request from a client for which it can’t get an audit token from the XPC connection. This suggests that there’s something really broken with your code signature, but it doesn’t offer any hints as to what they might be.

Please do the following for both your app and the sysex embedded within the app:

  • Dump the code signature and entitlements:

    % codesign -d -vvv --entitlements :- /path/to/item

    .

  • Dump the embedded provisioning profile:

    % security cms -D -i /path/to/item/Contents/embedded.provisionprofile

    .

Then post the results here.

Note Please elide the certificates and device list (if any) from the provisioning profile. Also, feel free to redact anything that you want to keep private.

Share and Enjoy

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

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

I noticed that I had mixed responces with another question here (https://forums.developer.apple.com/thread/129794) which has now been answered. Continuing information relevant to this thread here.


I indeed got alot more useful information from sysextd. Below is a redated list of events:

- staging extension with identifier [APP_ID]

- Making activation decision for extension with teamID teamID("[TEAM_ID]"), identifier [APP_ID]

- Extension with teamID teamID([TEAM_ID]), identifier [APP_ID] is not in the list of allowed extensions.

- Activation decision for extension with teamID teamID("[TEAM_ID]"), identifier [APP_ID] is UserOption

- validating extension with identifier [APP_ID]

- MacOS error: 3

- Error checking with notarization daemon: 3

- bundle code signature is not valid - does not satisfy requirement: -67050 code failed to satisfy specified code requirement(s)

- extension failed to validate! uninstalling...


I dont see the extension appearing in Security & Privacy settings for me to allow it. Is there some other way of explicitly allowing this ?

I guess the first question is do you notarize your app prior to running it ?

Network system extension : invalid signature or entitlements
 
 
Q