apple_codesign/
lib.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Binary code signing for Apple platforms.
6//!
7//! This crate implements application code signing for Apple operating systems
8//! (like macOS and iOS). A goal of this crate is to serve as a stand-in
9//! replacement for Apple's `codesign` (and similar tools) without a dependency
10//! on an Apple hardware device or operating system: you should be able to
11//! sign and release Apple binaries from Linux, Windows, or other non-Apple
12//! environments if you want to.
13//!
14//! Apple code signing is complex and there are likely several areas where
15//! this crate and Apple's implementations don't align. It is highly recommended
16//! to validate output against what Apple's official tools produce.
17//!
18//! # Features and Capabilities
19//!
20//! This crate can:
21//!
22//! * Find code signature data embedded in Mach-O binaries (both single and
23//!   multi-arch/fat/universal binaries). (See [MachOBinary] struct.)
24//! * Deeply parse code signature data into Rust structs. (See
25//!   [EmbeddedSignature], [BlobData], and e.g. [CodeDirectoryBlob].
26//! * Parse and verify the RFC 5652 Cryptographic Message Syntax (CMS)
27//!   signature data. This includes using a Time-Stamp Protocol (TSP) / RFC 3161
28//!   server for including a signed time-stamp token for that signature.
29//!   (Functionality provided by the `cryptographic-message-syntax` crate,
30//!   developed in the same repository as this crate.)
31//! * Generate new embedded signature data, including cryptographically
32//!   signing that data using any signing key and X.509 certificate chain
33//!   you provide. (See [MachOSigner] and [BundleSigner].)
34//! * Writing a new Mach-O file containing new signature data. (See
35//!   [MachOSigner].)
36//! * Parse `CodeResources` XML plist files defining information on nested/signed
37//!   resources within bundles. This includes parsing and applying the filtering
38//!   rules defining in these files.
39//! * Sign bundles. Nested bundles will automatically be signed. Additional
40//!   Mach-O binaries outside the main executable will also be signed. Non
41//!   Mach-O/code files will be digested. A `CodeResources` XML file will be
42//!   produced.
43//! * Submit notarization requests to Apple and query notarization status. (Bundles,
44//!   DMGs, and `.pkg` installers are all supported.)
45//! * Retrieve notarization tickets from Apple and staple. All formats supporting
46//!   notarization can be stapled.
47//!
48//! There are a number of missing features and capabilities from this crate
49//! that we hope are eventually implemented:
50//!
51//! * No parsing of the Code Signing Requirements DSL. We support parsing the binary
52//!   requirements to Rust structs, serializing back to binary, and rendering to the
53//!   human friendly DSL. You will need to use the `csreq` tool to compile an
54//!   expression to binary and then give that binary blob to this crate. Alternatively,
55//!   you can write Rust code to construct a code requirements expression and serialize
56//!   that to binary.
57//! * No turnkey support for signing keys. We want to make it easier for obtaining
58//!   signing keys (and their X.509 certificate chain) for use with this crate. It
59//!   should be possible to easily integrate with the OS's key store or hardware
60//!   based stores (such as Yubikeys). We also don't look for necessary X.509
61//!   certificate extensions that Apple's verification likely mandates, which we should
62//!   do and enforce.
63//! * Some more advanced bundles or `.pkg` files may not sign, notarize, or staple
64//!   correctly. Problems here are considered bugs and should be reported.
65//!
66//! There is missing features and functionality that will likely never be implemented:
67//!
68//! * Binary verification compliant with Apple's operating systems. We are capable
69//!   of verifying the digests of code and other embedded signature data. We can also
70//!   verify that a cryptographic signature came from the annotated public key in
71//!   that signature. We can also write heuristics to look for certain common problems
72//!   with signatures. But we can't and likely never will implement all the rules Apple
73//!   uses to verify a binary for execution because we perceive there to be little
74//!   value in doing this. This crate could be used to build such functionality
75//!   elsewhere, however.
76//!
77//! # End-User Documentation
78//!
79//! The end-user documentation is maintained as a Sphinx docs tree in the `docs`
80//! directory. The latest version of the documentation is published at
81//! <https://gregoryszorc.com/docs/apple-codesign/main/>.
82//!
83//! # Getting Started
84//!
85//! The [UnifiedSigner] type is a good place to start to see how the high level API for
86//! signing is implemented.
87//!
88//! To learn about the low-level data structures in embedded code signatures, read
89//! [specification]. Or look at the code in [embedded_signature] and
90//! [embedded_signature_builder].
91//!
92//! [MachOSigner] is the type responsible for signing Mach-O files.
93//!
94//! [BundleSigner] is the type responsible for signing bundles.
95//!
96//! [dmg::DmgSigner] signs DMG files.
97//!
98//! The [EmbeddedSignature] represents a parsed Apple code signature and provides API
99//! for data retrieval.
100//!
101//! # Accessing Apple Code Signing Certificates
102//!
103//! This crate doesn't yet support integrating with the macOS keychain to obtain
104//! or use the code signing certificate private key. However, it does support
105//! importing the certificate key from a `.p12` file exported from the `Keychain
106//! Access` application. It also supports exporting the x509 certificate chain
107//! for a given certificate by speaking directly to the macOS keychain APIs.
108//!
109//! See the `keychain-export-certificate-chain` CLI command for exporting a
110//! code signing certificate's x509 chain as PEM.
111
112mod apple_certificates;
113pub use apple_certificates::*;
114mod bundle_signing;
115pub use bundle_signing::*;
116mod certificate;
117pub use certificate::*;
118pub mod cli;
119mod code_directory;
120pub use code_directory::*;
121pub mod code_requirement;
122pub use code_requirement::*;
123mod code_resources;
124pub use code_resources::*;
125pub mod cryptography;
126pub mod dmg;
127pub mod embedded_signature;
128pub use embedded_signature::*;
129pub mod embedded_signature_builder;
130pub use embedded_signature_builder::*;
131pub mod entitlements;
132pub mod environment_constraints;
133mod error;
134pub use error::*;
135mod macho;
136pub use macho::*;
137pub mod macho_builder;
138#[cfg(target_os = "macos")]
139#[allow(non_upper_case_globals)]
140mod macos;
141#[cfg(target_os = "macos")]
142pub use macos::*;
143mod macho_signing;
144pub use macho_signing::*;
145mod macho_universal;
146pub use macho_universal::UniversalBinaryBuilder;
147#[cfg(feature = "notarize")]
148pub mod notarization;
149#[cfg(feature = "notarize")]
150pub use notarization::*;
151pub mod plist_der;
152mod policy;
153pub use policy::*;
154mod reader;
155pub use reader::*;
156pub mod remote_signing;
157mod signing_settings;
158pub use signing_settings::*;
159mod signing;
160pub use signing::*;
161pub mod specification;
162pub mod stapling;
163pub mod ticket_lookup;
164mod verify;
165pub use verify::*;
166#[cfg(target_os = "windows")]
167pub mod windows;
168#[cfg(feature = "yubikey")]
169pub mod yubikey;