This page will act as a brain dump and collaborative design document for implementation of package signing in pacman.
- 1 Aim
- 2 Why sign packages?
- 3 Currently implemented signing functionality in pacman and associated tools
- 4 How Arch will implement package signing
- 5 Course of action
- 5.1 Requirements
- 5.2 Additional Features
- 6 How signing is implemented in other distributions
- 7 Ideas
- 8 pacman internals
- 9 Links
Implement package signing in pacman.
Why sign packages?
Because it makes it significantly more difficult for an attacker to cause you to install malicious packages.
Currently implemented signing functionality in pacman and associated tools
- Template:Codeline can sign a package
- Template:Codeline can add said signature to the database and sign the database
- Template:Codeline exists for the sake of managing keys, but there is missing functionality
- Template:Codeline can verify package signatures from repos, detached (.asc) package signatures, and signatures of the repos themselves
How Arch will implement package signing
- Packages will be signed using Template:Codeline. This creates a detached binary signature (.sig).
- The signed package will be added to the repository, and a detached signature of the repository will be generated (currently binary/.sig but ASCII/.asc would be better), using Template:Codeline. The command line options indicate that the signature of the old database will be verified, and that the new database will be signed. Independently of these options, Template:Codeline will detect the detached signature, convert it to ASCII, and add it to the repository.
- Template:Codeline will download both the databases and the database signatures and verify the databases upon database sync. Upon package install, it will use the signature in the database to verify a new package
Course of action
These are the changes that need to be made before Arch can implement package signing.
The pacman-keyring package, which will contain the developers' keys, must be created. Kerrick will do this.
key creation wiki page
The DeveloperWiki page for key creation must be finalized. Several developers and now Kerrick are working on this; feel free to contribute.
key creation, submission and verification
Solely the responsibility of the developers. This page gives the current progress.
Initially, pacman will install new packages from repositories as long as their SHA256 hash is given in a signed database, and give a warning if the database is unsigned. Later, pacman will abort if the database is unsigned. Further on, pacman will issue a warning for each package that is not individually signed. Finally, pacman will abort installation of unsigned packages from repositories. A configuration should be generated for at least the first case. There is currently discussion on verification levels going on on the mailing list.
pactests must be written for all signing functionality. This is a big issue; if you would like to contribute, this is a good place to do so.
Documentation for the new features must be reviewed and finalized.
These are important but non-essential features that should be added soon after package signing is implemented. Work on these issues can start now, but priority should be given to the "requirements" above.
package validation without root privileges
Currently, pacman's GnuPG home directory (aka gpgdir, typically /etc/pacman.d/gnupg/) must be locked in order to check a package's signature. Only root can perform this locking, so either locking must be disabled for read-only accesses, or the directory must be copied/linked to a writable location when a user is performing package verification.
timeline for increasing security
A timeline for transitioning between the stages listed in "transitory configuration" must be made. This is the responsibility of the devs; it'll most likely end up being played by ear.
secure ISO downloads
The page that hosts ISOs must be changed to use HTTPS. Updated versions of these ISOs containing the package signing features must be created and uploaded. Again, mostly the responsibility of the devs.
Allan's TODO list
Allan has a TODO list with further needed features at his page.
How signing is implemented in other distributions
Frugalware uses a fork of pacman which implements package signing (verify)
Arch based distro gnuffy uses signed packages with their custom package manager Spaceman modeled on pacman.
Binary packages (.deb)
To sum up, the GPG signature is included in the .deb.
Regular non signed binary packages are "ar" archives of at least 3 files:
- data.tar.gz (files to be installed)
- control.tar.gz (package metadata)
- debian-binary (contains the version of the deb format)
Signed packages also have a _gpgorigin file at the root of the .deb that is a "gpg -abs" of the concatenation of the 3 laters (as explained here):
cat debian-binary control.tar.gz data.tar.gz > /tmp/combined-contents gpg -abs -o _gpgorigin /tmp/combined-contents (-a "Create ASCII armored output" ; -b "detach signature" ; -s "sign")
Original files are provided on the repo like this acpid_2.0.4.orig.tar.gz with diff if necessary (acpid_2.0.4-1.diff.gz). A description file containing MD5sums of the orig.tar.gz and diff.gz is written and signed using GPG and uploaded along these.
- Signature type: GPG
- Stored: in the RPM
A RPM package is a tarball of installed files to which is added a header made up of metadata (name of package, version, ...). This metadata can contain a GPG signature of the tarball. See the file format specification for details.
NB: packages built for the RedHat Network are signed with the RedHat official key(s) but technically a RPM can be signed using any other key (one can even add another signature to the RPM)
To check a package correction, one must first import the signer's key first: Example for RedHat
rpm --import /usr/share/doc/rpm-4.1/RPM-GPG-KEY
And can then check signature manually:
$ rpm -K openldap-clients-2.3.43-4.x86_64.rpm openldap-clients-2.3.43-4.x86_64.rpm: sha1 md5 OK
And even fully check the package (MD5):
$ rpm -Kv openldap-clients-2.3.43-4.x86_64.rpm openldap-clients-2.3.43-4.x86_64.rpm: SHA1 header hash: OK (65999383ad859be0ce337aee4c1f6bd049ebe4a0) MD5 sum: OK (4be23a341d23b794d08fbee35c459c83)
Option --nogpg prevents rpm from checking GPG signatures
- Enable Official Distribution package signature but also enables personal and multiple signatures
- Implies complicated package format with header containing signature of an inner tarball (not very KISS)
- Space greedy on repos
For each package, a small description file containing the SHA sum of the package is created. That file is then signed using gpg (.dsc) and uploaded within the same folder as the package:
gpg --clearsign description_of_package
- Space greedy (2 files for 1 package)
SSL key chain
Seems to be the solution used by a lot of distributions
Every packager uses his own GPG key to sign the pkg.tar.gz file. Each Arch installation needs an initial database with the GPG keys. Pacman downloads the pkg.tar.gz and checks the signature.
Package file format
- packages are Template:Filename by default, but some are Template:Filename. See this news article for further details. Extract with Template:Codeline
- within the archive, the location of a file gives the installation location (relative to /): extracting a package to / installs it
- there are two hidden files in the archive's / directory:
- Template:Filename is a text file with package metadata. It is generated using information in the Template:Filename. It is used to generate the Template:Filename file, which goes in the sync database
- Template:Filename is an optional shell script that can define functions that are called after install, upgrade, or remove operations. It is placed in the same directory as the Template:Filename when building (e.g. Template:Filename) and is named inside the Template:Filename with Template:Codeline. It is stored in the local database after the package is installed
- installed packages are cached in Template:Filename
- further information at Creating Packages
Database file format
- there are two database types: the local database (stored at Template:Filename) and the sync databases (stored in Template:Filename)
- there is one sync database per repository
- the sync databases are .tar.gz format but have a .db file extension
- each sync database has a directory for each package. Each directory contains the files Template:Filename and Template:Filename, which give dependencies and metadata, respectively
- the Template:Filename file contains the MD5sum and optionally the signature
- the local database has a directory for each installed package, which contains the files Template:Filename, a rearranged version of the sync db's Template:Filename that omits some information like the MD5sum; Template:Filename, which lists the files comprising the package; and optionally Template:Filename, a copy of Template:Filename
- there is one sync database per repository
Mailing list discussions and patches
- Add Keyring option in alpm/pacman
- Package signing again
- PATCH (newgpg) Let pacman specify GnuPG's home directory.
- Dan's pacman tree build&test
- GPG work
- GPG signature option in makepkg patch
- GPG signature support for makepkg
- GPG signature option in makepkg, adapted to Dan McGee's suggestions patch
- GPG verification patch
- GPGSIG in repo-add patch
- Signing by default
- Package Database signing
- Pointless to use non-md5 for makepkg INTEGRITY_CHECK
- Can we trust our mirrors
- Multiple/Shared Architectures