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"

Can I Exporting a Developer ID PacketTunnelProvider Plugin?
 
 
Q