Code signatures are used throughout iOS to allow binaries to be executed on device. Without a code signature, a binary won't be able to run. The code signature consists of multiple blobs: entitlements, requirements, CodeDirectory and the signature itself.
Code directory
The code directory is a data blob that contains hashes for the rest of the binary, and it has the 0xFADE0C02
magic. Firstly you have the "special slots" - which go from -11 to -1:
- -1: The hash of the Info.plist file
- -2: The hash of the requirements blob
- -3: The hash of _CodeSignature/CodeResources
- -4: An app-specific hash (often goes unused)
- -5: The hash of the entitlements blob
- -6: The hash of a disk image (if applicable)
- -7: The hash of the DER-encoded entitlements blob
- -8 through -11: The hashes of various launch constraints for the process and related processes (if applicable)
Following these slots are regular "code slots" (slots 0 onwards), which are hashes of each page of the Mach-O binary. This way, the code directory itself can be hashed, and is representative of the entire binary. If one byte is changed anywhere, the CDHash (code directory hash) will be incorrect.
Entitlements
The entitlements blobs are used to store the entitlements of the binary. There are two entitlements blobs in the code signature - one is a DER-encoded blob, and the other is a XML blob. The XML blob has a magic of 0xFADE7171
, and the DER blob has a magic of 0xFADE7172
.
Entitlements are a set of key-value pairs that define what the binary is allowed to do. For example, the com.apple.private.security.no-sandbox entitlement allows the binary to run without sandbox restrictions. The com.apple.private.persona-mgmt entitlement allows a binary to spawn another binary under the root user (or any user, for that matter).
Requirements
The requirements blob is used to store the requirements of the binary. Requirements are a set of rules that must be met in order for the binary to be allowed to run. It appears requirements are not respected for App Store apps (and hence apps which are signed with a CoreTrust bypass), but they are respected for developer-signed apps. If an app's code signature does not meet the requirements, the app will not be allowed to run.