Add fingerprint record parsing for pgp list keys. (see #3695)

Modify parse_pub_line to parse fpr records and add the fingerprint to
the pgp_key_t's fingerprint field.

Add "--with-fingerprint --with-fingerprint" to the
pgp_list_pubring_command and pgp_list_secring_command commands in
contrib/gpg.rc.  The second invocation generates fpr records for subkeys
too.

-Kevin
# HG changeset patch
# User Kevin McCarthy <ke...@8t8.us>
# Date 1424023750 28800
#      Sun Feb 15 10:09:10 2015 -0800
# Node ID af5951f5d81c13b54f8896b2b372fb1774547c06
# Parent  47b4e57b2f1c68f40cf607e625b85a97aa03299e
Add fingerprint record parsing for pgp list keys. (see #3695)

Modify parse_pub_line to parse fpr records and add the fingerprint to
the pgp_key_t's fingerprint field.

Add "--with-fingerprint --with-fingerprint" to the
pgp_list_pubring_command and pgp_list_secring_command commands in
contrib/gpg.rc.  The second invocation generates fpr records for subkeys
too.

diff --git a/contrib/gpg.rc b/contrib/gpg.rc
--- a/contrib/gpg.rc
+++ b/contrib/gpg.rc
@@ -60,20 +60,20 @@
 
 # export a key from the public key ring
 set pgp_export_command="gpg --no-verbose --export --armor %r"
 
 # verify a key
 set pgp_verify_key_command="gpg --verbose --batch --fingerprint --check-sigs 
%r"
 
 # read in the public key ring
-set pgp_list_pubring_command="gpg --no-verbose --batch --quiet --with-colons 
--list-keys %r" 
+set pgp_list_pubring_command="gpg --no-verbose --batch --quiet --with-colons 
--with-fingerprint --with-fingerprint --list-keys %r"
 
 # read in the secret key ring
-set pgp_list_secring_command="gpg --no-verbose --batch --quiet --with-colons 
--list-secret-keys %r" 
+set pgp_list_secring_command="gpg --no-verbose --batch --quiet --with-colons 
--with-fingerprint --with-fingerprint --list-secret-keys %r"
 
 # fetch keys
 # set pgp_getkeys_command="pkspxycwrap %r"
 
 # pattern for good signature - may need to be adapted to locale!
 
 # set pgp_good_sign="^gpgv?: Good signature from "
 
diff --git a/gnupgparse.c b/gnupgparse.c
--- a/gnupgparse.c
+++ b/gnupgparse.c
@@ -116,16 +116,17 @@
   }
 }
 
 static pgp_key_t parse_pub_line (char *buf, int *is_subkey, pgp_key_t k)
 {
   pgp_uid_t *uid = NULL;
   int field = 0, is_uid = 0;
   int is_pub = 0;
+  int is_fpr = 0;
   char *pend, *p;
   int trust = 0;
   int flags = 0;
   struct pgp_keyinfo tmp;
 
   *is_subkey = 0;
   if (!*buf)
     return NULL;
@@ -143,36 +144,41 @@
   for (p = buf; p; p = pend)
   {
     if ((pend = strchr (p, ':')))
       *pend++ = 0;
     field++;
     if (!*p && (field != 1) && (field != 10))
       continue;
 
+    if (is_fpr && (field != 10))
+      continue;
+
     switch (field)
     {
       case 1:                  /* record type */
       {
        dprint (2, (debugfile, "record type: %s\n", p));
 
        if (!mutt_strcmp (p, "pub"))
          is_pub = 1;
        else if (!mutt_strcmp (p, "sub"))
          *is_subkey = 1;
        else if (!mutt_strcmp (p, "sec"))
          ;
        else if (!mutt_strcmp (p, "ssb"))
          *is_subkey = 1;
        else if (!mutt_strcmp (p, "uid"))
          is_uid = 1;
+       else if (!mutt_strcmp (p, "fpr"))
+         is_fpr = 1;
        else
          return NULL;
 
-       if (!(is_uid || (*is_subkey && option (OPTPGPIGNORESUB))))
+       if (!(is_uid || is_fpr || (*is_subkey && option (OPTPGPIGNORESUB))))
          memset (&tmp, 0, sizeof (tmp));
 
        break;
       }
       case 2:                  /* trust info */
       {
        dprint (2, (debugfile, "trust info: %s\n", p));
 
@@ -285,16 +291,24 @@
          * We allow an empty field for a pub record type because it is
          * possible for a primary uid record to have an empty User-ID
          * field.  Without any address records, it is not possible to
          * use the key in mutt.
          */
         if (!(pend && (*p || is_pub)))
          break;
 
+        if (is_fpr)
+        {
+          /* don't let a subkey fpr overwrite an existing primary key fpr */
+          if (!tmp.fingerprint)
+            tmp.fingerprint = safe_strdup (p);
+          break;
+        }
+
        /* ignore user IDs on subkeys */
        if (!is_uid && (*is_subkey && option (OPTPGPIGNORESUB)))
          break;
 
        dprint (2, (debugfile, "user ID: %s\n", NONULL (p)));
 
        uid = safe_calloc (sizeof (pgp_uid_t), 1);
        fix_uid (p);
@@ -344,17 +358,17 @@
        break;
       
       default:
         break;
     }
   }
 
   /* merge temp key back into real key */
-  if (!(is_uid || (*is_subkey && option (OPTPGPIGNORESUB))))
+  if (!(is_uid || is_fpr || (*is_subkey && option (OPTPGPIGNORESUB))))
     k = safe_malloc (sizeof (*k));
   memcpy (k, &tmp, sizeof (*k));
   /* fixup parentship of uids after mering the temp key into
    * the real key */
   if (tmp.address)
   {
     for (uid = k->address; uid; uid = uid->next)
       uid->parent = k;

Attachment: signature.asc
Description: PGP signature

Reply via email to