Auditing code signatures

We are trying to get much more serious about our ability to audit signed code and trace it back to a signing event. We have a signing service that includes a bit of client code that provides a CryptoTokenKit extension to expose the signing certificate to codesign and Xcode. The private keys are held by the signing service and access is strictly controlled.

The CTK extension is given a message/digest to sign, and from reading TN 3126, I believe this is representative of the code directory. For an audit trail, we can record some metadata about the signing request, such as Git repository, branch, commit SHA, etc., but the only value linked to the thing being signed is this blob.

Later, if we have an app and want to link it back to the signing event, I can't figure out how to find this blob. It's not the CDHash or any other value I see in the output of codesign -d -vvvvvv.

is there a way to recreate that blob given a signed artifact?

Answered by DTS Engineer in 822151022

The Inside Code Signing technotes have to strike a delicate balance between:

  • Helping developers understand how this stuff works, and

  • Discussing too many implementation details

The end result was that they don’t go into minute detail — they’re not a specification of the code signature format! — and I put a big disclaimer at the top of each technote (-:

And with that in mind, let’s look at your specific question:

Written by SteveM-JC in 772761021
is there a way to recreate that blob given a signed artifact?

Not in a way that DTS is prepared to support.

The signing code is in Darwin so you could rummage around there to see what’s what. However, this isn’t something we support because these low-level details of code signing have changed in the past and could well change again in the future.

Having said that, I understand your desire to track the origin of signed artefacts, and it’d be nice if we could create a supported path forward. I encourage you to file an enhancement request that describes what you’re trying to do, why, and what problems you’re hitting.

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"

Accepted Answer

The Inside Code Signing technotes have to strike a delicate balance between:

  • Helping developers understand how this stuff works, and

  • Discussing too many implementation details

The end result was that they don’t go into minute detail — they’re not a specification of the code signature format! — and I put a big disclaimer at the top of each technote (-:

And with that in mind, let’s look at your specific question:

Written by SteveM-JC in 772761021
is there a way to recreate that blob given a signed artifact?

Not in a way that DTS is prepared to support.

The signing code is in Darwin so you could rummage around there to see what’s what. However, this isn’t something we support because these low-level details of code signing have changed in the past and could well change again in the future.

Having said that, I understand your desire to track the origin of signed artefacts, and it’d be nice if we could create a supported path forward. I encourage you to file an enhancement request that describes what you’re trying to do, why, and what problems you’re hitting.

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"

Thanks, Quinn! We'll take a look at the Darwin code and evaluate the effort there. In the meantime, I filed an enhancement request through Feedback Assistant: FB16386476.

So I also asked about this internally and have something I’d like you to try. If you dump a code signature with enough -v options, you eventually get to the CMSDigest field. Does that line up with your signing operations?

% codesign -d --arch arm64 -vvvvv /Applications/Pages.app
…
CMSDigest=4380386763a016bee5fbfbf362f7c9c05bb1a5ea2d5ed9535b371fb36223e3e6
…
% codesign -d --arch x86_64 -vvvvv /Applications/Pages.app
…
CMSDigest=d4d89d97cc94daa5437f14f02490a4a9efd9eece7ca22150d807df344c36d3c9
…

Note that it’s different for each architecture.

Share and Enjoy

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

It doesn't. I checked both standalone binaries and .app bundles, and in both cases CMSDigest matches CandidateCDHashFull. The digests signed by the CTK extension are 256-bits, the same length as CMSDigest and sha256 CDHash, but not the same bytes.

CandidateCDHashFull sha256=bc8686ef2e5092e3d6e133ed29521fad2db6d6e819c6d2752c8b480be6852fdd
Hash choices=sha256
CMSDigest=bc8686ef2e5092e3d6e133ed29521fad2db6d6e819c6d2752c8b480be6852fdd

Bummer.

Please update FB16386476 with new info like this as you discover it.

Share and Enjoy

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

Auditing code signatures
 
 
Q