Subject: [bug#77667] guix-install.sh: Check fingerprint of downloaded PGP keys before importing

From: Scott Tankard <[email-masked]>
Date: Tue, 8 Apr 2025 19:30:00 -0700

Hello,

First of all, a thank you to all those who make Guix.

Attached is a patch for etc/guix-install.sh. With this patch, the script
checks the fingerprint of the downloaded PGP keyfiles, before importing
them.

This patch is a rough draft. (This is not yet an actual patch submission.)
The patch is against commit 6a2a78fde19683f07c8b10f492cda67447bc99eb or
similar:
https://git.savannah.gnu.org/cgit/guix.git/tree/etc/guix-install.sh?id=6a2a78fde19683f07c8b10f492cda67447bc99eb

## Background

I noticed that while the script does already include hardcoded PGP
fingerprints, it does not use those fingerprints to check that downloaded
keyfiles are correct before importing them.

In current implementation: The fingerprints are only used to check whether
keys are already present in keyring. If keys are not present, they are
downloaded from savannah.gnu.org and directly imported, without checking
the fingerprints. This means that if for any reason an incorrect keyfile is
received from the server (for example, if the server is compromised), then
the incorrect key will be imported.

The script guix-install.sh effectively serves as a root of trust for
bootstrapping the installation. With this patch, it can do so more
reliably.

This also means that for example, a user can pin the guix-install.sh file
by checksum, and rely on that checksum to ensure integrity of the entire
guix installation and all packages. (Of course, this is assuming there are
no other breaks in the chain further on.) Cf. also a prior issue (
https://issues.guix.gnu.org/34125) that mentioned securing the install
script with a gpg signature... pinning by checksum seems more versatile for
certain contexts.

## Implementation details

The patch adds two new functions:
get_gpg_fpr_of_keyfile
import_key

It also includes modifications to two functions:
chk_gpg_keyring
main

The current implementation of get_gpg_fpr_of_keyfile() includes some
unsightly grep regexes. It could be made simpler by using awk -- this would
mean adding awk into REQUIRES. If that's acceptable, I can submit a revised
patch.

## Additional notes

I have tested this patch ad-hoc/manually. I didn't find any automated tests
for guix-install.sh, but let me know if I missed them.

I am unsure of whether it is possible for a malicious keyfile to spoof its
fingerprint, whether gpg can be trusted to accurately report a keyfile's
fingerprint, and for what versions of GPG. I haven't looked into it. In any
case, checking seems better than not checking.

In case someone suggests just completely changing to `gpg --recv-keys`
instead... I think the combination of download from URL + verify
fingerprint is superior, in that it includes two verification factors, one
of which (the URL) is actually human-readable.