Introduction
Since Package Collections (SE-0291) can be created and published by anyone, issues related to authenticity and integrity may emerge. We would like to propose signed package collections such that:
- Publishers can establish authenticity and protect their collections from tampering.
- Users can choose and consume collections based on trust guarantees and therefore help prevent package collections from being used as an attack vector.
Package collection signing is optional—publishers are not required to sign collections. Users will be warned and prompted for confirmation before they can add an unsigned collection.
Tooling will be provided, most likely an addition to the existing generator repository, for publishers to sign their collections. It will be open-sourced and cross-platform, and publishers are strongly recommended to use this tool instead of attempting their own.
Detailed Design
Sign a package collection
To generate a signature one must provide:
- The package collection (JSON) to be signed
- A code signing certificate (DER encoded)
- The certificate’s private key (PEM encoded)
- The certificate’s chain in its entirety
The tool will produce a new collection JSON file with the signature embedded:
{
// Package collection JSON
...,
// New "signature" object
"signature": {
"signature": <SIGNATURE>,
"certificate": {
"subject": {
"commonName": "Jane Doe"
},
"issuer": {
"commonName": "Sample CA"
}
}
}
}
The signature will include the certificate’s public key and chain for verification purposes.
Publish a package collection
Package collections, whether they are signed or not, must be accessible without requiring authentication, and their URLs should be HTTPS. This can be done by publishing the files to a web server or CDN-like infrastructure. Services such as GitHub.com, Amazon S3, and others also support the required features for hosting package collections.
Non-HTTPS collection URLs are allowed but will trigger user warnings similar to unsigned collections.
Verify package collection signature
If signature
is present in a package collection, SwiftPM will verify that:
- The file content (excluding
signature
) is what was used to generate the signature. In other words, this checks to see if the collection has been altered since it was signed. - The signing certificate is valid.
SwiftPM will not import a collection if there were any failures during verification.
Certificate for signing
The following is enforced during signing and verification:
- The timestamp at which signing/verification is done must fall within the signing certificate’s validity period.
- The certificate’s “Extended Key Usage” extension must include “Code Signing”.
- The certificate must use either 256-bit EC (recommended) or 2048-bit RSA key.
- The certificate must not be revoked. The certificate authority must support OCSP, which means the certificate must have the “Certificate Authority Information Access” extension that includes OCSP as a method, specifying the responder’s URL.
- The certificate chain is valid and root certificate must be trusted.
On Apple platforms, all root certificates that come preinstalled with the OS are automatically trusted. Users may specify additional certificates to trust by placing them in a directory and configure the signing tool or SwiftPM to use it. On non-Apple platforms, the signing tool and SwiftPM will only trust root certificates in the configured directory.
Non-expired, non-revoked Apple Distribution certificates from developer.apple.com satisfy all of the criteria above and can be used without further actions by collection publishers or users on Apple platforms.