Companies often need to re-sign custom apps which 
they have commissioned for deployment in an enterprise app store. 
Typically this is done with tools available on an Apple Mac 
(specifically, a tool called “codesign”
 that can either be invoked directly or via “Xcode”
 – an integrated development environment). However, Apple Mac devices 
are not commonly available in many companies and the question is 
sometimes asked whether it is practical to
 sign such apps using tools that can run under Microsoft Windows.
An Apple app is actually a ZIP archive with a naming 
convention for certain core files. The top-level folder is always called
 “Payload” and this contains a single folder named after the application
 (e.g.
Example.app). The first core file is called 
Info.plist and would be found at this path in the archive:
                Payload/Example.app/Info.plist
The extension “.plist” indicates that this is a “property list” file and some of the properties in this file are essential to signing and executing the
 app. For example, the property “CFBundleExecutable” identifies the file that is the main “executable” file for the app and “CFBundleIdentifier”
 specifies the globally unique identifier for the app. As
 the Wikipedia article mentions, there are a variety of representations 
of property list files, one of which is an XML format; this XML format 
is the most easy to manipulate under Windows. If re-signing the app will
 require changes to
Info.plist (more on this later), then 
Info.plist can be converted into the XML format (if it is not 
already in this format), modified and saved in XML format (there is no 
need to convert it back into its original format).
Signing a Mach-O binary app
If the main executable is a 
Mach-O binary file then (normally) the bulk of the code signing 
information is embedded in this file. A Mach-O file can be “fat” 
(contains a collections of machine architecture specific slices) or 
“thin” (contains just the code for one machine architecture).
 Each machine architecture specific slice is signed individually, so 
signing a “fat” Mach-O file is equivalent to individually signing a 
collection of “thin” Mach-O files.
The embedded code signing information obviously 
consumes space in the Mach-O file and this space is not 
available/reserved in a newly compiled and linked Mach-O file – space 
has to be added. There is a program for the Apple Mac called “codesign_allocate”
 that extends Mach-O files to make space for a code signature. 
Typically, extending a Mach-O file to make space for a signature 
involves locating the segment called “__LINKEDIT” (other common segments
 are called “__TEXT” and “__DATA”) and extending it to make
 space for (an estimate of the size of) the code signature. A Mach-O 
“load command” called “LC_CODE_SIGNATURE” is also appended to the other 
load commands to record the size and location of the code signature. If 
the Mach-O file is “fat” then the individual
 “thin” slices must be separately extended and moved within the “fat” 
file, and the corresponding sizes and offsets to the “thin” slice 
updated.
The space reserved by “codesign_allocate”
 is typically large enough to contain a replacement code signature, 
which means that it is not normally necessary to repeat the operation 
when re-signing an app.
A “C” include file containing definitions of the data structures in a “thin” Mach-O file (“loader.h”) can be found
here, and definitions of the data structures in a “fat” file (“fat.h”) can be found
here. The third (and final) include file (“codesign.h”), containing the code signing data structures themselves, needed to understand the code signing process can be found
here.
The code signature is actually a “superblob” (using a name derived from
codesign.h), which typically contains four “blobs”: 
CODEDIRECTORY, REQUIREMENTS, ENTITLEMENTS and SIGNATURE.
Let’s start with the CODEDIRECTORY blob. At the 
time of writing, three versions of this data structure are often 
encountered (2.00, 2.01 and 2.02). Amongst other things, this blob 
contains the globally unique identifier of the app, the
 hash algorithm (normally SHA-1), hashes of the pages of the main 
executable (up to, but not including, the code signature) and hashes of 
other important data structures (e.g. REQUIREMENTS and ENTITLEMENTS 
blobs) and files (e.g.
Info.plist and _CodeSignature/CodeResources).
Even if the app is just being resigned with a 
“newer” certificate issued to the same subject as the original signer, 
it will still be necessary to modify this blob. The reason is rather 
convoluted. The signing certificate (in its entirety,
 base64 encoded) is included in the “provisioning profile” which is a 
PKCS #7 signed data blob, signed by Apple and downloaded from the iOS 
Developer Enterprise Program web site; the provisioning profile is 
included in the app in a file with the name “embedded.mobileprovision”
 (e.g. “Payload/Example.app/embedded.mobileprovision”). A hash (or two) of “embedded.mobileprovision” is included in the file _CodeSignature/CodeResources
 (e.g. “Payload/Example.app/_CodeSignature/CodeResources”) and a hash of _CodeSignature/CodeResources is included in
 the CODEDIRECTORY blob. 
If the app was originally signed by a software 
developer and we now wish to re-sign the app for enterprise deployment, 
then even more elements of the blob will change (e.g. the globally 
unique identifier, the hash of the ENTITLEMENTS blob,
 the hash of Info.plist, amongst others). The globally unique identifier in the CODEDIRECTORY blob must match the value of the
CFBundleIdentifier property in Info.plist; the
CFBundleIdentifier property in Info.plist
 must be consistent with the application-identifier in the provisioning 
profile; the entitlements in the ENTITLEMENTS blob must be consistent 
with the entitlements
 in the provisioning profile’s “Entitlements” property, etc..
The REQUIREMENTS blob expresses additional 
requirements that the application must fulfil in order to be allowed to 
run. The requirements are expressed in a language documented in the “Code
 Signing Guide” from Apple; the Apple codesign tool (whose source code is available
here) uses
ANTLR to recognize the requirements.
A typical requirement might be:
designated => identifier "com.acme.myapp"
 and anchor apple generic and certificate leaf[subject.CN] = "iPhone 
Distribution: Acme Corporation" and certificate 
1[field.1.2.840.113635.100.6.2.1]
 exists
These requirements  are
 not linked to the provisioning profile, so one has some flexibility 
about what requirements to include. The requirements are checked when 
the app is loaded, so whatever the requirements
 express needs to be true for the signed app. The requirement shown 
above is of the form of the default requirement set by the “codesign” tool. “1.2.840.113635.100.6.2.1” is a “marker” certificate extension OID included in the “Apple
 Worldwide Developer Relations Certification Authority” certificate.
Apple apps run in a sandbox environment and the 
ENTITLEMENTS blob specifies which additional rights/entitlements the app
 should be granted. As mentioned earlier, the contents of the 
ENTITLEMENTS blob must be “consistent” with the entitlements
 in the provisioning profile’s “Entitlements” property. “Consistent” in 
this context means that the claimed entitlements should be a subset of 
the entitlements granted by the provisioning profile; wildcard values in
 the provisioning profile should be replaced
 by fully qualified values in the ENTITLEMENTS blob.
The SIGNATURE blob contains a PKCS #7 signed data 
“detached signature”, signing the contents of the CODEDIRECTORY blob. 
The “signer
infos” element typically includes the full 
trust chain of the signing certificate (including the trusted root 
certification authority certificate) and sometimes includes a PKCS #9 
“signing time” attribute in the set of authenticated
 attributes; the signature is not countersigned by a time stamping 
service. The signing certificate contains an “Authority Information 
Access” extension that contains the URL of an Apple “On-Line Certificate
 Status Protocol” (OCSP) server.
Signing a script-based app
If the app does not have a Mach-O binary file as 
its “bundle executable” then the various blobs described above are 
stored as separate files in the _CodeSignature folder; the folder structure will look like this:
- Payload/Example.app/_CodeSignature/CodeDirectory
- Payload/Example.app/_CodeSignature/CodeRequirements
- Payload/Example.app/_CodeSignature/CodeResources
- Payload/Example.app/_CodeSignature/CodeSignature
Additional steps for “first time” signature
The additional steps involved in signing an app for the first time are the reservation of space in Mach-O executables and computing the list of files to be hashed and their hashes (i.e. generating the file _CodeSignature/CodeResources).
There are built-in (into the codesign tool) “rules” for deciding which files in an app bundle should have their hashes included in
CodeResources, but this can be influenced by creating a property list file containing other inclusion rules (often a file called “ResourceRules.plist” is used for this purpose). To be consistent with the
 newest code signing expectations, all “possible” files should have their hashes included in
CodeResources; some files cannot have their hashes included in
CodeResources (e.g. CodeResources itself and other code signing files in the _CodeSignature folder and the bundle executable (if it is in Mach-O format)) because they include
 a hash of  CodeResources and are consequently modified after
CodeResources has been created.
Magic is important
The information in Mach-O files can be either big 
or little endian and Mach-O slices can be 32 or 64 bit. The values of 
the magic numbers at the start of many of the Mach-O data structures 
allows both of these characteristics to be determined.
 The signature blobs contain magic numbers too, so even if the signature
 information is stored in separate files in the _CodeSignature folder, the byte ordering needed for the file can be determined.
Run-time validation of an app
The text above describes what “raw” information is 
available when making a decision about whether an app should be allowed 
to run. The tests that are actually performed depend upon the platform 
and the version of the operating system installed
 on the device.
A key feature is the inclusion of information signed by Apple (the file “embedded.mobileprovision” containing the provisioning profile) and the link between this information and the “distribution” certificate
 used to sign the app bundle.
As an example, in the case of apps signed for 
distribution in an enterprise app store, the App ID and/or Team ID 
prefixes provide the raw information needed to check (against a database
 of installed apps) whether apps from other “enterprises”
 are installed on the device. This could be (is?) used to prevent apps 
from being sold outside the Apple App Store.
Developing a tool under Windows
The .NET framework contains classes that make 
implementing most of the necessary functionality straightforward. For 
example, there are classes that allow files in a ZIP archive to be 
updated or replaced in-situ and classes that implement
 all of the necessary cryptographic operations. The only “unexpected” 
difficulty is the manipulation or conversion of binary property list 
files: an
authorative specification of this format is difficult to find.
