You use the codesign command-line tool to sign your code. This section discusses what to sign and gives some examples of the use of codesign. See the codesign(1) manual page for a complete description of its use.
What to Sign
When to Sign
Using the codesign Utility
You should sign every program in your product, including applications, tools, hidden helper tools, utilities and so forth. Signing an application bundle covers its resources, but not its subcomponents such as tools and sub-bundles. Each of these must be signed independently.
If your application consists of a big UI part with one or more little helper tools that try to present a single face to the user, you can make them indistinguishable to code signing by giving them all the exact same code signing identifier. (You can do that by making sure that they all have the same CFBundleIdentifier value in their Info.plist, or by using the -s option in the codesign utility, as described in “Signing Code,” to assign the same identifier.) In that case, all your program components have access to the same keychain items and validate as the same program. Do this only if the programs involved are truly meant to form a single entity, with no distinctions made.
A universal binary (bundle or tool) automatically has individual signatures applied to each architecture component. These are independent, and usually only the native architecture on the end user's system is verified.
You may also want to sign your plugins and libraries. Although this is not currently required, it will be in the future, and there is no disadvantage to having signatures on these components.
Depending on the situation, codesign may add to your Mach-O executable file, add extended attributes to it, or create new files in your bundle's Contents directory. None of your other files is modified.
You can run codesign at any time on any system running Mac OS X v10.5 or later, provided you have access to the signing identity. You can run it from a shell script phase in Xcode if you like, or as a step in your Makefile scripts, or anywhere else you find suitable. Signing is typically done as part of the product mastering process, after quality assurance work has been done. Avoid signing pre-final copies of your product so that no one can mistake a leaked or accidentally released incomplete version of your product for the real thing.
Your final signing must be done after you are done building your product, including any post-processing and assembly of bundle resources. Code signing detects any change to your program after signing, so if you make any changes at all after signing, your code will be rejected when an attempt is made to verify it. Sign your code before you package the product for delivery.
Because each architecture component is signed independently, it is all right to perform universal-binary operations (such as running the lipo command) on signed programs. The result will still be validly signed as long as you make no other changes.
The codesign command is fully described in the codesign(1) manual page. This section provides some examples of common uses of the command. Note that your signing identity must be in a keychain for these commands to work.
To sign the code located at code-path, using the signing identity identity, use the following command:
codesign -s identity code-path ...
Signing identities are discussed in “Obtaining a Signing Identity.”
As is typical of Unix-style commands, this command gives no confirmation of success. To get some feedback, include the -v option:
codesign -s -v identity code-path ...
The identity can be named with any (case sensitive) substring of the certificate's common name attribute, as long as it's unique throughout your keychains.
Use the -r option to specify an internal requirement. With this option you can specify a text file containing the requirements, a precompiled requirements binary, or the actual requirements text prefixed with an equal sign (=). For example, to add an internal requirement that all libraries be signed by Apple, you could use the following option:
-r="library => anchor apple" |
If you have built your own certificate hierarchy (perhaps using Certificate Assistant—see “Obtaining a Signing Identity”), and want to use your certificate’s anchor to form a designated requirement for your program, you could use the following command:
codesign -s signing-identity -r="designated => anchor /my/anchor/cert and identifier com.mycorp.myprog" |
Note that the requirement source language accepts either an SHA1 hash of a certificate (for example H"abcd....") or a path to the DER encoded certificate in a file. It does not currently accept a reference to the certificate in a keychain, so you have to export the certificate before executing this command.
You can also use the csreq utility to write the requirements out to a file, and then use the path to that file as the input value for the -r option in the codesign utility. See the manual page for csreq(1) for more information on that utility.
Here are some other samples of requirements:
anchor apple –the code is signed by Apple
anchor trusted –the anchor is trusted (for code signing) by the system
certificate leaf = /path/to/cert –the leaf (signing) certificate is the one specified
certificate leaf = /path/to/cert and identifier "com.mycorp.myprog" –the leaf certificate and program identifier are as specified
info[mykey] = myvalue – the Info.plist key mykey exists and has the value myvalue
Except for the explicit anchor trusted requirement, the system does not consult its trust settings database when verifying a code requirement. Therefore, as long as you don’t add this designated requirement to your code signature, the anchor certificate you use for signing your code does not have to be introduced to the user’s system for validation to succeed.
To verify the signature on a signed binary, use the -v option with no other options:
codesign -v code-path ...
This checks that the code binaries at code-path are actually signed, that the signature is valid, that all the sealed components are unaltered, and that the whole thing passes some basic consistency checks. It does not by default check that the code satisfies any requirements except its own designated requirement. To check a particular requirement, use the -R option. For example, to check that the Apple Mail application is identified as Mail, signed by Apple, and secured with Apple’s root signing certificate, you could use the following command:
codesign -v -R="identifier com.apple.Mail and anchor apple" /Applications/Mail.app |
Note that, unlike the -r option, the -R option takes only a single requirement rather than a requirements collection (no => tags). Add one or more additional -v options to get details on the validation process.
If you pass a number rather than a path to the verify option, codesign takes the number to be the process ID (pid) of a running process, and performs dynamic validation instead.
To get information about a code signature, use the -d option. For example, to output the code signature’s internal requirements to standard out, use the following command:
codesign -d -r- code-path |
Note that this option does not verify the signature.
Last updated: 2007-05-15