This simplifies the gpgme validity checking code by caching it in
crypt_key_t.  It also fixes a bug in _crypt_compare_trust() where it
wasn't using the correct validity value.

This patch is based on the just emailed "Fix pgp-gpgme to set
revoke/expired/disabled flags." patch.

-Kevin
# HG changeset patch
# User Kevin McCarthy <[email protected]>
# Date 1423433981 28800
#      Sun Feb 08 14:19:41 2015 -0800
# Node ID addd7cea01d4699b52363bc94c88e6bb04153fae
# Parent  7162033d1fb8a3b054244fc8097ab8b5bb5a99ed
Cache uid validity in crypt_key_t.

In order to find the validity for a crypt_key_t, the code has to loop
through the key->kobj->uids list up to the correct index.  This is a
bit silly since the uid is available when the crypt_key_t is created in
get_candidates().

This patch adds a validity field, and changes the various places to use
that instead of looping.

Also fix a bug in _crypt_compare_trust(): it was using the validity of
the first uid instead of the corresponding uid's validity.

diff --git a/crypt-gpgme.c b/crypt-gpgme.c
--- a/crypt-gpgme.c
+++ b/crypt-gpgme.c
@@ -105,16 +105,17 @@
    check and does not need any memory (gpgme uses reference counting). */
 typedef struct crypt_keyinfo
 {
   struct crypt_keyinfo *next;
   gpgme_key_t kobj;
   int idx;             /* and the user ID at this index */
   const char *uid;     /* and for convenience point to this user ID */
   unsigned int flags;  /* global and per uid flags (for convenience)*/
+  gpgme_validity_t validity;  /* uid validity (cached for convenience) */
 } crypt_key_t;
 
 typedef struct crypt_entry
 {
   size_t num;
   crypt_key_t *key;
 } crypt_entry_t;
 
@@ -263,16 +264,17 @@
   crypt_key_t *k;
 
   k = safe_calloc (1, sizeof *k);
   k->kobj = key->kobj;
   gpgme_key_ref (key->kobj);
   k->idx = key->idx;
   k->uid = key->uid;
   k->flags = key->flags;
+  k->validity = key->validity;
 
   return k;
 }
 
 /* Release all the keys at the address of KEYLIST and set the address
    to NULL. */
 static void crypt_free_key (crypt_key_t **keylist)
 {
@@ -297,31 +299,22 @@
   if (k->flags & KEYFLAG_CANTUSE)
     return 0;
   return 1;
 }
 
 /* Return true whe validity of KEY is sufficient. */
 static int crypt_id_is_strong (crypt_key_t *key)
 {
-  gpgme_validity_t val = GPGME_VALIDITY_UNKNOWN;
-  gpgme_user_id_t uid = NULL;
   unsigned int is_strong = 0;
-  unsigned int i = 0;
 
   if ((key->flags & KEYFLAG_ISX509))
     return 1;
 
-  for (i = 0, uid = key->kobj->uids; (i < key->idx) && uid;
-       i++, uid = uid->next)
-    ;
-  if (uid)
-    val = uid->validity;
-
-  switch (val)
+  switch (key->validity)
     {
     case GPGME_VALIDITY_UNKNOWN:
     case GPGME_VALIDITY_UNDEFINED:
     case GPGME_VALIDITY_NEVER:
     case GPGME_VALIDITY_MARGINAL:
       is_strong = 0;
       break;
 
@@ -2836,45 +2829,38 @@
       else if (!(kflags & (KEYFLAG_ABILITIES)))
         optional = 0;
       break;
     case 't':
       if ((kflags & KEYFLAG_ISX509))
         s = "x";
       else
        {
-         gpgme_user_id_t uid = NULL;
-         unsigned int i = 0;
-
-         for (i = 0, uid = key->kobj->uids; uid && (i < key->idx);
-               i++, uid = uid->next)
-            ;
-         if (uid)
-           switch (uid->validity)
-             {
-             case GPGME_VALIDITY_UNDEFINED:
-               s = "q";
-               break;
-             case GPGME_VALIDITY_NEVER:
-               s = "n";
-               break;
-             case GPGME_VALIDITY_MARGINAL:
-               s = "m";
-               break;
-             case GPGME_VALIDITY_FULL:
-               s = "f";
-               break;
-             case GPGME_VALIDITY_ULTIMATE:
-               s = "u";
-               break;
-             case GPGME_VALIDITY_UNKNOWN:
-             default:
-               s = "?";
-               break;
-             }
+          switch (key->validity)
+            {
+            case GPGME_VALIDITY_UNDEFINED:
+              s = "q";
+              break;
+            case GPGME_VALIDITY_NEVER:
+              s = "n";
+              break;
+            case GPGME_VALIDITY_MARGINAL:
+              s = "m";
+              break;
+            case GPGME_VALIDITY_FULL:
+              s = "f";
+              break;
+            case GPGME_VALIDITY_ULTIMATE:
+              s = "u";
+              break;
+            case GPGME_VALIDITY_UNKNOWN:
+            default:
+              s = "?";
+              break;
+            }
        }
       snprintf (fmt, sizeof (fmt), "%%%sc", prefix);
       snprintf (dest, destlen, fmt, s? *s: 'B');
       break;
     case 'p':
       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
       snprintf (dest, destlen, fmt,
                 gpgme_get_protocol_name (key->kobj->protocol));
@@ -2977,20 +2963,18 @@
   crypt_key_t **t = (crypt_key_t **) b;
   unsigned long ts = 0, tt = 0;
   int r;
 
   if ((r = (((*s)->flags & (KEYFLAG_RESTRICTIONS))
            - ((*t)->flags & (KEYFLAG_RESTRICTIONS)))))
     return r > 0;
 
-  if ((*s)->kobj->uids)
-    ts = (*s)->kobj->uids->validity;
-  if ((*t)->kobj->uids)
-    tt = (*t)->kobj->uids->validity;
+  ts = (*s)->validity;
+  tt = (*t)->validity;
   if ((r = (tt - ts)))
     return r < 0;
 
   if ((*s)->kobj->subkeys)
     ts = (*s)->kobj->subkeys->length;
   if ((*t)->kobj->subkeys)
     tt = (*t)->kobj->subkeys->length;
   if (ts != tt)
@@ -3785,16 +3769,17 @@
               k = safe_calloc (1, sizeof *k);
               k->kobj = key;
               gpgme_key_ref (k->kobj);
               k->idx = idx;
               k->uid = uid->uid;
               k->flags = flags;
               if (uid->revoked)
                 k->flags |= KEYFLAG_REVOKED;
+              k->validity = uid->validity;
               *kend = k;
               kend = &k->next;
             }
           gpgme_key_unref (key);
         }
       if (gpg_err_code (err) != GPG_ERR_EOF)
         mutt_error (_("gpgme_op_keylist_next failed: %s"), gpgme_strerror 
(err));
       gpgme_op_keylist_end (ctx);
@@ -3828,16 +3813,17 @@
          for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
             {
               k = safe_calloc (1, sizeof *k);
               k->kobj = key;
               gpgme_key_ref (k->kobj);
               k->idx = idx;
               k->uid = uid->uid;
               k->flags = flags;
+              k->validity = uid->validity;
               *kend = k;
               kend = &k->next;
             }
           gpgme_key_unref (key);
         }
       if (gpg_err_code (err) != GPG_ERR_EOF)
         mutt_error (_("gpgme_op_keylist_next failed: %s"), gpgme_strerror 
(err));
       gpgme_op_keylist_end (ctx);
@@ -4010,30 +3996,18 @@
             {
               const char *warn_s;
               char buff[LONG_STRING];
               
               if (key_table[menu->current]->flags & KEYFLAG_CANTUSE)
                 warn_s = N_("ID is expired/disabled/revoked.");
               else 
                 {
-                 gpgme_validity_t val = GPGME_VALIDITY_UNKNOWN;
-                 gpgme_user_id_t uid = NULL;
-                 unsigned int j = 0;
-
                   warn_s = "??";
-
-                 uid = key_table[menu->current]->kobj->uids;
-                 for (j = 0; (j < key_table[menu->current]->idx) && uid;
-                       j++, uid = uid->next)
-                    ;
-                 if (uid)
-                   val = uid->validity;
-
-                  switch (val)
+                  switch (key_table[menu->current]->validity)
                     {
                     case GPGME_VALIDITY_UNKNOWN:   
                     case GPGME_VALIDITY_UNDEFINED: 
                       warn_s = N_("ID has undefined validity.");
                       break;
                     case GPGME_VALIDITY_NEVER:     
                       warn_s = N_("ID is not valid.");
                       break;

Attachment: signature.asc
Description: PGP signature

Reply via email to