Cross-platform interface for code signing.
This crate implements functionality for performing code signing in a platform-agnostic manner. It attempts to abstract over platform differences so users don’t care what platform they are running on or what type of entity they are signing. It achieves varying levels of success, depending on limitations of underlying crates.
SigningCertificate represents a code signing certificate (logically a private key + a public X.509 certificate). Instances are constructed with a reference to a code signing certificate in one of the enumerated supported locations.
SigningCertificate are converted into Signer, which is a slightly broader scoped entity. Signer holds additional attributes beyond the SigningCertificate, such as a list of issuing CapturedX509Certificate constituting the certificate chain and a Time-Stamp Protocol server URL to use.
SignableCandidate represents the different potential data types that can be signed. e.g. a filesystem path or slice of data.
Signer exposes a concrete test for whether a SignableCandidate is signable, via Signer::resolve_signability. The test relies on heuristics in the supported signing backends (e.g. tugger_apple_codesign and tugger_windows_codesign) as well as Signer specific state to determine if an entity is signable. False positives and negatives are possible: please report bugs! If an entity is signable, it will be converted to a Signable instance.
To sign a Signable, you need to obtain a SignableSigner.
You can do this by calling Signer::resolve_signer. This function performs
signability checks internally and returns
None if unsignable entities are
seen. So most consumers with an intent to sign should call this without
calling Signer::resolve_signability to avoid a potentially expensive
double signability test.
SignableSigner are associated with a Signer and Signable and are used for signing just a single entity. SignableSigner instances are guaranteed to be capable of signing a Signable. However, signing operations support specifying writing the signed results to multiple types of destinations, as specified via SigningDestination, and not every destination is supported by every input or signing backend. So before attempting signing, it is a good idea to call [SignableSigner.destination_compatibility] and verify that writing to a specific SigningDestination is supported!
SignableSigner instances can further be customized to influence signing settings. See its documentation for available settings. For power users, callback functions can be registered on Signer instances to allow customization of the low-level signing primitives used for signing individual Signable. See Signer::apple_settings_callback and Signer::windows_settings_callback.
Finally, a signing operation can be performed via SignableSigner::sign. This hides away all the complexity of mapping different signable entities to different signing backends and gives you a relatively clean interface to attempt code signing. If signing was successful, you’ll get a SignedOutput describing where the signed content lives.
A single invocation of a signing operation.
An entity for performing code signing.
Represents different methods of signing that are supported.
Represents the results of a signability test.
Represents a known, typed entity which is signable.
Represents an entity that is a candidate for signing.
Describes the output of a successful signing operation.
Represents a signing key and public certificate to sign something.
Represents a location where signed data should be written.
Describes capability of signing some entity to a SigningDestination.
Represents a signing error.
Represents how an entity can be signed.
URL of Apple’s time-stamp protocol server.
Resolve signability information given a data slice.
Resolve signability information given an input path.
A callback for influencing the creation of [tugger_apple_codesign.SigngingSettings] instances for a given Signable.