sassoftware / relic

Relic is a service and a tool for adding digital signatures to operating system packages for Linux and Windows
Apache License 2.0
151 stars 41 forks source link

Fix mach-o signing when padding #21

Closed chrisroberts closed 1 year ago

chrisroberts commented 1 year ago

I ran into an issue where some of the binaries I was signing were showing as invalid when checked with codesign. Taking a problematic binary, I would sign it:

➜ ./relic sign --bundle-id curl -c ./config.yml --file ./curl --output ./curl.signed --key maccode --hardened-runtime
Signed ./curl

and then transfer it to a macos host to verify it:

Mac ~ % codesign -vvv curl.signed
curl.signed: invalid or unsupported format for signature

I attempted to resign the binary and encountered an interesting error:

➜ ./relic sign --bundle-id curl -c ./config.yml --file ./curl.signed --output ./curl.resigned --key maccode --hardened-runtime
ERROR: old signature is not coterminous with __LINKEDIT segment

After testing various binaries I was able to determine that the only binaries where this issue would occur were ones that required padding prior to the signature. Once the padding was included to determine the end of the __LINKEDIT segment the binary could be signed and resigned successfully. However, when the binary is first signed, codesign would report it with the same invalid or unsupported error. If I resigned that signed binary and checked it again, it would be valid.

Taking the signed binary and the resigned binary and diffing them led me to differing values in the cdhash. I can continue resigning the binary and the cdhash values remain the same, but the first signed binary was always different. I found this to be caused by the reader provided when reading the pages not including the trailing padding that was added. Once the padding was included, the cdhash values stay consistent and codesign shows the binary as valid:

Mac ~ % codesign -vvv curl.signed
curl.signed: valid on disk
curl.signed: satisfies its Designated Requirement

Included an unsigned binary you can use as an example for testing/validating the behavior. Thanks!

curl.zip

chrisroberts commented 1 year ago

@mtharp Thanks for taking the time to review this!