Fail to load system extension due to invalid code signature or missing entitlements

Context::

I try to build a Network Extension in Objective-C, and copy the app to my virtual machine ( SIP is disabled ). But when I run the app ( which activate that Network Extension inside, using OSSystemExtensionRequest ), it is killed immediately by SIGKILL. Meanwhile, if I run on the host machine ( SIP is enabled ), it gives an error :
Code Block bash
Request to load system extension has failed! Error (8): Invalid code signature or missing entitlements


I have a valid certificate for developing Network Extension ( imgur.com/ro4KQQK -- Sorry I cant paste the image here xD ).

Can someone give me a hint to fix this?


I encountered this issue but do not remember in which specific scenario. Reading my "don't" notes, this reminds me of this case:
  • Avoid creating a macOS App Development provisioning profile: you probably will end up with a system extension that can not be loaded because the signature can not be verified (and the parent app will tell you everything is fine).

Otherwise, you probably need to check that the entitlements are correctly set up as documented in this thread:

https://developer.apple.com/forums/thread/125508
Yes, you are right, I create a "App IDs" Identifier and grant it the permission for "Network Extension" and "System Extension". So what am I supposed to do?
This part looks OK.

Other things to check, just in case:
  • the Network Extension has the Network Extension permission.

  • the Network Extension app ID starts with the app ID of the embedding application.

  • the Team Prefix is the same for both app IDs.

  • the profiles for the Network Extension and the Application uses the same Developer ID Application certificate. In the case the certificate used to create the profile is not the same instance that is selected in Xcode, Xcode will warn you in the project settings.

Thanks for your reply, I have checked my application and:
  • Here is my example_extension.entitlements for the Network Extension and its bundleID is "com.example.installer.networkext":

Code Block xml
<?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.developer.networking.networkextension</key>
<array>
<string>app-proxy-provider</string>
</array>
<key>com.apple.security.application-groups</key>
<array>
<string>$(TeamIdentifierPrefix)com.example.installer.networkext</string>
</array>
</dict>
</plist>
  • Here is its Info.plist also:

Code Block xml
<?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>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>example_extension</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2020 HarDToBelieve. All rights reserved.</string>
<key>NSSystemExtensionUsageDescription</key>
<string></string>
<key>NetworkExtension</key>
<dict>
<key>NEMachServiceName</key>
<string>$(TeamIdentifierPrefix)com.example.installer.networkext</string>
<key>NEProviderClasses</key>
<dict>
<key>com.apple.networkextension.app-proxy</key>
<string>AppProxyProvider</string>
</dict>
</dict>
</dict>
</plist>

  • Here is my example.entitlements ( which is the entitlements of my app containing the network extension above ), and its bundleID is "com.example.installer":

Code Block xml
<?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.security.application-groups</key>
<array>
<string>$(TeamIdentifierPrefix)com.example.installer</string>
</array>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>app-proxy-provider</string>
</array>
</dict>
</plist>
  • I build the application successfully without any warning or error about provisioning profile or signing cert, so I think I have configured information on Apple server and my local machine correctly ( haven't I? )

I think I have configured information on Apple server and my local machine correctly

I recommend that you not rely on Xcode to catch problems like this but instead verify the output of your build process. You can dump the entitlements of a code item using:

Code Block
% codesign -d --entitlements :- /path/to/item


You can dump a provisioning profile using:

Code Block
% security cms -D -i /path/to/profile


Make sure to dump the embedded.provisionprofile that’s embedded within the bundle.

Check that:
  • Only your main executables contain entitlements; do not add entitlements to library code (like frameworks, dynamic libraries, bundles)

  • Any such entitlements are allowedlisted by the matching provisioning profile

Pasted in below is an example of me doing this for a EndpointSecurity sysex (sorry it’s not an NetworkExtension sysex but it’s what I have lying around at the moment).

Note If you work through this example you’ll see that, for both the app and the sysex, the get-task-allow entitlement (com.apple.security.get-task-allow) is not allowlisted by the profile. This is an unconstrained entitlement on macOS. Unconstrained entitlements don’t need to be allowlisted by a profile. Another example of this, particularly relevant for NE providers, is the App Sandbox entitlement (com.apple.security.app-sandbox).

Share and Enjoy

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



Code Block
% codesign -d --entitlements :- NullEndpointSecurity.app
<dict>
<key>com.apple.application-identifier</key>
<string>SKMME9E2Y8.com.example.apple-samplecode.NullEndpointSecurity</string>
<key>com.apple.developer.system-extension.install</key>
<true/>
<key>com.apple.developer.team-identifier</key>
<string>SKMME9E2Y8</string>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>
%
% security cms -D -i NullEndpointSecurity.app/Contents/embedded.provisionprofile
<dict>
<key>Entitlements</key>
<dict>
<key>com.apple.developer.system-extension.install</key>
<true/>
<key>com.apple.application-identifier</key>
<string>SKMME9E2Y8.com.example.apple-samplecode.NullEndpointSecurity</string>
<key>keychain-access-groups</key>
<array>
<string>SKMME9E2Y8.*</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>SKMME9E2Y8</string>
<key>com.apple.developer.networking.custom-protocol</key>
<true/>
</dict>
</dict>
</plist>
%
% codesign -d --entitlements :- NullEndpointSecurity.app/Contents/Library/SystemExtensions/com.example.apple-samplecode.NullEndpointSecurity.Extension.systemextension
<dict>
<key>com.apple.application-identifier</key>
<string>SKMME9E2Y8.com.example.apple-samplecode.NullEndpointSecurity.Extension</string>
<key>com.apple.developer.endpoint-security.client</key>
<true/>
<key>com.apple.developer.team-identifier</key>
<string>SKMME9E2Y8</string>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>
% security cms -D -i NullEndpointSecurity.app/Contents/Library/SystemExtensions/com.example.apple-samplecode.NullEndpointSecurity.Extension.systemextension/Contents/embedded.provisionprofile
<dict>
<key>Entitlements</key>
<dict>
<key>com.apple.application-identifier</key>
<string>SKMME9E2Y8.*</string>
<key>keychain-access-groups</key>
<array>
<string>SKMME9E2Y8.*</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>SKMME9E2Y8</string>
<key>com.apple.developer.endpoint-security.client</key>
<true/>
</dict>
</dict>
</plist>

@HarDToBelieve If you're using a Developer ID Application certificate, shouldn't there be a -systemextension suffix for the com.apple.developer.networking.networkextension values?

i.e. app-proxy-provider-systemextension
@eskimo:
Here is the entitlement of main app:
Code Block xml
Executable=/private/tmp/example_installer.app/Contents/MacOS/example_installer
<?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>W7S57TNBH5.com.example.installer</string>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>app-proxy-provider</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>W7S57TNBH5</string>
<key>com.apple.security.application-groups</key>
<array>
<string>W7S57TNBH5.com.example.installer</string>
</array>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>

main app's provision profile:
Code Block xml
...
<key>Entitlements</key>
<dict>
<key>com.apple.developer.system-extension.install</key>
<true/>
<key>com.apple.application-identifier</key>
<string>W7S57TNBH5.com.example.installer</string>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>app-proxy-provider</string>
<string>content-filter-provider</string>
<string>packet-tunnel-provider</string>
<string>dns-proxy</string>
<string>dns-settings</string>
</array>
<key>keychain-access-groups</key>
<array>
<string>W7S57TNBH5.*</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>W7S57TNBH5</string>
</dict>
...

Entitlement from its network extension
Code Block xml
Executable=/private/tmp/example_installer.app/Contents/Library/SystemExtensions/com.example.installer.networkext.systemextension/Contents/MacOS/com.example.installer.networkext
<?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>W7S57TNBH5.com.example.installer.networkext</string>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>app-proxy-provider</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>W7S57TNBH5</string>
<key>com.apple.security.application-groups</key>
<array>
<string>W7S57TNBH5.com.example.installer.networkext</string>
</array>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>

and its provision profile also
Code Block xml
...
<key>Entitlements</key>
<dict>
<key>com.apple.developer.system-extension.install</key>
<true/>
<key>com.apple.application-identifier</key>
<string>W7S57TNBH5.com.example.installer.networkext</string>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>app-proxy-provider</string>
<string>content-filter-provider</string>
<string>packet-tunnel-provider</string>
<string>dns-proxy</string>
<string>dns-settings</string>
</array>
<key>keychain-access-groups</key>
<array>
<string>W7S57TNBH5.*</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>W7S57TNBH5</string>
</dict>
...

I really dont see any problems here ...

@tartempion I tried to add that suffix but nothing changed after all
Fail to load system extension due to invalid code signature or missing entitlements
 
 
Q