Add keyringctl as tooling for a curated keyring
This implements a keyringctl
command (fronting sq
) that can be used to convert the current set of PGP certificates to a more specific directory structure (see #6 (closed) for details):
Workflow (for testing)
# convert current setup
./keyringctl -v import --main master master-revoked
./keyringctl -v import packager packager-revoked
The tool allows for exporting the combined PGP packets to a file, that can be used as a pacman keyring:
# export converted certificate layout to a keyring file and export ownertrust and revoker status
./keyringctl -v build
(Future) Workflow
# update an existing main public key (and e.g. its signatures)
./keyringctl -v import --main <some_file>.gpg
# update an existing packager public key (and e.g. its signatures)
./keyringctl -v import <some_file>.gpg
Currently it is untested whether
- the conversion exports all relevant PGP packets from the existing certificates
- the export creates a functioning file that can be used as a pacman keyring
- the revoker status can be improved (to not have to rely on a separate file)
NOTE: Currently it is not yet possible to create a deterministic keyring using sq keyring merge
: https://gitlab.com/sequoia-pgp/sequoia/-/issues/762
TODO
-
update README.md to reflect changes and explain new workflow -
derive username by matching against existing public key fingerprints in the target directory (to not simply rely on input certificate name) -
filter out any certifications that are not done by main or packager public keys -
simplify the command-line interface (e.g. import-packager
,import-main
,export-packager
,export-main
,export-keyring
) -
add gitlab CI integration to create keyring files, import them with pacman-key and use them -
standardize directory naming (e.g. uids
->uid
,subkeys
->subkey
) -
check new keys to match our requirements (as is currently done in CI) -
Allow
Related to #6 (closed)
Merge request reports
Activity
requested review from @eworm, @diabonas, and @grazzolini
assigned to @dvzrv
added 1 commit
- 491398d9 - keyringctl: Add writing to keyring output file
- Resolved by David Runge
- Resolved by David Runge
This mostly LGTM so far! The currently implemented functionality works fine with the current Arch Linux keyring according to my (somewhat limited) testing.
Some comments regarding the proposed directory structure (#6 (comment 36606)):
- The structure generally looks sane and seems to preserve most of the the relevant information, the exception being subkey revocations, which are currently not handled at all.
- I really like the fact that this allows to audit what part of a key changed with an update instead of only seeing one big binary/ASCII-armoured blob changed. This should also make it easier to implement automated tests to make sure people don't accidentally make keys unusable e.g. by removing master key signatures during an update.
- In this regard it might be interesting to split up the
<username>/<main_fingerprint>/<main_fingerprint>.asc
even further into one user ID per file<username>/<main_fingerprint>/<simplified_user_id>/<main_fingerprint>.asc
. This would make the semi-frequent act of adding a new user ID somewhat more transparent. - Similarly, one could imagine splitting up
<username>/<main_fingerprint>/<main_fingerprint>.asc
into<username>/<main_fingerprint>/<subkey_fingerprint>/<subkey_fingerprint>.asc
for every subkey. This would allow capturing subkey revocations (currently not implemented at all, see above) in a more transparent way, by storing them in<username>/<main_fingerprint>/<subkey_fingerprint>/revocation/
(like it is already done for user IDs). - Both of the above suggestions are entirely optional, but seem to be in the spirit of making the status of a key clearer just by looking at the directory structure and extend this notion to user IDs and subkeys.
- Adding signatures is an "append-only" process, which is great for automatic verification. (The same would be true for adding user IDs and subkeys if the above suggestions were implemented.) Revoking signatures is not, as revoked signatures are removed from the
certification/
subdirectory and the revocation signature is added to therevocation/
subdirectory instead. I found this a little confusing at first, as I would have expected the old signature to stay incertification/
and the new signature revocation to be added torevocation/
. Not sure whether this is better though, having only valid, unrevoked signatures incertification/
seems to be nice as well.
Are there any plans for the user-facing tooling regarding the upload of new keys and signatures yet? I think having a dedicated command for splitting a single key (e.g. piped from
gpg --export <fingerprint>
) would be nice to make it easier for users to create merge requests with the correct directory structure. The command would be mostly identical to the existingconvert
command, just specifically geared towards a single key instead of a whole keyring.The directory structure should also make it pretty easy to run a pipeline for each merge request to check that users don't accidentally e.g. remove master key signatures to make their resulting key invalid, or modify other users' keys. This is probably out of scope for the current MR though.
added 1 commit
- 34b1389d - keyringctl: Split out subkeys to separate structure
added 1 commit
- 9facd662 - keyringctl: Write User IDs to separate files
added 1 commit
- 0bbfa7d0 - keyringctl: Implement export of ownertrust/ revoker status
- Resolved by Levente Polyak
With 0bbfa7d0 I have implemented the export of ownertrust and revoker status (the initial comment to this MR has been altered to reflect this).
Unfortunately, the latter (now solely relying on the layout of the new key directory and still being somewhat naive) revealed some issues that need to be addressed outside of this MR. To identify revoked keys we can rely on self-revocations (this is working) and those done by one of the main keys (this is complicated).
The previous approach relied on manual file additions to provide a hardcoded list of revoked keys (e.g. master-revoked-keyids and packager-revoked-keyids).
In the new approach we currently naively assume that if a public key has more than two revocations by main keys on any of its UIDs, it counts as being revoked (ends up in the revoker file). This is not ideal yet and needs to be improved!
Comparing this to the current list of revoked keys reveals a discrepancy though. The following keys have less than two revocations by main keys (past or present) and are therefore not in the list when exporting the keyring:
- 4FCF887689C41B09506BE8D5F3E1D5C5D30DB0AD
- 717026A9D4779FC53940726640F557B731496106
- 8CF934E339CAD8ABF342E822E711306E3C4F88BC
- D4DE5ABDE2A7287644EAC7E36D1A9E70E19DAA50
- DBE7D3DD8C81D58D0A13D0E76BC26A17B9B7018A
- F648622B1715468FD654F45CB7310AE5F04569AE
added 1 commit
- deca66fc - keyringctl: Add documentation to all functions