codesign results in errSecInternalComponent

I have a nodejs app, made into a single executable using pkg which signs the app with an ad-hoc signature. This single executable (xkeys-server-arm64)works fine on the machine which made it but fails on another machine of the same type - presumably because the ad-hoc signature is insufficient in this case.

I've tried to replace the ad-hoc signature with my own, using:

codesign --force --verify --verbose --sign "Developer ID Application: Christoph Willing (..........)" xkeys-server-arm64

but that fails with

xkeys-server-arm64: replacing existing signature
xkeys-server-arm64: errSecInternalComponent

Checking my own signature with:

find-identity -v -p appleID

shows a bunch of stuff which doesn't look good. My Christoph_Willing_dev_CA entry says

(CSSMERR_TP_NOT_TRUSTED)

All other entries, including the Developer ID Application entry I'm trying to codesign with have the comment:

(Missing required extension)

My questions are:

  • what causes the errSecInternalComponent error (and how can I fix it)?
  • why isn't my dev_CA trusted (and how to fix)?
  • what are the missing extensions for the other certificates (and how to provide them)?

Thanks for any tips,

chris

Answered by DTS Engineer in 709388022

presumably because the ad-hoc signature is insufficient in this case.

Right.

There’s two ways you can approach this:

  • Fix your code signing issue.

  • Avoid the whole problem by continuing with your ad hoc signature.

I have some notes about the first but, before going down that path, I’d like to tackle the second. And apropos that, you wrote:

This single executable … works fine on the machine which made it but fails on another machine of the same type

You can, in general, copy ad hoc signed code from one machine to another and it will run. The sticking point here is quarantine. If you copy the code in a way that sets quarantine, it’ll be blocked by Gatekeeper.

This leaves you with a choice:

  • If you’re copying the code around internally — say from a development machine to a test machine — the easiest solution is to bypass Gatekeeper by either copying the code in a way that doesn’t apply quarantine (scp, for example) or removing the quarantine extended attribute from the file (using xattr).

  • If you plan to distribute the code more wildly, I recommend that you sort out code signing and notarisation.


As to your code signing issue, my experience is that this has two common causes, explained in this post.

Share and Enjoy

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

Accepted Answer

presumably because the ad-hoc signature is insufficient in this case.

Right.

There’s two ways you can approach this:

  • Fix your code signing issue.

  • Avoid the whole problem by continuing with your ad hoc signature.

I have some notes about the first but, before going down that path, I’d like to tackle the second. And apropos that, you wrote:

This single executable … works fine on the machine which made it but fails on another machine of the same type

You can, in general, copy ad hoc signed code from one machine to another and it will run. The sticking point here is quarantine. If you copy the code in a way that sets quarantine, it’ll be blocked by Gatekeeper.

This leaves you with a choice:

  • If you’re copying the code around internally — say from a development machine to a test machine — the easiest solution is to bypass Gatekeeper by either copying the code in a way that doesn’t apply quarantine (scp, for example) or removing the quarantine extended attribute from the file (using xattr).

  • If you plan to distribute the code more wildly, I recommend that you sort out code signing and notarisation.


As to your code signing issue, my experience is that this has two common causes, explained in this post.

Share and Enjoy

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

Thanks for the tips @eskimo

I confirmed that copying the code with rsync bypassed the Gatekeeper and allowed the it to run.

Since I do eventually want to have it downloadable by others, I followed your link and updated the Apple Worldwide Developer Relations Intermediate Certificate and reset the trust settings which I had been playing with. That has enabled me to codesign the application without any errors, so definitely a step forward - thanks.

However after downloading the app with browser from a web site, the app still cannot run on another machine. Interestingly, using curl to download the same app from the same web site results in an app that runs normally. Checking both downloads with ls -l@ shows

    com.apple.macl        -1 
    com.apple.metadata:kMDItemWhereFroms          -1 
    com.apple.quarantine          -1

for the version downloaded with a browser, so looks like there's more to do than just codesigning the app. I'll look into that some more.

Since my question was about codesigning, I'll mark this as solved. Thanks again.

chris

errSecInternalComponent

The one time I've seen that message, the root cause was that the keychain was locked. When Xcode does the exact same codesign action, I believe a window appears asking for a password to unlock the keychain, but if I invoke codesign from the command line it fails with that error. The solution is security unlock-keychain.

That may be nothing to do with your problem, but I thought it worth mentioning.

However after downloading the app with browser from a web site, the app still cannot run on another machine.

Right. Doing this quarantines the app which then triggers Gatekeeper when you launch it. To pass Gatekeeper [1] on modern systems you must notarise your code. If you’re building outside of Xcode, follow the advice in these posts:

Share and Enjoy

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

[1] Keep in mind that we’re talking about independent distribution here. None of this applies if you distribute via the Mac App Store.

The one time I've seen that message, the root cause was that the keychain was locked.

Ah, good point. Thanks for sharing.

Normally the keychain unlocks when you log in, so this doesn’t affect folks who run codesign from Terminal [1]. I see this more frequently when folks try to sign when logged in via SSH (or in weird environments like CI systems that don’t understand Mac execution contexts).

Share and Enjoy

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

[1] Unless, like me, you keep your signing assets in their own keychain (-:

Is there something I do in e.g. my ssh config to avoid this?

No. The keychain is unlocked by loginwindow at the end of the login sequence and that code doesn’t run when you log in via SSH.

Also, best practice is to configure SSH to use key-based authentication, in which case macOS doesn’t get a copy of your password and thus it can’t possibly unlock your keychain.

It would be great to get a better error message BTW.

That’s some fine passive voice you’ve got going on there (-:

Seriously though, I completely agree with you, and I encourage you to file a bug about that. Please post your bug number, just for the record.

Share and Enjoy

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

codesign results in errSecInternalComponent
 
 
Q