Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: [PATCH] _gpg: Use explicit UIDs for public / secret keys.

On Tue, Jun 12, 2018 at 06:14:11PM -0400, Phil Pennock wrote:
> Unless you need trust information or some of the specific parts of the
> userid, using `--fast-list-mode` can have significant wins too.

I have ran `diff` on the output of `gpg --list-public-keys
--with-colons` and `gpg --list-public-keys --fast-list-mode
--with-colons` and there was no significant reduce in the amount of
output with my version of gpg, as noted in the commit message you

> Matthew's link to
> <https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS>
> is accurate and good guidance.  As is his pointer to check the correct
> column numbers.

Since columns may be added or removed in the format, as explained in
this documentation, I think it'll be better not to hard-code the
columns' numbers while parsing. Therefor, I'm inclined to go through all
of the fields after `fpr` and after `uid` in every line. With the field
in the line with `fpr`, it's easy to be sure of the `uid` we get from
this line since we can check if it's matched against `[A-F0-9]{40}`.

As for the line with description (or usually an email address), I'm not
sure what regex match to test on it before putting it in the right
array.. As already pointed out by Daniel, testing it with `=~ "@"` is
not good enough. Perhaps here we'll use a hard-coded number as
documented in gpg's repository? I need some opinions here..

> Beware that recent versions of GnuPG always show fingerprints, for keys
> and subkeys, because (per commit message) "The fingerprint should always
> be used thus we should always print it."; so you'll get multiple `fpr:`
> records per top-level key, although between the `sec` or `pub` top-level
> introducer and the `uid:` lines for _that_ key there should just be the
> top-level fingerprint.

> Welcome to the world of GnuPG integration.  You have my sympathy.  But
> also my encouragement.  :)
> -Phil

Anyway, I've created a draft that should be a much better and much more
understood but it's not ready yet as I'm not sure about what I explained
above, this is it:

    local public_keys_lines=(${(f)"$(_call_program public-keys ${(q)words[1]} ${(q)needed} --list-public-keys --list-options no-show-photos --with-colons)"})
    local -a uids emails
    local i j parts
    for (( i = 1; i < ${#public_keys_lines[@]}; ++i )); do
      if [[ ${parts[1]} == "fpr" ]]; then
        # This loop ensures that no matter if fields are added, the last field
        # that is built from 40 upper case A-Z letters is used as the uid.
        # We named the variable current_uid becuase it may have many email
        # addresses.
        for (( j = 2; j <${#parts[@]}; ++j )); do
          if [[ "${parts[$j]}" =~ "[A-F0-9]{40}" ]]; then
        i=$((i + 1))
        while [[ ${parts[1]} == "uid" ]]; do
          for (( j = 2; j <${#parts[@]}; ++j )); do
            # FIXME?
            if [[ "${parts[$j]}" =~ "@" ]]; then
          i=$((i + 1))
    _describe -t public-keys 'public key' emails uids

For me it works great and it is much faster then before, yet I'm not
sure about the if statement right below the `FIXME` comment.

Messages sorted by: Reverse Date, Date, Thread, Author