Code Signing Release Notes for WWDC Seed



This file describes what changed with Code Signing since the Leopard GM release. Note that some of these changes have also been implemented in the 10.5.2 and 10.5.3 software updates to Leopard, and that in some cases the Leopard Update code may show slightly different behavior.

Public API

Major parts of the Code Signing API are now public in SnowLeopard and available for developer use. Specifically, the static and dynamic validation APIs, the APIs for manipulating code requirements, and the hosting API are included.

The signing API remains private. If you believe you need to sign code by calling an API (rather than running the codesign(1) command), please let us know.

As always, keep your fingers off all undocumented bits and dictionary keys, intriguing as they may be.

The Code Signing API is not currently available in the iOS SDK.

New Capabilities

Code Signing can now sign shallow bundles (the kind where everything is in one directory). To be recognized by Code Signing, the Info.plist must contain a CFBundleResourceSpecification key pointing at a valid resource specification file inside the bundle. There is no default resource specification for shallow bundles, since they have insufficient structure to infer one.

Code Signatures can now embed an entitlement configuration. This is used on the iPhone, but is also available on OS X. (OS X currently makes no use of entitlements.)

The requirement language has expanded:

Implicit Designated Requirements now traverse the certificate chain from the signing (leaf) certificate towards the anchor (root) until the Organization part of the subject changes. This means that if you made your own certificate authority and gave all certificates the same Organization (i.e. yours), the Designated Requirement will point at your anchor, not your leaf, and will thus be much more useful by default.

Bugs Fixes and Improvements

Files added to a bundle during signing are now placed into a _CodeSignature subdirectory, rather than placed directly into the support (Contents) directory. Symbolic links are placed into Contents to ease any transition issues, but will be eventually removed. This should not affect you unless you somehow explicitly addressed such files.

Code objects obtained from running code now dynamically pick the right Mach-O architecture by asking the kernel for it. In Leopard, this involved a heuristic that sometimes got it wrong when 32-bit and 64-bit programs tried to discuss each other’s validity.

The system now compares the signature picked up from disk with that used by the kernel and denies validation if they differ. This correctly rejects any situation where the main executable has changed since the kernel started running it. This means that from user space, any running program whose main executable file has changed on disk will (correctly) appear invalid.

The system generates correct implicit Designated Requirements for programs signed with identities issued by Apple to iPhone developers.

Requirement conversion to string (source) form does a better job at quoting string constants where needed.

During signing, Mach-O programs automatically embed internal library requirements for dynamic libraries they are linked with, in preparation for automatic library validation down the road.

Codesign(1) is now more likely to display (-d) the contents of, and allow re-signing (-f -s) of code with badly broken signatures, rather than just complain about it.

The --continue option now works for all operations in codesign(1), rather than just verifications.

Codesign(1) diagnostic messages now better describe the situation where some signing identities are available, but all are unsuitable for code signing. (This was previously reported as no signing identities at all being found.)

Codesign(1) now prefers an exact name match for a signing certificate over substring matches. You should be able to specify any certificate with its exact subject common name, as long as that is unique within your keychain search path.

A new --extract-certificates option allow codesign(1) to retrieve the embedded certificate chain of a code signature for detailed inspection.


Code signed on Leopard should verify without trouble in SnowLeopard.

Code signed on SnowLeopard will generally verify in Leopard 10.5.3 or later. Leopard 10.5.2 and 10.5.3 contain enhancements that teach Leopard to deal with most of the SnowLeopard-specific novelties. Leopard versions 10.5.0 and 10.5.1 may reject some code signed in SnowLeopard as invalid, though common cases will work.

Known Issues

Bundles whose main executable files have names containing regular expression meta-characters (+, *, [], etc.) cannot be signed or validated. As a work-around, rename the main executable to not contain these characters, and update the Info.plist to match. You do not need to rename the actual bundle or program. This does not affect single-file (unbundled) code.

The certificate[field...] requirement operator does not recognize some extensions that are in fact present. This includes some extensions used by the iPhone signing logic, which may cause properly signed iPhone applications appear to not match their designated requirements. This bug only affects SnowLeopard.

The hosting API header (SecCodeHost.h) was inadvertently omitted from the seed. It will be public in a future seed.

In some situations, the requirement compiler reverses the relative priority of and and or operators. If you combine and and or in a requirement expression, use explicit parentheses.

It is not possible to reliably sign or verify a whole framework. To sign and verify frameworks, address a (usually “the”) particular version, e.g.

codesign -v .../Frobozz.framework/Versions/A