Expand description
Binary code signing for Apple platforms.
This crate implements application code signing for Apple operating systems
(like macOS and iOS). A goal of this crate is to serve as a stand-in
replacement for Apple’s codesign
(and similar tools) without a dependency
on an Apple hardware device or operating system: you should be able to
sign and release Apple binaries from Linux, Windows, or other non-Apple
environments if you want to.
Apple code signing is complex and there are likely several areas where this crate and Apple’s implementations don’t align. It is highly recommended to validate output against what Apple’s official tools produce.
§Features and Capabilities
This crate can:
- Find code signature data embedded in Mach-O binaries (both single and multi-arch/fat/universal binaries). (See MachOBinary struct.)
- Deeply parse code signature data into Rust structs. (See EmbeddedSignature, BlobData, and e.g. CodeDirectoryBlob.
- Parse and verify the RFC 5652 Cryptographic Message Syntax (CMS)
signature data. This includes using a Time-Stamp Protocol (TSP) / RFC 3161
server for including a signed time-stamp token for that signature.
(Functionality provided by the
cryptographic-message-syntax
crate, developed in the same repository as this crate.) - Generate new embedded signature data, including cryptographically signing that data using any signing key and X.509 certificate chain you provide. (See MachOSigner and BundleSigner.)
- Writing a new Mach-O file containing new signature data. (See MachOSigner.)
- Parse
CodeResources
XML plist files defining information on nested/signed resources within bundles. This includes parsing and applying the filtering rules defining in these files. - Sign bundles. Nested bundles will automatically be signed. Additional
Mach-O binaries outside the main executable will also be signed. Non
Mach-O/code files will be digested. A
CodeResources
XML file will be produced. - Submit notarization requests to Apple and query notarization status. (Bundles,
DMGs, and
.pkg
installers are all supported.) - Retrieve notarization tickets from Apple and staple. All formats supporting notarization can be stapled.
There are a number of missing features and capabilities from this crate that we hope are eventually implemented:
- No parsing of the Code Signing Requirements DSL. We support parsing the binary
requirements to Rust structs, serializing back to binary, and rendering to the
human friendly DSL. You will need to use the
csreq
tool to compile an expression to binary and then give that binary blob to this crate. Alternatively, you can write Rust code to construct a code requirements expression and serialize that to binary. - No turnkey support for signing keys. We want to make it easier for obtaining signing keys (and their X.509 certificate chain) for use with this crate. It should be possible to easily integrate with the OS’s key store or hardware based stores (such as Yubikeys). We also don’t look for necessary X.509 certificate extensions that Apple’s verification likely mandates, which we should do and enforce.
- Some more advanced bundles or
.pkg
files may not sign, notarize, or staple correctly. Problems here are considered bugs and should be reported.
There is missing features and functionality that will likely never be implemented:
- Binary verification compliant with Apple’s operating systems. We are capable of verifying the digests of code and other embedded signature data. We can also verify that a cryptographic signature came from the annotated public key in that signature. We can also write heuristics to look for certain common problems with signatures. But we can’t and likely never will implement all the rules Apple uses to verify a binary for execution because we perceive there to be little value in doing this. This crate could be used to build such functionality elsewhere, however.
§End-User Documentation
The end-user documentation is maintained as a Sphinx docs tree in the docs
directory. The latest version of the documentation is published at
https://gregoryszorc.com/docs/apple-codesign/main/.
§Getting Started
The UnifiedSigner type is a good place to start to see how the high level API for signing is implemented.
To learn about the low-level data structures in embedded code signatures, read specification. Or look at the code in embedded_signature and embedded_signature_builder.
MachOSigner is the type responsible for signing Mach-O files.
BundleSigner is the type responsible for signing bundles.
dmg::DmgSigner signs DMG files.
The EmbeddedSignature represents a parsed Apple code signature and provides API for data retrieval.
§Accessing Apple Code Signing Certificates
This crate doesn’t yet support integrating with the macOS keychain to obtain
or use the code signing certificate private key. However, it does support
importing the certificate key from a .p12
file exported from the Keychain Access
application. It also supports exporting the x509 certificate chain
for a given certificate by speaking directly to the macOS keychain APIs.
See the keychain-export-certificate-chain
CLI command for exporting a
code signing certificate’s x509 chain as PEM.
Re-exports§
pub use code_requirement::*;
pub use embedded_signature::*;
pub use embedded_signature_builder::*;
pub use notarization::*;
Modules§
- cli
- code_
requirement - Code requirement language primitives.
- cryptography
- Common cryptography primitives.
- dmg
- DMG file handling.
- embedded_
signature - Common embedded signature data structures (superblobs, magic values, etc).
- embedded_
signature_ builder - Provides primitives for constructing embeddable signature data structures.
- entitlements
- Code entitlements handling.
- environment_
constraints - Launch constraints and library constraints.
- macho_
builder - Mach-O writing.
- notarization
- Apple notarization functionality.
- plist_
der - Plist DER encoding.
- remote_
signing - Remote signing support.
- specification
- Apple code signing technical specifications
- stapling
- Attach Apple notarization tickets to signed entities.
- ticket_
lookup - Support for retrieving notarization tickets and stapling artifacts.
Structs§
- Blob
Description - Build
Version Command - Content of an
LC_BUILD_VERSION
load command. - Bundle
Signer - A primitive for signing an Apple bundle.
- Bundle
Signing Context - Holds state and helper methods to facilitate signing a bundle.
- Bundle
Signing Info - Holds metadata describing the result of a bundle signing operation.
- Certificate
Info - CmsSignature
- High-level representation of a CMS signature.
- CmsSigner
- Code
Directory - Code
Directory Blob - Represents a code directory blob entry.
- Code
Resources - Represents a
_CodeSignature/CodeResources
XML plist. - Code
Resources Builder - Interface for constructing a
CodeResources
instance. - Code
Resources Rule - Represents an abstract rule in a
CodeResources
XML plist. - Code
Signature - High level representation of a code signature.
- Code
Signature Flags - Code signature flags.
- DmgEntity
- Executable
Segment Flags - Flags that influence behavior of executable segment.
- File
Entity - Mach
File - Represents a semi-parsed Mach[-O] binary.
- MachO
Binary - A Mach-O binary.
- MachO
Entity - MachO
Signature Data - Describes signature data embedded within a Mach-O binary.
- MachO
Signer - Mach-O binary signer.
- Macho
Target - Targeting settings for a Mach-O binary.
- Scatter
- Signed
MachO Info - Metadata about a signed Mach-O file or bundle.
- Signing
Settings - Represents code signing settings.
- Single
Bundle Signer - A primitive for signing a single Apple bundle.
- Unified
Signer - An entity for performing signing that is able to handle all supported target types.
- Universal
Binary Builder - Interface for constructing a universal Mach-O binary.
- Verification
Context - Context for a verification issue.
- Verification
Problem - XarFile
- XarSignature
- XarTable
OfContents
Enums§
- Apple
Codesign Error - Unified error type for Apple code signing.
- Certificate
Authority Extension - Denotes specific certificate extensions on Apple certificate authority certificates.
- Certificate
Profile - Describes combinations of certificate extensions for Apple code signing certificates.
- Code
Directory Version - Version of Code Directory data structure.
- Code
Signature File - Code
Signing Certificate Extension - Describes one of the many X.509 certificate extensions found on Apple code signing certificates.
- Designated
Requirement Mode - Describes how to derive designated requirements during signing.
- Execution
Policy - Defines well-known execution policies for signed code.
- Extended
KeyUsage Purpose - Describes the type of code signing that a certificate is authorized to perform.
- Files
Flavor - Which files section we are operating on and how to digest.
- Known
Certificate - Defines all known Apple certificates.
- Path
Type - Describes the type of entity at a path.
- Platform
- Represents
PLATFORM_
mach-o constants. - Scoped
Setting - Describes the type of a scoped setting.
- Settings
Scope - Denotes the scope for a setting.
- Signature
Entity - Signature
Reader - Entity for reading Apple code signature data.
- Verification
Problem Type - Describes a problem with verification.
Constants§
- OID_
USER_ ID - UserID.
Traits§
- Apple
Certificate - Extends functionality of CapturedX509Certificate with Apple specific certificate knowledge.
- Apple
Certificate Builder - Extensions to X509CertificateBuilder specializing in Apple certificate behavior.
Functions§
- copy_
bundle - Copy a bundle’s contents to a destination directory.
- create_
self_ signed_ code_ signing_ certificate - Create a new self-signed X.509 certificate suitable for signing code.
- derive_
designated_ requirements - Derive a designated requirements expression given a code signing certificate.
- developer_
id_ signed_ expression - Derive a code requirements expression for a Developer ID issued certificate.
- non_
apple_ signed_ expression - Derive the requirements expression for non Apple signed certificates.
- normalized_
resources_ path - Convert a relative filesystem path to its
CodeResources
normalized form. - parse_
version_ nibbles - Parses and integer with nibbles xxxx.yy.zz into a semver::Version.
- path_
identifier - path_
is_ macho - Whether the specified filesystem path is a Mach-O binary.
- path_
is_ xar - Test whether a given path is likely a XAR file.
- path_
is_ zip - Test whether a given path is likely a ZIP file.
- semver_
to_ macho_ target_ version - Convert a semver::Version to a u32 with nibble encoding used by Mach-O.
- verify_
macho - Verifies a parsed Mach-O binary.
- verify_
macho_ data - Verifies unparsed Mach-O data.
- worldwide_
developer_ relations_ signed_ expression - Derive the requirements expression for a cert signed by the Worldwide Developer Relations CA.
- write_
macho_ file - Write Mach-O file content to an output file.
Type Aliases§
- Result
- Result type for this library.