packet-tunnel to packet-tunnel-systemextension conversion

Hi,

I have an app that works fine with packet-tunnel-provider network extension. But I am not able to distribute it with developer ID signing, so I followed the instructions below

https://developer.apple.com/forums/thread/125508?answerId=402187022#402187022

I was able to sign/distribute/notarize my app, but the packet tunnel provider piece of it fails to start because it says "signature check failed: code failed to satisfy specified code requirement(s)" / "Validation of the extension failed".

I am attaching a screenshot here. Note that I did not really make any code changes, I just followed the steps by eskimo verbatim - so the question is should I call stuff like "OSSystemExtensionRequest.activationRequest(" from the mainApp or the network extension old style will continue to work as is? I just want to be able to developer sign a simple packet tunnel app thats about it. But I guess the code signing errors are not related to whether I call activationRequest or not

codesign -dv NextensioAppMac.app Executable=/Users/gopakumarchoorakkotedakkunni/NXT/NextensioAppMac.app/Contents/MacOS/NextensioAppMac Identifier=io.nextensio.agent1 Format=app bundle with Mach-O thin (arm64) CodeDirectory v=20500 size=959 flags=0x10000(runtime) hashes=19+7 location=embedded Signature size=9009 Timestamp=May 26, 2021 at 3:47:08 PM Info.plist entries=25 TeamIdentifier=3S6YLTX9PM Runtime Version=11.3.0 Sealed Resources version=2 rules=13 files=13 Internal requirements count=1 size=212

cat NextensioAppMac.app/Contents/Info.plist <?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>BuildMachineOSBuild</key> <string>20E241</string> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleExecutable</key> <string>NextensioAppMac</string> <key>CFBundleIconFile</key> <string>AppIcon</string> <key>CFBundleIconName</key> <string>AppIcon</string> <key>CFBundleIdentifier</key> <string>io.nextensio.agent1</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>Nextensio</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>0.1.4</string> <key>CFBundleSupportedPlatforms</key> <array> <string>MacOSX</string> </array> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLName</key> <string>io.nextensio.agent1</string> </dict> </array> <key>CFBundleVersion</key> <string>1</string> <key>DTCompiler</key> <string>com.apple.compilers.llvm.clang.1_0</string> <key>DTPlatformBuild</key> <string>12E262</string> <key>DTPlatformName</key> <string>macosx</string> <key>DTPlatformVersion</key> <string>11.3</string> <key>DTSDKBuild</key> <string>20E214</string> <key>DTSDKName</key> <string>macosx11.3</string> <key>DTXcode</key> <string>1250</string> <key>DTXcodeBuild</key> <string>12E262</string> <key>LSApplicationCategoryType</key> <string>public.app-category.utilities</string> <key>LSMinimumSystemVersion</key> <string>11.1</string> <key>NSMainStoryboardFile</key> <string>Main</string> <key>NSPrincipalClass</key> <string>NSApplication</string> </dict> </plist>
cat NextensioAppMac.app/Contents/PlugIns/NextensioPacketTunnelMac.appex/Contents/Info.plist <?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>BuildMachineOSBuild</key> <string>20E241</string> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleDisplayName</key> <string>NextensioPacketTunnel</string> <key>CFBundleExecutable</key> <string>NextensioPacketTunnelMac</string> <key>CFBundleIdentifier</key> <string>io.nextensio.agent1.tunnel</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>NextensioPacketTunnelMac</string> <key>CFBundlePackageType</key> <string>XPC!</string> <key>CFBundleShortVersionString</key> <string>0.1.4</string> <key>CFBundleSupportedPlatforms</key> <array> <string>MacOSX</string> </array> <key>CFBundleVersion</key> <string>1</string> <key>DTCompiler</key> <string>com.apple.compilers.llvm.clang.1_0</string> <key>DTPlatformBuild</key> <string>12E262</string> <key>DTPlatformName</key> <string>macosx</string> <key>DTPlatformVersion</key> <string>11.3</string> <key>DTSDKBuild</key> <string>20E214</string> <key>DTSDKName</key> <string>macosx11.3</string> <key>DTXcode</key> <string>1250</string> <key>DTXcodeBuild</key> <string>12E262</string> <key>LSMinimumSystemVersion</key> <string>11.1</string> <key>NSExtension</key> <dict> <key>NSExtensionPointIdentifier</key> <string>com.apple.networkextension.packet-tunnel</string> <key>NSExtensionPrincipalClass</key> <string>NextensioPacketTunnelMac.PacketTunnelProvider</string> </dict> </dict> </plist>

so the question is should I call stuff like "OSSystemExtensionRequest.activationRequest(" from the mainApp

Yes, you would still call this from the container app no matter if you are testing with a Development signed build or with a Developer ID / Notarized signed build.

Based on your screen shot it looks like you have the following:

# Container app
io.nextensio.agent1

# Network System Extension
io.nextensio.agent1.tunnel

And then in your Info.plist's from the comments I see:

cat NextensioAppMac.app/Contents/PlugIns/NextensioPacketTunnelMac.appex

Can you display the entitlements for your Container app (io.nextensio.agent1). It sounded like you were wanting to run a Network System Extension (OSSystemExtensionRequest) but it looks like you are using a Network App Extension, which would explain the code signature verification failure.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Sorry about the delay responding here. I thought I would post in detail in case it helps someone else.

  1. The first mistake I made is in assuming that converting a packet tunnel to system extension is just a matter of updating the entitlements to say that I am using system extension, but I figured out that its incorrect - I needed to delete my old network extension target and create a NEW target in xcode selecting the type as system-extension. So I guess that makes xcode to package the application differently - the system extension app has the Library/SystemExtension folder with my system extension code inside it etc.. which will happen only if we create a target specifically marked as system-extension in xcode.

  2. Then in developer.apple.com for the app IDs, the UI APP ID has BOTH network and system extension checked, the packet-tunnel app ID has Network extension checked but NOT system extension.

  3. Then of course I had to mention it in my entitlements. I am listing it here for anyone's future reference

Packet tunnel entitlement:

UI App entitlement:

  1. And then I built the image, and uploaded to apple for "Developer ID" signing and it was signed all well and fine and then I exported the signed app as a mac app. Now this is where it was frustrating as hell - the app would work fine on my laptop, I can open it and it will ask permission to install system extension etc.., but it would NOT work on anyone else's laptop - it would not ask for permission to install system extension, radio silence. And in the system logs there is really nothing legible that says what the problem is. I spent at least a couple of days complete waste of time chasing this - and finally figured that the developer ID signed app has to be moved to the Applications folder and only then the system extension would work. And how did I find that out ? There was this slide deck - https://objectivebythesea.com/v3/talks/OBTS_v3_sKnight.pdf - where somewhere deep inside it there was an allusion to the need to move the app to Applications folder, and thanks to this kind soul who made the pdf, my pain ended in two days. These are the things which apple has been terrible in documenting. Does no one at apple run through the sequence end to end and see what are the steps required and document it ???

At any rate, after the above, it all works fine - it asks for permission to install system extension and I allow it and it creates a seperate process with my system extension code - that is a thing to note when writing system extensions, unlike the previous packet tunnel mechanism, the system extension code runs as a seperate process that keeps running for ever as long as the system extension is installed, ie it keeps running even after your app is terminated. And when you relaunch the app and again activate system extension, the process will still be the same, its not restarted - ie make sure to cleanup and have the process start from a clean state without actually restarting the process

Thank you for posting the resolution of your issue. I am glad you were able to get it resolved.

Regarding:

and finally figured that the developer ID signed app has to be moved to the Applications folder and only then the system extension would work. And how did I find that out ? There was this slide deck - https://objectivebythesea.com/v3/talks/OBTS_v3_sKnight.pdf - where somewhere deep inside it there was an allusion to the need to move the app to Applications folder, and thanks to this kind soul who made the pdf, my pain ended in two days. These are the things which apple has been terrible in documenting. Does no one at apple run through the sequence end to end and see what are the steps required and document it ???

This is touched on briefly in the Debugging and Testing System Extensions article under the Enable Activation from Any Directory section, "You must place all system extensions in the Contents/Library/SystemExtensions directory of your app bundle, and the app itself must be installed in one of the system’s Applications directories. " Now, having said that, if you feel the documentation could be improved, please open an Enhancement Request here. There is always room for our documentation to be improved.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Why not have this error printed in the logs as to why the system extension is not loading - something like "binary needs to be in Application folder" or some such ?

I don’t think there’d be any resistance to doing that; please write it up in an enhancement request and then post your bug number, just for the record.

Share and Enjoy

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

packet-tunnel to packet-tunnel-systemextension conversion
 
 
Q