[Pkg-gnupg-commit] [gnupg2] 19/180: g10: Avoid gratuitously loading a keyblock when it is already available

Daniel Kahn Gillmor dkg at fifthhorseman.net
Sat Dec 24 22:29:03 UTC 2016


This is an automated email from the git hooks/post-receive script.

dkg pushed a commit to branch master
in repository gnupg2.

commit 03a65a53231cc3132a50a1871e81a512c44da169
Author: Neal H. Walfield <neal at g10code.com>
Date:   Wed Nov 23 12:29:22 2016 +0100

    g10: Avoid gratuitously loading a keyblock when it is already available
    
    * g10/trust.c (get_validity): Add new, optional parameter KB.  Only
    load the keyblock if KB is NULL.  Update callers.
    (get_validity): Likewise.
    * g10/trustdb.c (tdb_get_validity_core): Likewise.
    
    --
    Signed-off-by: Neal H. Walfield <neal at g10code.com>
    GnuPG-bug-id: 2812
---
 g10/getkey.c     |  2 +-
 g10/gpgv.c       |  7 +++++--
 g10/keyedit.c    |  9 ++++----
 g10/keylist.c    |  4 ++--
 g10/mainproc.c   | 15 +++++++++-----
 g10/photoid.c    |  2 +-
 g10/pkclist.c    |  7 ++++---
 g10/test-stubs.c |  7 +++++--
 g10/trust.c      | 63 ++++++++++++++++++++++++++++++++++++++------------------
 g10/trustdb.c    | 34 +++++++++++++++++++++++-------
 g10/trustdb.h    |  8 ++++---
 11 files changed, 108 insertions(+), 50 deletions(-)

diff --git a/g10/getkey.c b/g10/getkey.c
index f0e33c5..68e6a1b 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -1543,7 +1543,7 @@ pubkey_cmp (ctrl_t ctrl, const char *name, struct pubkey_cmp_cookie *old,
 
       new->uid = scopy_user_id (uid);
       new->validity =
-        get_validity (ctrl, &new->key, uid, NULL, 0) & TRUST_MASK;
+        get_validity (ctrl, new_keyblock, &new->key, uid, NULL, 0) & TRUST_MASK;
       new->valid = 1;
 
       if (! old->valid)
diff --git a/g10/gpgv.c b/g10/gpgv.c
index da07989..0ecf232 100644
--- a/g10/gpgv.c
+++ b/g10/gpgv.c
@@ -292,19 +292,22 @@ check_trustdb_stale (ctrl_t ctrl)
 }
 
 int
-get_validity_info (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid)
+get_validity_info (ctrl_t ctrl, kbnode_t kb, PKT_public_key *pk,
+                   PKT_user_id *uid)
 {
   (void)ctrl;
+  (void)kb;
   (void)pk;
   (void)uid;
   return '?';
 }
 
 unsigned int
-get_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
+get_validity (ctrl_t ctrl, kbnode_t kb, PKT_public_key *pk, PKT_user_id *uid,
               PKT_signature *sig, int may_ask)
 {
   (void)ctrl;
+  (void)kb;
   (void)pk;
   (void)uid;
   (void)sig;
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 5b77ee7..94fa8c4 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -3585,7 +3585,7 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
 	    es_putc ('e', fp);
 	  else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks))
 	    {
-	      int trust = get_validity_info (ctrl, pk, NULL);
+	      int trust = get_validity_info (ctrl, keyblock, pk, NULL);
 	      if (trust == 'u')
 		ulti_hack = 1;
 	      es_putc (trust, fp);
@@ -3644,7 +3644,7 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
 	      int uid_validity;
 
 	      if (primary && !ulti_hack)
-		uid_validity = get_validity_info (ctrl, primary, uid);
+		uid_validity = get_validity_info (ctrl, keyblock, primary, uid);
 	      else
 		uid_validity = 'u';
 	      es_fprintf (fp, "%c::::::::", uid_validity);
@@ -3819,7 +3819,7 @@ show_key_with_all_names (ctrl_t ctrl, estream_t fp,
 
 	      /* Show a warning once */
 	      if (!did_warn
-		  && (get_validity (ctrl, pk, NULL, NULL, 0)
+		  && (get_validity (ctrl, keyblock, pk, NULL, NULL, 0)
 		      & TRUST_FLAG_PENDING_CHECK))
 		{
 		  did_warn = 1;
@@ -6304,7 +6304,8 @@ core_revuid (ctrl_t ctrl, kbnode_t keyblock, KBNODE node,
               /* If the trustdb has an entry for this key+uid then the
                  trustdb needs an update. */
               if (!update_trust
-                  && ((get_validity (ctrl, pk, uid, NULL, 0) & TRUST_MASK)
+                  && ((get_validity (ctrl, keyblock, pk, uid, NULL, 0)
+                       & TRUST_MASK)
                       >= TRUST_UNDEFINED))
                 update_trust = 1;
 #endif /*!NO_TRUST_MODELS*/
diff --git a/g10/keylist.c b/g10/keylist.c
index 0523be0..a5fdc06 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -1228,7 +1228,7 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
     trustletter_print = 0;
   else
     {
-      trustletter = get_validity_info (ctrl, pk, NULL);
+      trustletter = get_validity_info (ctrl, keyblock, pk, NULL);
       if (trustletter == 'u')
         ulti_hack = 1;
       trustletter_print = trustletter;
@@ -1309,7 +1309,7 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
 	  else if (ulti_hack)
             uid_validity = 'u';
           else
-            uid_validity = get_validity_info (ctrl, pk, uid);
+            uid_validity = get_validity_info (ctrl, keyblock, pk, uid);
 
           es_fputs (uid->attrib_data? "uat:":"uid:", es_stdout);
           if (uid_validity)
diff --git a/g10/mainproc.c b/g10/mainproc.c
index c1819f0..30e19fe 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -1015,8 +1015,13 @@ list_node (CTX c, kbnode_t node)
 
           keyid_from_pk( pk, keyid );
           if (pk->flags.primary)
-            c->trustletter = (opt.fast_list_mode?
-                              0 : get_validity_info (c->ctrl, pk, NULL));
+            c->trustletter = (opt.fast_list_mode
+                              ? 0
+                              : get_validity_info
+                                  (c->ctrl,
+                                   node->pkt->pkttype == PKT_PUBLIC_KEY
+                                   ? node : NULL,
+                                   pk, NULL));
           es_printf ("%s:", pk->flags.primary? "pub":"sub" );
           if (c->trustletter)
             es_putc (c->trustletter, es_stdout);
@@ -1973,8 +1978,8 @@ check_sig_and_print (CTX c, kbnode_t node)
 	     does not print a LF we need to compute the validity
 	     before calling that function.  */
           if ((opt.verify_options & VERIFY_SHOW_UID_VALIDITY))
-            valid = get_validity (c->ctrl, mainpk, un->pkt->pkt.user_id,
-                                  NULL, 0);
+            valid = get_validity (c->ctrl, keyblock, mainpk,
+                                  un->pkt->pkt.user_id, NULL, 0);
           else
             valid = 0; /* Not used.  */
 
@@ -2075,7 +2080,7 @@ check_sig_and_print (CTX c, kbnode_t node)
 		       actually ask the user to update any trust
 		       information.  */
                     valid = (trust_value_to_string
-                             (get_validity (c->ctrl, mainpk,
+                             (get_validity (c->ctrl, keyblock, mainpk,
                                             un->pkt->pkt.user_id, NULL, 0)));
                   log_printf (" [%s]\n",valid);
                 }
diff --git a/g10/photoid.c b/g10/photoid.c
index b61ed1b..8b193b3 100644
--- a/g10/photoid.c
+++ b/g10/photoid.c
@@ -304,7 +304,7 @@ show_photos (ctrl_t ctrl, const struct user_attribute *attrs, int count,
 
   memset (&args, 0, sizeof(args));
   args.pk = pk;
-  args.validity_info = get_validity_info (ctrl, pk, uid);
+  args.validity_info = get_validity_info (ctrl, NULL, pk, uid);
   args.validity_string = get_validity_string (ctrl, pk, uid);
   namehash_from_uid (uid);
   args.namehash = uid->namehash;
diff --git a/g10/pkclist.c b/g10/pkclist.c
index 51e8f27..0426da8 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -569,7 +569,7 @@ check_signatures_trust (ctrl_t ctrl, PKT_signature *sig)
     log_info(_("WARNING: this key might be revoked (revocation key"
 	       " not present)\n"));
 
-  trustlevel = get_validity (ctrl, pk, NULL, sig, 1);
+  trustlevel = get_validity (ctrl, NULL, pk, NULL, sig, 1);
 
   if ( (trustlevel & TRUST_FLAG_REVOKED) )
     {
@@ -872,7 +872,7 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
     {
       int trustlevel;
 
-      trustlevel = get_validity (ctrl, pk, pk->user_id, NULL, 1);
+      trustlevel = get_validity (ctrl, NULL, pk, pk->user_id, NULL, 1);
       if ( (trustlevel & TRUST_FLAG_DISABLED) )
         {
           /* Key has been disabled. */
@@ -1212,7 +1212,8 @@ build_pk_list (ctrl_t ctrl, strlist_t rcpts, PK_LIST *ret_pk_list)
                 { /* Check validity of this key. */
                   int trustlevel;
 
-                  trustlevel = get_validity (ctrl, pk, pk->user_id, NULL, 1);
+                  trustlevel =
+                    get_validity (ctrl, NULL, pk, pk->user_id, NULL, 1);
                   if ( (trustlevel & TRUST_FLAG_DISABLED) )
                     {
                       tty_printf (_("Public key is disabled.\n") );
diff --git a/g10/test-stubs.c b/g10/test-stubs.c
index 2dc65ab..8752f88 100644
--- a/g10/test-stubs.c
+++ b/g10/test-stubs.c
@@ -98,19 +98,22 @@ check_trustdb_stale (ctrl_t ctrl)
 }
 
 int
-get_validity_info (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid)
+get_validity_info (ctrl_t ctrl, kbnode_t kb, PKT_public_key *pk,
+                   PKT_user_id *uid)
 {
   (void)ctrl;
+  (void)kb;
   (void)pk;
   (void)uid;
   return '?';
 }
 
 unsigned int
-get_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
+get_validity (ctrl_t ctrl, kbnode_t kb, PKT_public_key *pk, PKT_user_id *uid,
               PKT_signature *sig, int may_ask)
 {
   (void)ctrl;
+  (void)kb;
   (void)pk;
   (void)uid;
   (void)sig;
diff --git a/g10/trust.c b/g10/trust.c
index 2a829b8..080926a 100644
--- a/g10/trust.c
+++ b/g10/trust.c
@@ -151,7 +151,7 @@ uid_trust_string_fixed (ctrl_t ctrl, PKT_public_key *key, PKT_user_id *uid)
     return                         _("[ expired]");
   else if(key)
     {
-      switch (get_validity (ctrl, key, uid, NULL, 0) & TRUST_MASK)
+      switch (get_validity (ctrl, NULL, key, uid, NULL, 0) & TRUST_MASK)
         {
         case TRUST_UNKNOWN:   return _("[ unknown]");
         case TRUST_EXPIRED:   return _("[ expired]");
@@ -297,12 +297,13 @@ check_or_update_trustdb (ctrl_t ctrl)
 
 
 /*
- * Return the validity information for PK.  If the namehash is not
- * NULL, the validity of the corresponding user ID is returned,
- * otherwise, a reasonable value for the entire key is returned.
+ * Return the validity information for KB/PK (at least one must be
+ * non-NULL).  If the namehash is not NULL, the validity of the
+ * corresponding user ID is returned, otherwise, a reasonable value
+ * for the entire key is returned.
  */
 unsigned int
-get_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
+get_validity (ctrl_t ctrl, kbnode_t kb, PKT_public_key *pk, PKT_user_id *uid,
               PKT_signature *sig, int may_ask)
 {
   int rc;
@@ -310,6 +311,16 @@ get_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
   u32 kid[2];
   PKT_public_key *main_pk;
 
+  if (kb && pk)
+    log_assert (keyid_cmp (pk_main_keyid (pk),
+                           pk_main_keyid (kb->pkt->pkt.public_key)) == 0);
+
+  if (! pk)
+    {
+      log_assert (kb);
+      pk = kb->pkt->pkt.public_key;
+    }
+
   if (uid)
     namehash_from_uid (uid);
 
@@ -317,17 +328,22 @@ get_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
   if (pk->main_keyid[0] != kid[0] || pk->main_keyid[1] != kid[1])
     {
       /* This is a subkey - get the mainkey. */
-      main_pk = xmalloc_clear (sizeof *main_pk);
-      rc = get_pubkey (main_pk, pk->main_keyid);
-      if (rc)
+      if (kb)
+        main_pk = kb->pkt->pkt.public_key;
+      else
         {
-	  char *tempkeystr = xstrdup (keystr (pk->main_keyid));
-          log_error ("error getting main key %s of subkey %s: %s\n",
-                     tempkeystr, keystr (kid), gpg_strerror (rc));
-	  xfree (tempkeystr);
-          validity = TRUST_UNKNOWN;
-          goto leave;
-	}
+          main_pk = xmalloc_clear (sizeof *main_pk);
+          rc = get_pubkey (main_pk, pk->main_keyid);
+          if (rc)
+            {
+              char *tempkeystr = xstrdup (keystr (pk->main_keyid));
+              log_error ("error getting main key %s of subkey %s: %s\n",
+                         tempkeystr, keystr (kid), gpg_strerror (rc));
+              xfree (tempkeystr);
+              validity = TRUST_UNKNOWN;
+              goto leave;
+            }
+        }
     }
   else
     main_pk = pk;
@@ -335,7 +351,7 @@ get_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
 #ifdef NO_TRUST_MODELS
   validity = TRUST_UNKNOWN;
 #else
-  validity = tdb_get_validity_core (ctrl, pk, uid, main_pk, sig, may_ask);
+  validity = tdb_get_validity_core (ctrl, kb, pk, uid, main_pk, sig, may_ask);
 #endif
 
  leave:
@@ -350,21 +366,28 @@ get_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
     validity = ((validity & (~TRUST_MASK | TRUST_FLAG_PENDING_CHECK))
                 | TRUST_EXPIRED);
 
-  if (main_pk != pk)
+  if (main_pk != pk && !kb)
     free_public_key (main_pk);
   return validity;
 }
 
 
 int
-get_validity_info (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid)
+get_validity_info (ctrl_t ctrl, kbnode_t kb, PKT_public_key *pk,
+                   PKT_user_id *uid)
 {
   int trustlevel;
 
+  if (kb && pk)
+    log_assert (keyid_cmp (pk_main_keyid (pk),
+                           pk_main_keyid (kb->pkt->pkt.public_key)) == 0);
+
+  if (! pk && kb)
+    pk = kb->pkt->pkt.public_key;
   if (!pk)
     return '?';  /* Just in case a NULL PK is passed.  */
 
-  trustlevel = get_validity (ctrl, pk, uid, NULL, 0);
+  trustlevel = get_validity (ctrl, kb, pk, uid, NULL, 0);
   if ((trustlevel & TRUST_FLAG_REVOKED))
     return 'r';
   return trust_letter (trustlevel);
@@ -379,7 +402,7 @@ get_validity_string (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid)
   if (!pk)
     return "err";  /* Just in case a NULL PK is passed.  */
 
-  trustlevel = get_validity (ctrl, pk, uid, NULL, 0);
+  trustlevel = get_validity (ctrl, NULL, pk, uid, NULL, 0);
   if ((trustlevel & TRUST_FLAG_REVOKED))
     return _("revoked");
   return trust_value_to_string (trustlevel);
diff --git a/g10/trustdb.c b/g10/trustdb.c
index 51a8f22..d402cb2 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -983,13 +983,15 @@ tdb_check_trustdb_stale (ctrl_t ctrl)
 }
 
 /*
- * Return the validity information for PK.  This is the core of
- * get_validity.  If SIG is not NULL, then the trust is being
- * evaluated in the context of the provided signature.  This is used
- * by the TOFU code to record statistics.
+ * Return the validity information for KB/PK (at least one of them
+ * must be non-NULL).  This is the core of get_validity.  If SIG is
+ * not NULL, then the trust is being evaluated in the context of the
+ * provided signature.  This is used by the TOFU code to record
+ * statistics.
  */
 unsigned int
 tdb_get_validity_core (ctrl_t ctrl,
+                       kbnode_t kb,
                        PKT_public_key *pk, PKT_user_id *uid,
                        PKT_public_key *main_pk,
 		       PKT_signature *sig,
@@ -1002,6 +1004,17 @@ tdb_get_validity_core (ctrl_t ctrl,
   unsigned int tofu_validity = TRUST_UNKNOWN;
 #endif
   unsigned int validity = TRUST_UNKNOWN;
+  int free_kb = 0;
+
+  if (kb && pk)
+    log_assert (keyid_cmp (pk_main_keyid (pk),
+                           pk_main_keyid (kb->pkt->pkt.public_key)) == 0);
+
+  if (! pk)
+    {
+      log_assert (kb);
+      pk = kb->pkt->pkt.public_key;
+    }
 
 #ifndef USE_TOFU
   (void)sig;
@@ -1030,14 +1043,20 @@ tdb_get_validity_core (ctrl_t ctrl,
 #ifdef USE_TOFU
   if (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP)
     {
-      kbnode_t kb = NULL;
       kbnode_t n = NULL;
       strlist_t user_id_list = NULL;
       int done = 0;
 
       /* If the caller didn't supply a user id then use all uids.  */
       if (! uid)
-	kb = n = get_pubkeyblock (main_pk->keyid);
+        {
+          if (! kb)
+            {
+              kb = get_pubkeyblock (main_pk->keyid);
+              free_kb = 1;
+            }
+          n = kb;
+        }
 
       if (DBG_TRUST && sig && sig->signers_uid)
         log_debug ("TOFU: only considering user id: '%s'\n",
@@ -1132,7 +1151,8 @@ tdb_get_validity_core (ctrl_t ctrl,
                                            may_ask);
 
       free_strlist (user_id_list);
-      release_kbnode (kb);
+      if (free_kb)
+        release_kbnode (kb);
     }
 #endif /*USE_TOFU*/
 
diff --git a/g10/trustdb.h b/g10/trustdb.h
index 45ecc56..6081d10 100644
--- a/g10/trustdb.h
+++ b/g10/trustdb.h
@@ -94,9 +94,11 @@ void revalidation_mark (void);
 void check_trustdb_stale (ctrl_t ctrl);
 void check_or_update_trustdb (ctrl_t ctrl);
 
-unsigned int get_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
+unsigned int get_validity (ctrl_t ctrl, kbnode_t kb, PKT_public_key *pk,
+                           PKT_user_id *uid,
 			   PKT_signature *sig, int may_ask);
-int get_validity_info (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid);
+int get_validity_info (ctrl_t ctrl, kbnode_t kb, PKT_public_key *pk,
+                       PKT_user_id *uid);
 const char *get_validity_string (ctrl_t ctrl,
                                  PKT_public_key *pk, PKT_user_id *uid);
 
@@ -135,7 +137,7 @@ void tdb_check_or_update (ctrl_t ctrl);
 
 int tdb_cache_disabled_value (PKT_public_key *pk);
 
-unsigned int tdb_get_validity_core (ctrl_t ctrl,
+unsigned int tdb_get_validity_core (ctrl_t ctrl, kbnode_t kb,
                                     PKT_public_key *pk, PKT_user_id *uid,
                                     PKT_public_key *main_pk,
 				    PKT_signature *sig, int may_ask);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git



More information about the Pkg-gnupg-commit mailing list