Does signed macho binary with teamID is signed by Apple root certificate

In my application I validate the authenticity of my own binaries by checking that the Team Identifier in the code signature matches a predefined value.

Currently I do not perform a full signature validation that verifies the certificate chain up to Apple’s root CA. When attempting to do this using SecStaticCodeCheckValidityWithErrors (or validateWithRequirement), the operation sometimes takes several minutes. During that time the calling thread appears blocked, and the system logs show:

trustd: [com.apple.securityd:SecError] Malformed anchor records, not an array

Because of this delay, I decided to rely only on the Team Identifier. My question is:

Can it be assumed that if a Mach-O binary contains a Team Identifier in its code signature, then it must have been signed with a valid Apple Developer certificate? Or are there cases where a binary could contain a Team ID but still not be signed by Apple’s trust chain?

Thanks for the help !

I’m confused. To start, I’m concerned about this path:

I decided to rely only on the Team Identifier.

I don’t understand how you can trust anything about the code signature, and that includes the Team ID, if you don’t first validate the code signature.

Next, in cases like this I usually ask about the big picture. And on that subject you wrote:

In my application I validate the authenticity of my own binaries

Programs can’t authenticate themselves. If an attacker is able to modify your code, they can also remove or subvert any checks that you add.

What problem are you trying to solve here?

ps On iOS I usually point folks at App Attest, but I’m presuming that you’re on the Mac.

Share and Enjoy

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

Regarding Programs can’t authenticate themselves. I don't try to authenticate my own executable, I am trying to verify a helper binary/dylib inside my product that can be updated separately from the main binary.

Before running/dlopening it, I would like to ensure:

Test 1) The signature chain of the executable/dylib leads to the apple root.

Test 2) The leaf certificate team-id is my team-id.

Per my understanding this will ensure that this executable/binary was signed by me.

If anyone else has a valid certificate(it can pass Test 1) but it will fail the Test 2 as its team ID will be different.

If someone crafts a rogue certificate in order to pass Test 2 then this rogue certificate is not signed by apple and therefore will fail Test 1.

Please advise if you see any problem with this approach.

Now to my main question: When I try to extract the team id from the executable/dylib using SecCodeCopySigningInformation, I see some posts claim that if that executable is not signed by apple root chain team-id will come up as empty.

I therefore ask:

Approach 1: Is it enough to extract the team-id and compare to mine ? Does extracting a team-id(using SecCodeCopySigningInformation) automatically verifies that the anchor is apple ?

OR

Approach 2: Should I extract the team-id and compare it to mine AND in addition, manually verify the that anchor/root is apple ?

I currently did "Approach 2" but it seems when I am trying to verify the anchor it sometimes takes several minutes for some reason and I see:

trustd: [com.apple.securityd:SecError] Malformed anchor records, not an array

Printed in the logs.

I therefore wonder if its required at all.

I am trying to verify a helper binary/dylib inside my product that can be updated separately from the main binary.

Is this an executable or a dynamic library? Or do you need this test to support both?

And by “inside my product” do you mean that it’s located within an app’s bundle? Or that it’s logically part of your product, but is stored in some other location on disk?


And while I’ll have a lot more to say about your overall issue once I better understand it, I want to nip this one in the bud:

Does extracting a team-id … automatically verifies that the anchor is apple?

No. You can’t trust the information you get back from SecCodeCopySigningInformation unless you’ve validated the code signature.

Share and Enjoy

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

Hi @DTS Engineer , I need to support both use case (exec and dylib). As for the library case, I’m aware that macOS provides built-in validation to ensure a library and the loading binary are signed with the same certificate, this does not apply in my scenario since the library is provided by a third party.

So I've disabled the default library validation via the entitlement com.apple.security.cs.disable-library-validation, and instead perform my own certificate validation logic within the application code.

Does signed macho binary with teamID is signed by Apple root certificate
 
 
Q