NSXPCConnection setCodeSigningRequirement: in sandbox works only with Developer ID signing

Hello,

I use setCodeSigningRequirement: in sandboxed XPCService and it seems that no matter what I always get errSecCSNoSuchCode[1] when the app is signed with development certificate. The same application signed with DeveloperID is fine.

I use following CSR for development signed builds.

identifier com.example.app and anchor apple generic 
and certificate 1[field.1.2.840.113635.100.6.2.1] exists 
and certificate leaf[field.1.2.840.113635.100.6.1.12] exists

But also tried to simplify to identifier com.example.app or just true. If I validated the CSR with codesign -R I get "explicit requirement satisfied".

I spotted this log line:


Sandbox: com.example.app(67058) deny(1) file-read-data /Users/(...)/example-app/build/arm64-mac/src/mac/app/Debug/Example App.app/Contents/MacOS/ExampleApp

So I disabled the sandbox for XPCService and now everything works. But then why the DeveloperID signed build works with XPCService sandboxed? ...or does it really? :)

Just for completeness the CSR which I use in production build are:

identifier com.example.app and anchor apple generic
and certificate 1[field.1.2.840.113635.100.6.2.6] exists
and certificate leaf[field.1.2.840.113635.100.6.1.13] exists
and certificate leaf[subject.OU] = EXAMPLE
Answered by isnotgoodms in 792413022

Thank you Quinn for looking into this. I think I found the problem:

I'm having a simple scenario where main bundle contains and embedded XPCService bundle. In services NSXPCListenerDelegate I'm using the - setCodeSigningRequirement: on the incoming connection with valid code signing requirements.

The connection was always refused and I've seen the security_exception in the log. So I compared the entitlements and signing of the applications bundles and only difference between working and non-working version was obvious presence of get-task-allow on developer signed builds and different signing certificate chain. So I was wrongly assuming that difference is due to signing.

But it turned out that if I moved the problematic bundle to /Applications it immediately started to work. So it's not a signing difference but it's on-disk location difference.

I think it can come from the application.sb:

(allow file-read*
       process-exec
       ...
       (subpath "/Developer")
       (subpath "/Applications"))

So when the XPCService is located under /Applications it can read the code signature from the parent bundle's executable.

I'm not sure that profile is used for XPCServices bundled in the application but it would explain the behaviour.

[1] Here's the full error stack:

connection	[0x13a904080] activating connection: mach=false listener=false peer=true name=com.example.app.service.peer[46207].0x13a904080	com.apple.xpc
security_exception	MacOS error: -67065	com.apple.securityd
security_exception	0   Security                            0x00000001943d6108 Security::CommonError::LogBacktrace() + 124	com.apple.securityd
security_exception	1   Security                            0x00000001943d66bc Security::MacOSError::MacOSError(int) + 340	com.apple.securityd
security_exception	2   Security                            0x00000001943d672c Security::MacOSError::throwMe(int) + 40	com.apple.securityd
security_exception	3   Security                            0x00000001942d28d4 Security::CodeSigning::KernelCode::locateGuest(__CFDictionary const*) + 1140	com.apple.securityd
security_exception	4   Security                            0x00000001942a7560 Security::CodeSigning::SecCode::autoLocateGuest(__CFDictionary const*, unsigned int) + 132	com.apple.securityd
security_exception	5   Security                            0x00000001942b05c8 SecCodeCopyGuestWithAttributes + 156	com.apple.securityd
security_exception	6   support                             0x0000000104d166e8 xpc_support_check_token + 280	com.apple.securityd
security_exception	7   libxpc.dylib                        0x00000001910632e0 _xpc_connection_check_peer_requirement + 428	com.apple.securityd
security_exception	8   libxpc.dylib                        0x000000019104b58c _xpc_connection_mach_event + 1056	com.apple.securityd
security_exception	9   libdispatch.dylib                   0x0000000105092c64 _dispatch_client_callout4 + 20	com.apple.securityd
security_exception	10  libdispatch.dylib                   0x00000001050b5994 _dispatch_mach_msg_invoke + 612	com.apple.securityd
security_exception	11  libdispatch.dylib                   0x000000010509bb98 _dispatch_lane_serial_drain + 368	com.apple.securityd
security_exception	12  libdispatch.dylib                   0x00000001050b70c4 _dispatch_mach_invoke + 496	com.apple.securityd
security_exception	13  libdispatch.dylib                   0x000000010509bb98 _dispatch_lane_serial_drain + 368	com.apple.securityd
security_exception	14  libdispatch.dylib                   0x000000010509ceb0 _dispatch_lane_invoke + 468	com.apple.securityd
security_exception	15  libdispatch.dylib                   0x00000001050ac958 _dispatch_root_queue_drain_deferred_wlh + 652	com.apple.securityd
security_exception	16  libdispatch.dylib                   0x00000001050abc30 _dispatch_workloop_worker_thread + 444	com.apple.securityd
security_exception	17  libsystem_pthread.dylib             0x000000010513bd40 _pthread_wqthread + 288	com.apple.securityd
security_exception	18  libsystem_pthread.dylib             0x0000000105143a94 start_wqthread + 8	com.apple.securityd
esecurity_exception	UNIX error exception: 1	com.apple.securityd
security_exception	0   Security                            0x00000001943d6108 Security::CommonError::LogBacktrace() + 124	com.apple.securityd
security_exception	1   Security                            0x00000001943d6464 Security::UnixError::UnixError(int, bool) + 352	com.apple.securityd
security_exception	2   Security                            0x00000001943d64d4 Security::UnixError::throwMe(int) + 44	com.apple.securityd
security_exception	3   Security                            0x00000001943d6aec Security::UnixPlusPlus::FileDesc::close() + 0	com.apple.securityd
security_exception	4   Security                            0x00000001942fcbd0 Security::CodeSigning::SingleDiskRep::fd() + 64	com.apple.securityd
security_exception	5   Security                            0x00000001942dfdfc Security::CodeSigning::MachORep::MachORep(char const*, Security::CodeSigning::DiskRep::Context const*) + 528	com.apple.securityd
security_exception	6   Security                            0x00000001942d223c Security::CodeSigning::KernelCode::identifyGuest(Security::CodeSigning::SecCode*, __CFData const**) + 684	com.apple.securityd
security_exception	7   Security                            0x00000001942a6bc8 Security::CodeSigning::SecCode::identify() + 100	com.apple.securityd
security_exception	8   Security                            0x00000001942a759c Security::CodeSigning::SecCode::autoLocateGuest(__CFDictionary const*, unsigned int) + 192	com.apple.securityd
security_exception	9   Security                            0x00000001942b05c8 SecCodeCopyGuestWithAttributes + 156	com.apple.securityd
security_exception	10  support                             0x0000000104d166e8 xpc_support_check_token + 280	com.apple.securityd
security_exception	11  libxpc.dylib                        0x00000001910632e0 _xpc_connection_check_peer_requirement + 428	com.apple.securityd
security_exception	12  libxpc.dylib                        0x000000019104b58c _xpc_connection_mach_event + 1056	com.apple.securityd
security_exception	13  libdispatch.dylib                   0x0000000105092c64 _dispatch_client_callout4 + 20	com.apple.securityd
security_exception	14  libdispatch.dylib                   0x00000001050b5994 _dispatch_mach_msg_invoke + 612	com.apple.securityd
security_exception	15  libdispatch.dylib                   0x000000010509bb98 _dispatch_lane_serial_drain + 368	com.apple.securityd
security_exception	16  libdispatch.dylib                   0x00000001050b70c4 _dispatch_mach_invoke + 496	com.apple.securityd
security_exception	17  libdispatch.dylib                   0x000000010509bb98 _dispatch_lane_serial_drain + 368	com.apple.securityd
security_exception	18  libdispatch.dylib                   0x000000010509ceb0 _dispatch_lane_invoke + 468	com.apple.securityd
security_exception	19  libdispatch.dylib                   0x00000001050ac958 _dispatch_root_queue_drain_deferred_wlh + 652	com.apple.securityd
security_exception	20  libdispatch.dylib                   0x00000001050abc30 _dispatch_workloop_worker_thread + 444	com.apple.securityd
security_exception	21  libsystem_pthread.dylib             0x000000010513bd40 _pthread_wqthread + 288	com.apple.securityd
security_exception	22  libsystem_pthread.dylib             0x0000000105143a94 start_wqthread + 8	com.apple.securityd
<Missing Description>	xpc_support_check_token: identifier com.example.app status: 100001	
connection	[0x13a904080] invalidated because the current process cancelled the connection by calling xpc_connection_cancel()	com.apple.xpc
<Missing Description>	invalidate<com.example.app.service([app<application.com.example.app.271193970.274328866.AF06BFB0-EAE9-4539-AA9C-368A2584E9AE(501)>:46207])(501)>{vt: (null)}:

By “XPCService” do you mean an .xpc bundle within your app?

If so, applying a code signing requirement is kinda pointless. XPC services bundled within your app are only visible to your app.

Share and Enjoy

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

By “XPCService” do you mean an .xpc bundle within your app?

Yes, I do.

If so, applying a code signing requirement is kinda pointless. XPC services bundled within your app are only visible to your app.

I'm not really sure what visibility means in this case, so asked here https://developer.apple.com/forums/thread/757627. Our security team requires us to make sure no-one else can connect to in case the can guess the service's port (if that's possible).

Why the DeveloperID signed app is validating the connection from sandboxed xpcservice just fine?

I’m not really sure I understand this question. Can you post a more complete explanation of what the tests you ran and the behaviours you saw?

ps It’s best to reply in a reply; if you reply in comments, I’m not notified. See Quinn’s Top Ten DevForums Tips for this and other advice on how best to use DevForums.

Share and Enjoy

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

Thank you Quinn for looking into this. I think I found the problem:

I'm having a simple scenario where main bundle contains and embedded XPCService bundle. In services NSXPCListenerDelegate I'm using the - setCodeSigningRequirement: on the incoming connection with valid code signing requirements.

The connection was always refused and I've seen the security_exception in the log. So I compared the entitlements and signing of the applications bundles and only difference between working and non-working version was obvious presence of get-task-allow on developer signed builds and different signing certificate chain. So I was wrongly assuming that difference is due to signing.

But it turned out that if I moved the problematic bundle to /Applications it immediately started to work. So it's not a signing difference but it's on-disk location difference.

I think it can come from the application.sb:

(allow file-read*
       process-exec
       ...
       (subpath "/Developer")
       (subpath "/Applications"))

So when the XPCService is located under /Applications it can read the code signature from the parent bundle's executable.

I'm not sure that profile is used for XPCServices bundled in the application but it would explain the behaviour.

NSXPCConnection setCodeSigningRequirement: in sandbox works only with Developer ID signing
 
 
Q