Can I Exporting a Developer ID PacketTunnelProvider Plugin?

I can develop a PacketTunnelProvider on Mac with xcode. I work with my self codesign.

But when I sign it with Developer ID after read https://developer.apple.com/forums/thread/737894 , it still fail when I turn on the vpn .

Answered by DTS Engineer in 857915022

OK, that’s definitely a sysex. Thanks for confirming.

Given that, you should be able to export it for direct distribution with Developer ID signing. You’ll have to carefully work through the steps in Exporting a Developer ID Network Extension. Make sure that:

  • The code is signed with the Developer ID variants of the com.apple.developer.networking.networkextension entitlement values.
  • That entitlement claim is authorised by a Developer ID provisioning profile.

Make sure to check both the container app and the embedded sysex.

I also recommend that you add a ‘first light’ log point to your sysex so you can see whether it’s code runs at all. See Debugging a Network Extension Provider for more about that.

And if you don’t get that log point, make sure to check for crash reports.

Share and Enjoy

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

In console , I found the following logs:

default 19:18:04.714864+0800 UCPacketTunnelMac Signature check failed: code failed to satisfy specified code requirement(s)

Is in your packet tunnel provider packaged as a system extension? Or an app extension?

This matters because, as explained in TN3134 Network Extension provider deployment, we only support system extension packaging when deploying directly with Developer ID.

Share and Enjoy

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

This is my extension's entitlements which dump by codesign

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.application-identifier</key> <string>xxxxxxx</string> <key>com.apple.developer.networking.networkextension</key> <array> <string>packet-tunnel-provider-systemextension</string> </array> <key>com.apple.developer.team-identifier</key> <string>xxxxx</string> <key>com.apple.security.app-sandbox</key> <true /> <key>com.apple.security.network.client</key> <true /> <key>com.apple.security.network.server</key> <true /> </dict> </plist>

It’s better to reply as a reply, rather than in the comments; see Quinn’s Top Ten DevForums Tips for this and other titbits.

I already sign with the system extension

OK. But I’m not asking how you signed it, I’m asking how you packaged it. Is the extension an app extension (.appex) or a system extension (.systemextension)?

If you’ve packaged it as an appex, your only valid distribution channel is the Mac App Store. You won’t be able to directly distribute it using Developer ID signing.

Share and Enjoy

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

My plugin packaged the following path:

./UCTunnel.app/Contents/Library/SystemExtensions/org.uc.UCTunnel.UCPacketTunnel.systemextension/Contents/MacOS/org.uc.UCTunnel.UCPacketTunnel

And I use the System Network Extension XCode Template with a main.m and PacketTunnelProvider.m


int main(int argc, char *argv[])

{

    @autoreleasepool {

        [NEProvider startSystemExtensionMode];

    }

    

    dispatch_main();

}



@implementation PacketTunnelProvider



- (void)startTunnelWithOptions:(NSDictionary *)options completionHandler:(void (^)(NSError *))completionHandler {

    // Add code here to start the process of connecting the tunnel.

    

    completionHandler(nil);

}



- (void)stopTunnelWithReason:(NEProviderStopReason)reason completionHandler:(void (^)(void))completionHandler {

    // Add code here to start the process of stopping the tunnel.

    completionHandler();

}



- (void)handleAppMessage:(NSData *)messageData completionHandler:(void (^)(NSData *))completionHandler {

    // Add code here to handle the message.

}



- (void)sleepWithCompletionHandler:(void (^)(void))completionHandler {

    // Add code here to get ready to sleep.

    completionHandler();

}



- (void)wake {

    // Add code here to wake up.

}



@end

OK, that’s definitely a sysex. Thanks for confirming.

Given that, you should be able to export it for direct distribution with Developer ID signing. You’ll have to carefully work through the steps in Exporting a Developer ID Network Extension. Make sure that:

  • The code is signed with the Developer ID variants of the com.apple.developer.networking.networkextension entitlement values.
  • That entitlement claim is authorised by a Developer ID provisioning profile.

Make sure to check both the container app and the embedded sysex.

I also recommend that you add a ‘first light’ log point to your sysex so you can see whether it’s code runs at all. See Debugging a Network Extension Provider for more about that.

And if you don’t get that log point, make sure to check for crash reports.

Share and Enjoy

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

Thanks for your patience.

I add some log at main and -(void)load function. However, the no logs and crash reports appear in console.app.

I also make a DTS request with Case-ID: 15847816 , and send the demo project and app.

Would you be able to review the attachment and offer additional support?

send the demo project and app

I took a look at that today and I’m confused by your starting point. My general advice when building Mac software is to do your day-to-day development using Apple Development signing. Then, once you have things working, you can export your app using the signing appropriate for your distribution channel (Apple Distribution for the Mac App Store, Developer ID for direct distribution). See The Care and Feeding of Developer ID for more about this.

If you do that then you only need to worry about the -systemextension stuff at the final step, when you export your product for distribution. And when you stick with Apple Development signing you can rely on Xcode’s automatic code signing to do the right thing.

However, you seem to be trying to use Developer ID signing for day-to-day development. This is a mistake, and it’s causing you grief here.

So, for example, I opened your project today to check how you’re app is using System Extensions framework to activate its system extension. However, I found no references to OSSystemExtensionManager at all.

This suggests you’re trying to deal with Developer ID signing before you get the basic function of your product working. That’s a mistake. You need to get Apple Development working first, and then deal with Developer ID at the end.

On the Apple Development front, I’m going to reiterate that Debugging a Network Extension Provider has the info you need to get your system extension working. Specifically:

  • It explains how to use the modern system log APIs for your ‘first light’ log point. The code you sent me uses NSLog. That’s a mistake, and I’ve recently updated Your Friend the System Log to explain why.
  • It explains how to set up your project to copy the container app to the Applications folder, allowing you to develop on a Mac with SIP enabled.

Once you have Apple Development signing worked out, please retry the Developer ID export using the instructions in steps in Exporting a Developer ID Network Extension. I expect that’ll just work. If not, feel free to send me the updated version of your test project and the script you’re using to export your Xcode archive (.xcarchive) as a Developer ID signed app.

Share and Enjoy

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

I used Apple Development sign to another demo which is success work with appex plugin.

It seems that I should use OSSystemExtensionManager to start a System Extension with Developer ID ?

Could you share any other reference examples for OSSystemExtensionManager?

I found the following exampe: https://developer.apple.com/documentation/NetworkExtension/filtering-network-traffic

It seems that, I should request the System Extension Redistributable Capability with my Develope Team ?

It seems that I should use OSSystemExtensionManager to start a System Extension … ?

Yes.

Technically, this activates the system extension, which may or may not start it depending on the type of sysex.

And, to be clear, you need this when you use system extension packaging, regardless of how you sign your extension. You can sign a sysex using:

  • Apple Developerment, for day-to-day development
  • Apple Developerment, for submission to the Mac App Store
  • Developer ID Application, for direct distribution

In all cases you need to use OSSystemExtensionManager. That’s correlated with the packaging, not with any specific signing identity.

Could you share any other reference examples for OSSystemExtensionManager?

Sure. The Filtering Network Traffic sample code shows how to use OSSystemExtensionManager to activate an NE sysex. It’s a content filter, not a packet tunnel, but the sysex side of this is the same.

Also, if you’re familiar with appex packaging you’ll find a few differences once you switch to a sysex. None of these are super difficult, but they can be confusing. I’ve used your thread as excuse to collect my comments about this in one place: Network Extension Provider Packaging

It seems that, I should request the System Extension Redistributable Capability … ?

No.

That capability is intended to be used by DriverKit sysexen, where one developer might want to create a DEXT for another developer to distribute in their container app. In your case you’re creating both the sysex and the container app, and you should sign both with your code-signing identity.

Share and Enjoy

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

Can I Exporting a Developer ID PacketTunnelProvider Plugin?
 
 
Q