10

It is possible to sign code or apps "ad-hoc" using codesign. The man page tells us the following about ad-hoc code signing:

If identity is the single letter "-" (dash), ad-hoc signing is performed. Ad-hoc signing does not use an identity at all, and identifies exactly one instance of code. Significant restrictions apply to the use of ad-hoc signed code; consult documentation before using this.

(Emphasis added by me)

I wanted to know more and tried to find said documentation, but I was unable to find any details. I have found a technical note called "macOS Code Signing In Depth", but it does not mention ad-hoc signing at all.

What are these "significant restrictions" and where are they documented?

4

Basically ad-hoc signing in this context means that the binary is signed without any cryptographic proof at all.

In essence normally binaries are signed by adding a so-called CMS (a cryptographic message) where the hash of the CodeDirectory is the message that is signed by the signing identity. This means that an outsider can verify that the code was indeed signed by someone holding the private key for that identity.

When running programs, the macOS system can verify that these signatures are valid, and that it trusts the signing identity - and if it does, run the program. This is the basics of the GateKeeper functionality.

Ad-hoc signed binaries are vastly different as they contain no such CMS. Instead it simply holds the SHA-1 hash value of the CodeDirectory without any cryptographic proof of its validity, and no path of certificates/identities to verify against.

The CodeDirectory is an object that describes a particular instance of static code by having hash values for various pieces of code that the application is made from. By ensuring that the CodeDirectory is untampered by verifying the cryptographic signature, and that the various code bits of the application match the hash values stored in the directory, you can ascertain that the code wasn't tampered with.

Without the cryptographic proof this "untampered" check cannot be performed in the normal way.

Instead ad-hoc signed binaries are checked by comparing the SHA-1 hash value against a list of "known good" hash values stored in the static trust cache inside the kernel.

In essence this means that the "significant restrictions" placed upon any application you ad-hoc sign yourself is that it won't pass any kind of verification anywhere. It basically be the same as a non-signed binary.

However, if you're Apple, you can create applications that aren't codesigned in the ordinary way, and are instead explicitly trusted by the kernel. I.e. if for example Apple wants to ensure that an application is untampered when run at an early stage in system startup where the full signing identity verification is not up and running (or is unavailable) they can use ad-hoc signing. These applications can always be verified by the static trust cache, no matter if your certificate repository is hosed or anything like that.

In practice creating ad-hoc signed binaries is only of practical value for Apple developers.

You can find minor documentation on ad-hoc signing in Apple's developer section. For example:

https://developer.apple.com/documentation/security/seccodesignatureflags/kseccodesignatureadhoc

But you can also find snippets of documents in the source code for the codesign utility itself, and in the source code for libsecurity.

  • Does "only of practical value for Apple developers" here mean, "only for developers working at Apple", or "only for developers working on Apple platforms"? Genuinely curious, as we've started getting some new issue where keychain can't find the key even when the name is correct, and we're considering switching to the hyphen for non-release builds. – Trejkaz Jul 12 '18 at 2:12
  • 1
    Means only for developers working at Apple. – jksoegaard Jul 12 '18 at 22:19
  • Note that the iOS simulator also uses adhoc signing. Adhoc signing may be of some use for developers outside of Apple for enabling the app to request entitlements, which I'm not sure is possible without a code signature (all the docs I've seen point to no). On the Mac this is usually not an issue but on iOS many features are gated behind entitlements, so testing that this works correctly is desirable for iOS developers. – milch Jul 2 at 11:38
  • @milch You're mixing up two unrelated concepts - "adhoc signing" (which is what this question was about), and "adhoc distribution" (which is what iOS developer often use and concern entitlements, etc.) – jksoegaard Jul 2 at 12:14
  • I'm pretty sure simulator builds are adhoc signed (not distributed). You can check by inspecting an iOS app built for the simulator with codesign -dv --verbose=4 /path/to/the.app. You'll get back a line saying Signature=adhoc, which seems to indicate an adhoc signature. Notably absent are other keys that are usually present in a regularly signed iOS application, such as Authority and TeamIdentifier – milch Jul 3 at 20:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .