17 breaking releases

0.18.0 Jan 17, 2024
0.17.0 Nov 17, 2023
0.16.0 Nov 15, 2023
0.13.0 Dec 21, 2022
0.2.0 Mar 28, 2022

#179 in macOS and iOS APIs

Download history 1031/week @ 2023-12-14 802/week @ 2023-12-21 819/week @ 2023-12-28 945/week @ 2024-01-04 1188/week @ 2024-01-11 1139/week @ 2024-01-18 1224/week @ 2024-01-25 997/week @ 2024-02-01 1136/week @ 2024-02-08 1141/week @ 2024-02-15 1342/week @ 2024-02-22 1251/week @ 2024-02-29 1390/week @ 2024-03-07 1532/week @ 2024-03-14 1821/week @ 2024-03-21 1599/week @ 2024-03-28

6,532 downloads per month
Used in 15 crates (via apple-codesign)

MPL-2.0 license

120KB
2.5K SLoC

apple-flat-package

This crate implements an interface to Apple's flat package installer package file format. This is the XAR-based installer package (.pkg) format used since macOS 10.5.

The interface is in pure Rust and doesn't require the use of Apple specific tools or hardware to run. The functionality in this crate could be used to reimplement Apple installer tools like pkgbuild and productbuild.


lib.rs:

Apple flat packages.

Apple flat packages - often existing as .pkg files - are an installer file format used by macOS.

File Format

Flat packages are Apple-flavored XAR archives. XAR is a tar-like file format consisting of file records/metadata and raw file data. See the apple-xar crate for more on this file format.

Flat packages come in 2 flavors: component packages and product packages. Component packages contain a single component. Product installers can contain multiple components as well as additional metadata describing the installer. End-user .pkg files are typically product packages. Using Apple tooling, component packages are built using pkgbuild and product packages using productbuild.

Components

A component defines an installable unit. Components are comprised of a set of well-known files:

Bom A bill of materials describing the contents of the component. PackageInfo An XML file describing the component. See [PackageInfo] for the Rust struct defining this file format. Payload A cpio archive containing files comprising the component. See the cpio-archive for more on this file format. Scripts A cpio archive containing scripts files that run as part of component processing.

Products

A product flat package consists of 1 or more components and additional metadata.

A product flat package is identified by the presence of a Distribution XML file in the root of the archive. See [Distribution] for the Rust type defining this file format. See also Apple's XML documentation.

Components within a product flat package exist in sub-directories which often have the name *.pkg/.

In addition, a product flat package may also have additional resource files in the Resources/ directory.

Cryptographic Signing

Cryptographic message syntax (CMS) / RFC 5652 signatures can be embedded in the XAR archive's table of contents, which is a data structure at the beginning of the XAR defining the content within.

The cryptographic signature is over the checksum content digest, which is also captured in the XAR table of contents. This checksum effectively captures the content of all files within the XAR.

Nested Archive Formats

Flat packages contain multiple data structures that effectively enumerate lists of files. There are many layers to the onion and there is duplication of functionality to express file manifests.

  • XAR archives contain a table of contents enumerating files within the XAR.
  • Each component has Payload and/or Scripts files, which are cpio archives. These cpio archives are file manifests containing file metadata and content.
  • Each component may have a Bom, which is a binary data structure defining file metadata as well as other attributes.

There are also multiple layers that involve compression:

  • The XAR table of contents is likely compressed with zlib.
  • Individual files within XAR archives can be individually compressed with a compression format denoted by a MIME type.
  • cpio archive files may also be compressed.
  • Installed files in components may also be compressed (but this file content is treated as opaque by the flat package format).

Dependencies

~13–24MB
~441K SLoC