Validating Signature Of XPC Process

Quinn, you've often suggested that to validate the other side of an XPC connection, we should use the audit token. But that's not available from the XPC object, whereas the PID is. So everyone uses the PID.

While looking for something completely unrelated, I found this in the SecCode.h file

OSStatus SecCodeCreateWithXPCMessage(xpc_object_t message, SecCSFlags flags,
	SecCodeRef * __nonnull CF_RETURNS_RETAINED target);

Would this be the preferred way to do this now? At least from 11.0 and up.

Like I said, I was looking for something completely unrelated and found this and don't have the cycles right now to try it. But it looks promising from the description and I wanted to check in with you about it in case you can say yes or no before I get a chance to test it.

Thanks

Answered by DTS Engineer in 716586022

I’m posting this summary so that I can mark it as Apple Recommended and (finally!) put this issue to bed. So:

  • If you’re using NSXPCConnection, use -setCodeSigningRequirement: method to solve this problem. This was introduced with macOS 13.

  • If you’re using the XPC C API, use the xpc_connection_set_peer_code_signing_requirement API to solve this problem. This was introduced with macOS 12.

    Both of these APIs take a code signing requirement. For more information on that topic, see TN3127 Inside Code Signing: Requirements.

  • Alternatively, use the xpc_connection_set_peer_lightweight_code_requirement API added in macOS 14.4. You can read its documentation here, but I also recommend that you read the doc comments in <xpc/connection.h>.

  • If you’re using the XPC C API on macOS 11, use SecCodeCreateWithXPCMessage for this. There’s currently no documentation but there are good doc comments in <Security/SecCode.h>.

  • If none of the above apply, there isn’t a great solution. Various options have been discussed here, including on the older thread referenced above, but there’s nothing I’m fully confident in.

ps If you have follow-up questions about this stuff, please don’t put them in the comments. As I mentioned in Quinn’s Top Ten DevForums Tips, I’m not notified of those. Rather, reply here or, better yet, start a new thread with all the details. Make sure to tag your new thread with XPC so that I see it.

Share and Enjoy

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

Revision History

  • 2024-03-13 Added an entry for xpc_connection_set_peer_lightweight_code_requirement. As a postscript about follow-up questions. Made other minor editorial changes.

  • 2022-07-09 First posted.

Accepted Answer

So everyone uses the PID.

I thought everyone just using the non-public stuff (-;

Would this be the preferred way to do this now?

Absolutely.

The main drawback here is that this is tied to the XPC C API, and thus isn’t available to folks using NSXPCConnection (r. 27605275).

Share and Enjoy

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

I’m very please to announce that macOS 12 beta includes a new API that represents a great solution to this problem: Check out xpc_connection_set_peer_code_signing_requirement, and its associated doc comments, in <xpc/connection.h>.

Still no news on the NSXPCConnection side of this (r. 27605275)-:

Share and Enjoy

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

I’m posting this link to a much older thread discussing this issue, just for context.

Share and Enjoy

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

I needed a secure XPC Mach Services connection and didn't want to be directly using the XPC C API throughout my codebase, so I created the SecureXPC framework for Swift. It uses the aforementioned SecCodeCreateWithXPCMessage API on macOS 11 and later, and falls back to as eskimo says the "non-public stuff" on older versions. Sharing this in the hopes it's helpful to people here. Feedback most welcome over on the Github page either as issues or discussions!

I've just started using xpc_connection_set_peer_code_signing_requirement() and can happily report that it meets all of my needs in terms of validating who my XPC connection is really connected to. However there seems to have been a slight oversight in that the new error XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT has either not been made public, or is not available to Swift code for some reason. For example:

if event === XPC_ERROR_CONNECTION_INVALID { // OK
} else if event === XPC_ERROR_TERMINATION_IMMINENT { // OK
} else if event === XPC_ERROR_CONNECTION_INTERRUPTED { // OK 
} else if event === XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT { // Error: Cannot find in scope
}

has either not been made public

It’s definitely public, declared in <xpc/connection.h> in the macOS 12.0 SDK.

or is not available to Swift code for some reason

Indeed.

XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT is actually a macro and it seems likely that this macro is structured in a way that prevents the Swift importer from seeing it. Please file a bug about that, then post your bug number, just for the record.

Working around this is relatively straightforward: Define a C function that returns XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT and call that from your Swift code.

Share and Enjoy

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

Earlier I wrote:

Still no news on the NSXPCConnection side of this (r. 27605275)-:

I’m very pleased to say that macOS 13 beta has a shiny new -[NSXPCConnection setCodeSigningRequirement:] method. It even comes with documentation! Please take it for a spin and let us know if you hit any problems.

For an in-depth discussion of code signing requirements, see TN3127 Inside Code Signing: Requirements.

Share and Enjoy

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

I’m posting this summary so that I can mark it as Apple Recommended and (finally!) put this issue to bed. So:

  • If you’re using NSXPCConnection, use -setCodeSigningRequirement: method to solve this problem. This was introduced with macOS 13.

  • If you’re using the XPC C API, use the xpc_connection_set_peer_code_signing_requirement API to solve this problem. This was introduced with macOS 12.

    Both of these APIs take a code signing requirement. For more information on that topic, see TN3127 Inside Code Signing: Requirements.

  • Alternatively, use the xpc_connection_set_peer_lightweight_code_requirement API added in macOS 14.4. You can read its documentation here, but I also recommend that you read the doc comments in <xpc/connection.h>.

  • If you’re using the XPC C API on macOS 11, use SecCodeCreateWithXPCMessage for this. There’s currently no documentation but there are good doc comments in <Security/SecCode.h>.

  • If none of the above apply, there isn’t a great solution. Various options have been discussed here, including on the older thread referenced above, but there’s nothing I’m fully confident in.

ps If you have follow-up questions about this stuff, please don’t put them in the comments. As I mentioned in Quinn’s Top Ten DevForums Tips, I’m not notified of those. Rather, reply here or, better yet, start a new thread with all the details. Make sure to tag your new thread with XPC so that I see it.

Share and Enjoy

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

Revision History

  • 2024-03-13 Added an entry for xpc_connection_set_peer_lightweight_code_requirement. As a postscript about follow-up questions. Made other minor editorial changes.

  • 2022-07-09 First posted.

Validating Signature Of XPC Process
 
 
Q