[pacman-dev] [PATCH] pacman-key: rework importing distro/repo provided keyrings

Allan McRae allan at archlinux.org
Wed Aug 17 20:49:43 EDT 2011


On 18/08/11 08:48, Dan McGee wrote:
> On Mon, Aug 15, 2011 at 8:10 AM, Allan McRae<allan at archlinux.org>  wrote:
>> The current --reload option, apart from being non-clear in its naming,
>> is very limited in that only one keyring can be provided.  A distribution
>> may want to provide multiple keyrings for various subsets of its
>> organisation or custom repo providers may also want to provide a keyring.
> Interesting thought. What happens here if a key is marked as OK in
> foo.gpg, but "revoked" in bar-revoked, as might happen if someone
> changes organizations?

Yeah.. that could be interesting.  At the moment I believe revoking 
anywhere takes precedence, but I will need to double check that.  I 
think this is something that entirely undocmuented HoldKey option can be 
used for.

> Keeping arch and the TU and Dev groups in mind, you could see such a
> situation. However, I don't believe we would ever put a key in the
> revoked keyring unless we had really good reason to- this wouldn't
> just happen if someone left the dev team for instance.
>
> Not that timestamps are trustable in signatures themselves if the key
> used to sign is trusted, but is there any way to say "this key is
> valid but not if sigs using it were created after X time"? Clearly we
> can get bogged down in this but something worth thinking about.

I have absolutely no idea if that is even possible with gpg...

>> This patch adds a --populate option that reads keyrings from (by default)
>> /usr/share/pacman/keyrings.  A keyring is named foo.gpg, with optional
>> foo-revoked file providing a list of revoked key ids.  These files are
>> required to be signed (detached) by a key trusted by pacman-key, in
>> practise probably by the key that signed the package providing these
> practice
>> files. The --populate flag either updates the pacman keyring using all
>> keyrings in the directory or individual keyrings can be specified.
>>
>> Signed-off-by: Allan McRae<allan at archlinux.org>
>> ---
>>   doc/pacman-key.8.txt     |    8 ++-
>>   scripts/Makefile.am      |    1 +
>>   scripts/pacman-key.sh.in |  149 +++++++++++++++++++++++-----------------------
>>   3 files changed, 82 insertions(+), 76 deletions(-)
>>
>> diff --git a/doc/pacman-key.8.txt b/doc/pacman-key.8.txt
>> index c8ce026..98ee6f6 100644
>> --- a/doc/pacman-key.8.txt
>> +++ b/doc/pacman-key.8.txt
>> @@ -80,8 +80,12 @@ Options
>>   *-r, \--receive*<keyserver>  <keyid(s)>::
>>         Fetch the specified keyids from the specified key server URL.
>>
>> -*\--reload*::
>> -       Reloads the keys from the keyring package.
>> +*\--populate* [<keyring(s)>]::
>> +       Reload the default keys from the (given) keyrings in +{pkgdatadir}/keyrings+.
> (optionally provided) ?
>
>> +       Each keyring is provided in a file foo.gpg that contains the keys for the foo
> filenames in `foo.gpg` backticks usually is the convention.
>> +       keyring. Optionally the file foo-revoked contains a list of revoked key ids
> Optionally,<comma>
> `foo-revoked.gpg` (forgot the extension here too). Or did I
> misunderstand and this is a text file with IDs rather than an actual
> keyring file with binary data? This might require some thought, it
> looks like I did misunderstand.
> "IDs" is the capitalization used in the gpg manpage.

Yes - the foo-revoked file is a list of key IDs rather than a keyring. 
I just went with extending what was already implemented previously so I 
guess this is how it is done in apt-key.  When you say "requires more 
thought" do you mean in the description or implementation?

>> +       for that keyring. These files are required to be signed (detached) by a
>> +       trusted PGP key.
>>
>>   *-u, \--updatedb*::
>>         Equivalent to \--check-trustdb in GnuPG.
>> diff --git a/scripts/Makefile.am b/scripts/Makefile.am
>> index adb259a..30b6ad8 100644
>> --- a/scripts/Makefile.am
>> +++ b/scripts/Makefile.am
>> @@ -46,6 +46,7 @@ edit = sed \
>>         -e 's|@localedir[@]|$(localedir)|g' \
>>         -e 's|@sysconfdir[@]|$(sysconfdir)|g' \
>>         -e 's|@localstatedir[@]|$(localstatedir)|g' \
>> +       -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' \
>>         -e 's|@prefix[@]|$(prefix)|g' \
>>         -e '1s|!/bin/bash|!$(BASH_SHELL)|g' \
>>         -e 's|@PACKAGE_VERSION[@]|$(REAL_PACKAGE_VERSION)|g' \
>> diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in
>> index 74ecfcf..c14d9bb 100644
>> --- a/scripts/pacman-key.sh.in
>> +++ b/scripts/pacman-key.sh.in
>> @@ -37,8 +37,8 @@ IMPORT_TRUSTDB=0
>>   INIT=0
>>   LISTKEYS=0
>>   LISTSIGS=0
>> +POPULATE=0
>>   RECEIVE=0
>> -RELOAD=0
>>   UPDATEDB=0
>>   VERIFY=0
>>
>> @@ -73,7 +73,8 @@ usage() {
>>         echo "$(gettext "  --import-trustdb<dir(s)>  Imports ownertrust values from trustdb.gpg in dir(s)")"
>>         echo "$(gettext "  --init                    Ensure the keyring is properly initialized")"
>>         echo "$(gettext "  --list-sigs [<keyid(s)>]  List keys and their signatures")"
>> -       echo "$(gettext "  --reload                  Reload the default keys")"
>> +       printf "$(gettext "  --populate [<keyring(s)]  Reload the default keys from the (given) keyrings\n\
>> +                            in '%s'")\n" "@pkgdatadir@/keyrings"
>>   }
>>
>>   version() {
>> @@ -139,75 +140,87 @@ check_keyring() {
>>
>>   verify_keyring_input() {
>>         local ret=0;
>> +       local KEYRING_IMPORT_DIR='@pkgdatadir@/keyrings'
>>
>> -       # Verify signatures of related files, if they exist
>> -       if [[ -r "${ADDED_KEYS}" ]]; then
>> -               msg "$(gettext "Verifying official keys file signature...")"
>> -               if ! "${GPG_PACMAN[@]}" --verify "${ADDED_KEYS}.sig"&>/dev/null; then
>> +       # Verify signatures of keyring files and association revocation files if they exist
>> +       msg "$(gettext "Verifying keyring file signatures...")"
>> +       local keyring
>> +       for keyring in ${KEYRINGIDS[@]}; do
>> +               if ! "${GPG_PACMAN[@]}" --verify "${KEYRING_IMPORT_DIR}/${keyring}.gpg.sig"&>/dev/null; then
> So how do we do the initial bootstrap? Maybe we need a way (e.g.
> command line option) to override the verification?

The initial bootstrap is going to require a user to manually add a 
key(s) and give it some trust.  That key(s) would then be used to sign 
the keyring (and the package it is distributed in) for the rest of the 
repo.  I can not see any sane way around that step.


<snip>

>> +       for keyring in ${KEYRINGIDS[@]}; do
>> +               if [[ -f "${KEYRING_IMPORT_DIR}/${keyring}-revoked" ]]; then
>> +                       while read key; do
>> +                               local key_values name
>> +                               key_values="$("${GPG_PACMAN[@]}" --quiet --with-colons --list-key "${key}" 2>/dev/null | grep ^pub | cut -d: -f5,10 --output-delimiter=' ')"
> A comment describing this madness line would be nice.

Sure...  note that is just an indent change so I will need to figure it 
out too!

>> +                               if [[ -n $key_values ]]; then
>> +                                       # The first word is the key_id
>> +                                       key_id="${key_values%% *}"
>> +                                       # the rest if the name of the owner
>> +                                       name="${key_values#* }"
>> +                                       if [[ -n ${key_id} ]]; then
>> +                                               # Mark this key to be deleted
>> +                                               removed_ids[$key_id]="$name"
>> +                                       fi
>>                                 fi
>> -                       fi
>> -               done<  "${REMOVED_KEYS}"
>> -       fi
>> +                       done<  "${KEYRING_IMPORT_DIR}/${keyring}-revoked"
>> +               fi
>> +       done
>>
>>         # List of keys that must be kept installed, even if in the list of keys to be removed
>>         local HOLD_KEYS="$(get_from "$CONFIG" "HoldKeys")"
> This is something I hadn't noticed before. How exactly does this hold
> keys stuff work? man pacman-key, /hold shows me nothing.

Looks like this was never documented anywhere...  My understanding is 
that you can provide a list of keys to never be removed from the keyring 
in using "HoldKey = " in pacman.conf.

Thinking about this, I'm not sure that is really an option for 
pacman.conf, but it does seem like something that is a useful feature. 
Suggestions for how it should be adjusted?

Allan



More information about the pacman-dev mailing list