Post

Replies

Boosts

Views

Activity

Reply to Cannot activate Network Extension signed with a Developer ID certificate
In case anyone has a similar issue, here's a script condensing my learnings from @eskimo's posts. Take it with a pinch of salt! # Assumes all variables are populated already, with app and extension built using a development certificate. # Extract the entitlements from the builds. They differ from the .entitlement files in the project! codesign -d --entitlements :- "${app_bundle}" > app.entitlements codesign -d --entitlements :- "${extension_bundle}" > sext.entitlements # We only use one, specify any others as needed sed -i '' 's/'$networkEntitlement'/'$networkEntitlement'-systemextension/g' app.entitlements sed -i '' 's/'$networkEntitlement'/'$networkEntitlement'-systemextension/g' sext.entitlements # Copy the system extension into the app bundle mkdir -p ${app_bundle}/Contents/Library/SystemExtensions/ ditto ${extension_bundle} ${app_bundle}/Contents/Library/SystemExtensions/${extension_bundle} # Replace the embedded provision profiles ditto ${app_provision_profile_path} "${app_bundle}/Contents/embedded.provisionprofile" ditto ${extension_provision_profile_path} "${app_bundle}/Contents/Library/SystemExtensions/${extension_bundle}/Contents/embedded.provisionprofile" # Sign the System extension bundle first, then the binary with entitlements. Both require hardened runtime codesign -f --timestamp --options runtime --sign "${certificate_name}" ${app_bundle}/Contents/Library/SystemExtensions/${extension_bundle} codesign -f --timestamp --options runtime --entitlements "sext.entitlements" --sign "${certificate_name}" "${app_bundle}/Contents/Library/SystemExtensions/${extension_bundle}/Contents/MacOS/${extension_id}" # Sign the App bundle first, then the binary with entitlements. Both require hardened runtime codesign -f --timestamp --options runtime --sign "${certificate_name}" ${app_bundle} codesign -f --timestamp --options runtime --entitlements "app.entitlements" --sign "${certificate_name}" "${app_bundle}/Contents/MacOS/${app_name}" # We cannot send the bundle directly to notarytool (it is a dir), zip it first. ditto -ck --rsrc --keepParent --sequesterRsrc "${app_bundle}" app.zip xcrun notarytool submit app.zip --wait --apple-id=${NOTARIZATION_EMAIL} --password="${NOTARIZATION_PASSWORD}" --team-id="$TEAM_ID" # Staple assuming notarization was Accepted. Even if it fails, notarytool returns 0, so stapler will fail then. xcrun stapler staple "${app_bundle}" My problem was in the runtime flag not being included in the bundle, only the binary. That's (as far as I could tell) what would break my system's connection. Thanks again for your help @eskimo
Jan ’24
Reply to Cannot activate Network Extension signed with a Developer ID certificate
Thanks for your reply @eskimo . I did update the provisioning profile. I think I'm missing the bigger picture here. In my older post I was trying to make this run from a daemon, and you recommended that I bundle that daemon as a separate app. So I followed Signing a daemon with a restricted entitlement, and it complicated things a lot, but I made it work. I encountered this same issue back then, but decided to simplify the problem and re-write the interaction with the Network Extension as a CLI that could be started from that daemon more easily without any entitlements in the daemon. It's a simple CLI, only activates/deactivates starts/stops the network extension. During development it was fine, only when signing for distribution it would fail. If I understand correctly, the problem is that the CLI doesn't have a GUI? Could I then have a very short lived window (or perhaps just something in the dock) that applies the same logic as the CLI and exits? That'd be strange, but besides it being annoying to users, why would that not work? Thanks!
Jan ’24
Reply to Taskgated-helper ignores embedded.provisionprofile
I packaged the Daemon as a separate app bundle within and it works during development. However, once I sign it with my developer ID certificate for distribution the network extension will not activate, getting stuck the activation request and completely killing any internet connectivity until I restart. The only thing that I see is different is when I call systemextensionsctl list I get something like: 1 extension(s) --- com.apple.system_extension.network_extension enabled active teamID bundleID (version) name [state] <TEAM_ID> com.company.networkExt (1.0/240116145656) - [validating by category] * * <TEAM_ID> com.company.networkExt (1.0/240115061310) ProxyExtension [activated enabled] Where the one specifying [validating by category] is the one that I'm trying to activate signed with the developer ID cert. The one that is [activated enabled] got there from a dev build. The app was built and notarized and shows to be valid by any codesign -dv --verify --strict and spctl commands that I've found. The system extension is valid according to codesign, but spctl --verbose=4 --assess does report: com.company.vpn.networkExt.systemextension: rejected (the code is valid but does not seem to be an app)
Jan ’24
Reply to Taskgated-helper ignores embedded.provisionprofile
Thanks for your reply, the project structure looks like this: └── Contents ├── Frameworks │   └── ... ├── Info.plist ├── Library │   ├── LaunchServices │   └── SystemExtensions ├── MacOS │   ├── ApplicationClient │   └── ApplicationDaemon ├── PkgInfo ├── PlugIns │   └── ... ├── Resources │   └── LICENSE.txt ├── _CodeSignature │   └── CodeResources └── embedded.provisionprofile ApplicationClient is the client app that launches when double clicking the app . This one runs fine when double clicking the app icon or when running from terminal. It's set in the Info.plist file as the bundle executable, which is what I suspected would cause the issue: <key>CFBundleExecutable</key> <string>Private Internet Access</string> ApplicationDaemon is set up to run as a launchctl daemon or can be run from the terminal. But, after adding the system extension entitlements, this binary won't run either from the terminal or as daemon, with an error from taskgated-helper (as seen in console.app) saying that it cannot find the matching provision profile, even though the bundle ID is reported as the same as the ApplicationClient. The strange part for me is that if the profile is installed manually (which I understand is an outdated way of doing things and we should use embedded.provisionprofile) it does get picked up immediately and taskgated-helper won't block it anymore. Thanks for the help!
Jan ’24