[git] GnuPG - branch, master, updated. gnupg-2.1.21-151-g166d0d7

by Werner Koch cvs at cvs.gnupg.org
Tue Jul 25 11:36:28 CEST 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  166d0d7a2439f30c0a250faadc16ce3453447d71 (commit)
       via  84c993d9325fc000acac7950b2dfeefa5976df3b (commit)
      from  d40b4a41a8d60292fd4b5b951a19883e31090179 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 166d0d7a2439f30c0a250faadc16ce3453447d71
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Jul 25 11:23:08 2017 +0200

    gpg: Update key origin info during import merge.
    
    * g10/import.c (update_key_origin): New.
    (merge_blocks): Add arg curtime.
    (import_one): Pass curtime to merge_blocks.  Call update_key_origin.
    --
    
    We probably need to refine the rules on how this is done.  But it is a
    start.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/import.c b/g10/import.c
index fda308b..6e83225 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -123,7 +123,7 @@ static int any_uid_left (kbnode_t keyblock);
 static int merge_blocks (ctrl_t ctrl, unsigned int options,
                          kbnode_t keyblock_orig,
 			 kbnode_t keyblock, u32 *keyid,
-                         int origin, const char *url,
+                         u32 curtime, int origin, const char *url,
 			 int *n_uids, int *n_sigs, int *n_subk );
 static gpg_error_t append_new_uid (unsigned int options,
                                    kbnode_t keyblock, kbnode_t node,
@@ -1521,6 +1521,81 @@ insert_key_origin (kbnode_t keyblock, int origin, const char *url)
 }
 
 
+/* Update meta data on KEYBLOCK.  This updates the key origin on the
+ * public key according to ORIGIN and URL.  The UIDs are already
+ * updated when this function is called.  */
+static gpg_error_t
+update_key_origin (kbnode_t keyblock, u32 curtime, int origin, const char *url)
+{
+  PKT_public_key *pk;
+
+  log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
+  pk = keyblock->pkt->pkt.public_key;
+
+  if (pk->keyupdate > curtime)
+    ; /* Don't do it for a time warp.  */
+  else if (origin == KEYORG_WKD || origin == KEYORG_DANE)
+    {
+      /* We only update the origin info if they either have never been
+       * set or are the origin was the same as the new one.  If this
+       * is WKD we also update the UID to show from which user id this
+       * was updated.  */
+      if (!pk->keyorg || pk->keyorg == KEYORG_WKD || pk->keyorg == KEYORG_DANE)
+        {
+          pk->keyorg = origin;
+          pk->keyupdate = curtime;
+          xfree (pk->updateurl);
+          pk->updateurl = NULL;
+          if (origin == KEYORG_WKD && url)
+            {
+              pk->updateurl = xtrystrdup (url);
+              if (!pk->updateurl)
+                return gpg_error_from_syserror ();
+            }
+        }
+    }
+  else if (origin == KEYORG_KS)
+    {
+      /* All updates from a keyserver are considered to have the
+       * freshed key.  Thus we always set the new key origin.  */
+      pk->keyorg = origin;
+      pk->keyupdate = curtime;
+      xfree (pk->updateurl);
+      pk->updateurl = NULL;
+      if (url)
+        {
+          pk->updateurl = xtrystrdup (url);
+          if (!pk->updateurl)
+            return gpg_error_from_syserror ();
+        }
+    }
+  else if (origin == KEYORG_FILE)
+    {
+      /* Updates from a file are considered to be fresh.  */
+      pk->keyorg = origin;
+      pk->keyupdate = curtime;
+      xfree (pk->updateurl);
+      pk->updateurl = NULL;
+    }
+  else if (origin == KEYORG_URL)
+    {
+      /* Updates from a URL are considered to be fresh.  */
+      pk->keyorg = origin;
+      pk->keyupdate = curtime;
+      xfree (pk->updateurl);
+      pk->updateurl = NULL;
+      if (url)
+        {
+          pk->updateurl = xtrystrdup (url);
+          if (!pk->updateurl)
+            return gpg_error_from_syserror ();
+        }
+    }
+
+  return 0;
+}
+
+
 /*
  * Try to import one keyblock. Return an error only in serious cases,
  * but never for an invalid keyblock.  It uses log_error to increase
@@ -1812,6 +1887,7 @@ import_one (ctrl_t ctrl,
     {
       KEYDB_HANDLE hd;
       int n_uids, n_sigs, n_subk, n_sigs_cleaned, n_uids_cleaned;
+      u32 curtime = make_timestamp ();
 
       /* Compare the original against the new key; just to be sure nothing
        * weird is going on */
@@ -1858,7 +1934,7 @@ import_one (ctrl_t ctrl,
       clear_kbnode_flags( keyblock );
       n_uids = n_sigs = n_subk = n_uids_cleaned = 0;
       rc = merge_blocks (ctrl, options, keyblock_orig, keyblock, keyid,
-                         origin, url,
+                         curtime, origin, url,
                          &n_uids, &n_sigs, &n_subk );
       if (rc )
         {
@@ -1872,6 +1948,21 @@ import_one (ctrl_t ctrl,
 
       if (n_uids || n_sigs || n_subk || n_sigs_cleaned || n_uids_cleaned)
         {
+          /* Unless we are in restore mode apply meta data to the
+           * keyblock.  Note that this will never change the first packet
+           * and thus the address of KEYBLOCK won't change.  */
+          if ( !(options & IMPORT_RESTORE) )
+            {
+              rc = update_key_origin (keyblock_orig, curtime, origin, url);
+              if (rc)
+                {
+                  log_error ("update_key_origin failed: %s\n",
+                             gpg_strerror (rc));
+                  keydb_release (hd);
+                  goto leave;
+                }
+            }
+
           mod_key = 1;
           /* KEYBLOCK_ORIG has been updated; write */
           rc = keydb_update_keyblock (ctrl, hd, keyblock_orig);
@@ -1929,6 +2020,9 @@ import_one (ctrl_t ctrl,
 	}
       else
         {
+          /* Fixme: we do not track the time we last checked a key for
+           * updates.  To do this we would need to rewrite even the
+           * keys which have no changes.  */
           same_key = 1;
           if (is_status_enabled ())
             print_import_ok (pk, 0);
@@ -3226,12 +3320,11 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock)
 static int
 merge_blocks (ctrl_t ctrl, unsigned int options,
               kbnode_t keyblock_orig, kbnode_t keyblock,
-              u32 *keyid, int origin, const char *url,
+              u32 *keyid, u32 curtime, int origin, const char *url,
 	      int *n_uids, int *n_sigs, int *n_subk )
 {
   kbnode_t onode, node;
   int rc, found;
-  u32 curtime = make_timestamp ();
 
   /* 1st: handle revocation certificates */
   for (node=keyblock->next; node; node=node->next )

commit 84c993d9325fc000acac7950b2dfeefa5976df3b
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Jul 25 10:19:12 2017 +0200

    gpg: Store key origin for new userids during import merge.
    
    * g10/import.c (apply_meta_data): Rename to ...
    (insert_key_origin): this.  Factor code out to ...
    (insert_key_origin_pk, insert_key_origin_uid): new funcs.
    (import_one): Move insert_key_origin behind clean_key.
    (merge_blocks): Add args options, origin, and url.
    (append_uid): Rename to ...
    (append_new_uid): this.  Add args options, curtime, origin, and url.
    Call insert_key_origin_uid for new UIDs.
    --
    
    This is a straightforward change to handle new user ids.
    
    How to test:
    
    With an empty keyring run
    
      gpg --with-key-origin --locate-key \
          --auto-key-locate clear,nodefault,wkd  wk at gnupg.org
    
    and then append a new keyid using
    
      gpg --with-key-origin --locate-key \
          --auto-key-locate clear,nodefault,wkd  wk at g10code.com
    
    Works with my current key 80615870F5BAD690333686D0F2AD85AC1E42B367.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/import.c b/g10/import.c
index f18ef48..fda308b 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -1,6 +1,6 @@
 /* import.c - import a key into our key storage.
  * Copyright (C) 1998-2007, 2010-2011 Free Software Foundation, Inc.
- * Copyright (C) 2014, 2016  Werner Koch
+ * Copyright (C) 2014, 2016, 2017  Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -120,10 +120,15 @@ static int chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
 static int delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock,
                              u32 *keyid, unsigned int options);
 static int any_uid_left (kbnode_t keyblock);
-static int merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig,
+static int merge_blocks (ctrl_t ctrl, unsigned int options,
+                         kbnode_t keyblock_orig,
 			 kbnode_t keyblock, u32 *keyid,
+                         int origin, const char *url,
 			 int *n_uids, int *n_sigs, int *n_subk );
-static int append_uid (kbnode_t keyblock, kbnode_t node, int *n_sigs);
+static gpg_error_t append_new_uid (unsigned int options,
+                                   kbnode_t keyblock, kbnode_t node,
+                                   u32 curtime, int origin, const char *url,
+                                   int *n_sigs);
 static int append_key (kbnode_t keyblock, kbnode_t node, int *n_sigs);
 static int merge_sigs (kbnode_t dst, kbnode_t src, int *n_sigs);
 static int merge_keysigs (kbnode_t dst, kbnode_t src, int *n_sigs);
@@ -1381,12 +1386,114 @@ apply_drop_sig_filter (ctrl_t ctrl, kbnode_t keyblock, recsel_expr_t selector)
 }
 
 
+/* Insert a key origin into a public key packet.  */
+static gpg_error_t
+insert_key_origin_pk (PKT_public_key *pk, u32 curtime,
+                      int origin, const char *url)
+{
+  if (origin == KEYORG_WKD || origin == KEYORG_DANE)
+    {
+      /* For WKD and DANE we insert origin information also for the
+       * key but we don't record the URL because we have have no use
+       * for that: An update using a keyserver has higher precedence
+       * and will thus update this origin info.  For refresh using WKD
+       * or DANE we need to go via the User ID anyway.  Recall that we
+       * are only inserting a new key. */
+      pk->keyorg = origin;
+      pk->keyupdate = curtime;
+    }
+  else if (origin == KEYORG_KS && url)
+    {
+      /* If the key was retrieved from a keyserver using a fingerprint
+       * request we add the meta information.  Note that the use of a
+       * fingerprint needs to be enforced by the caller of the import
+       * function.  This is commonly triggered by verifying a modern
+       * signature which has an Issuer Fingerprint signature
+       * subpacket.  */
+      pk->keyorg = origin;
+      pk->keyupdate = curtime;
+      xfree (pk->updateurl);
+      pk->updateurl = xtrystrdup (url);
+      if (!pk->updateurl)
+        return gpg_error_from_syserror ();
+    }
+  else if (origin == KEYORG_FILE)
+    {
+      pk->keyorg = origin;
+      pk->keyupdate = curtime;
+    }
+  else if (origin == KEYORG_URL)
+    {
+      pk->keyorg = origin;
+      pk->keyupdate = curtime;
+      if (url)
+        {
+          xfree (pk->updateurl);
+          pk->updateurl = xtrystrdup (url);
+          if (!pk->updateurl)
+            return gpg_error_from_syserror ();
+        }
+    }
+
+  return 0;
+}
+
+
+/* Insert a key origin into a user id packet.  */
+static gpg_error_t
+insert_key_origin_uid (PKT_user_id *uid, u32 curtime,
+                       int origin, const char *url)
+
+{
+  if (origin == KEYORG_WKD || origin == KEYORG_DANE)
+    {
+      /* We insert origin information on a UID only when we received
+       * them via the Web Key Directory or a DANE record.  The key we
+       * receive here from the WKD has been filtered to contain only
+       * the user ID as looked up in the WKD.  For a DANE origin we
+       * this should also be the case.  Thus we will see here only one
+       * user id.  */
+      uid->keyorg = origin;
+      uid->keyupdate = curtime;
+      if (url)
+        {
+          xfree (uid->updateurl);
+          uid->updateurl = xtrystrdup (url);
+          if (!uid->updateurl)
+            return gpg_error_from_syserror ();
+        }
+    }
+  else if (origin == KEYORG_KS && url)
+    {
+      /* If the key was retrieved from a keyserver using a fingerprint
+       * request we mark that also in the user ID.  However we do not
+       * store the keyserver URL in the UID.  A later update (merge)
+       * from a more trusted source will replace this info.  */
+      uid->keyorg = origin;
+      uid->keyupdate = curtime;
+    }
+  else if (origin == KEYORG_FILE)
+    {
+      uid->keyorg = origin;
+      uid->keyupdate = curtime;
+    }
+  else if (origin == KEYORG_URL)
+    {
+      uid->keyorg = origin;
+      uid->keyupdate = curtime;
+    }
+
+  return 0;
+}
+
+
 /* Apply meta data to KEYBLOCK.  This sets the origin of the key to
  * ORIGIN and the updateurl to URL.  Note that this function is only
  * used for a new key, that is not when we are merging keys.  */
 static gpg_error_t
-apply_meta_data (kbnode_t keyblock, int origin, const char *url)
+insert_key_origin (kbnode_t keyblock, int origin, const char *url)
 {
+  gpg_error_t err;
   kbnode_t node;
   u32 curtime = make_timestamp ();
 
@@ -1396,94 +1503,17 @@ apply_meta_data (kbnode_t keyblock, int origin, const char *url)
         ;
       else if (node->pkt->pkttype == PKT_PUBLIC_KEY)
         {
-          PKT_public_key *pk = node->pkt->pkt.public_key;
-
-          if (origin == KEYORG_WKD || origin == KEYORG_DANE)
-            {
-              /* For WKD and DANE we insert origin information also
-               * for the key but we don't record the URL because we
-               * have have no use for that: An update using a
-               * keyserver has higher precedence and will thus update
-               * this origin info.  For refresh using WKD or DANE we
-               * need to go via the User ID anyway.  Recall that we
-               * are only inserting a new key. */
-              pk->keyorg = origin;
-              pk->keyupdate = curtime;
-            }
-          else if (origin == KEYORG_KS && url)
-            {
-              /* If the key was retrieved from a keyserver using a
-               * fingerprint request we add the meta information.
-               * Note that the use of a fingerprint needs to be
-               * enforced by the caller of the import function.  This
-               * is commonly triggered by verifying a modern signature
-               * which has an Issuer Fingerprint signature
-               * subpacket.  */
-              pk->keyorg = origin;
-              pk->keyupdate = curtime;
-              pk->updateurl = xtrystrdup (url);
-              if (!pk->updateurl)
-                return gpg_error_from_syserror ();
-            }
-          else if (origin == KEYORG_FILE)
-            {
-              pk->keyorg = origin;
-              pk->keyupdate = curtime;
-            }
-          else if (origin == KEYORG_URL)
-            {
-              pk->keyorg = origin;
-              pk->keyupdate = curtime;
-              if (url)
-                {
-                  pk->updateurl = xtrystrdup (url);
-                  if (!pk->updateurl)
-                    return gpg_error_from_syserror ();
-                }
-            }
+          err = insert_key_origin_pk (node->pkt->pkt.public_key, curtime,
+                                      origin, url);
+          if (err)
+            return err;
         }
       else if (node->pkt->pkttype == PKT_USER_ID)
         {
-          PKT_user_id *uid = node->pkt->pkt.user_id;
-
-          if (origin == KEYORG_WKD || origin == KEYORG_DANE)
-            {
-              /* We insert origin information on a UID only when we
-               * received them via the Web Key Directory or a DANE
-               * record.  The key we receive here from the WKD has
-               * been filtered to contain only the user ID as looked
-               * up in the WKD.  For a DANE origin we this should also
-               * be the case.  Thus we will see here only one user
-               * id.  */
-              uid->keyorg = origin;
-              uid->keyupdate = curtime;
-              if (url)
-                {
-                  uid->updateurl = xtrystrdup (url);
-                  if (!uid->updateurl)
-                    return gpg_error_from_syserror ();
-                }
-            }
-          else if (origin == KEYORG_KS && url)
-            {
-              /* If the key was retrieved from a keyserver using a
-               * fingerprint request we mark that also in the user ID.
-               * However we do not store the keyserver URL in the UID.
-               * A later update (merge) from a more trusted source
-               * will replace this info.  */
-              uid->keyorg = origin;
-              uid->keyupdate = curtime;
-            }
-          else if (origin == KEYORG_FILE)
-            {
-              uid->keyorg = origin;
-              uid->keyupdate = curtime;
-            }
-          else if (origin == KEYORG_URL)
-            {
-              uid->keyorg = origin;
-              uid->keyupdate = curtime;
-            }
+          err = insert_key_origin_uid (node->pkt->pkt.user_id, curtime,
+                                       origin, url);
+          if (err)
+            return err;
         }
     }
 
@@ -1724,24 +1754,24 @@ import_one (ctrl_t ctrl,
       if (opt.verbose > 1 )
         log_info (_("writing to '%s'\n"), keydb_get_resource_name (hd) );
 
+      if ((options & IMPORT_CLEAN))
+        clean_key (ctrl, keyblock, opt.verbose, (options&IMPORT_MINIMAL),
+                   &n_uids_cleaned,&n_sigs_cleaned);
+
       /* Unless we are in restore mode apply meta data to the
        * keyblock.  Note that this will never change the first packet
        * and thus the address of KEYBLOCK won't change.  */
       if ( !(options & IMPORT_RESTORE) )
         {
-          rc = apply_meta_data (keyblock, origin, url);
+          rc = insert_key_origin (keyblock, origin, url);
           if (rc)
             {
-              log_error ("apply_meta_data failed: %s\n", gpg_strerror (rc));
+              log_error ("insert_key_origin failed: %s\n", gpg_strerror (rc));
               keydb_release (hd);
               return GPG_ERR_GENERAL;
             }
         }
 
-      if ((options & IMPORT_CLEAN))
-        clean_key (ctrl, keyblock, opt.verbose, (options&IMPORT_MINIMAL),
-                   &n_uids_cleaned,&n_sigs_cleaned);
-
       rc = keydb_insert_keyblock (hd, keyblock );
       if (rc)
         log_error (_("error writing keyring '%s': %s\n"),
@@ -1778,7 +1808,7 @@ import_one (ctrl_t ctrl,
       stats->imported++;
       new_key = 1;
     }
-  else /* merge */
+  else /* Merge the key.  */
     {
       KEYDB_HANDLE hd;
       int n_uids, n_sigs, n_subk, n_sigs_cleaned, n_uids_cleaned;
@@ -1827,8 +1857,9 @@ import_one (ctrl_t ctrl,
       clear_kbnode_flags( keyblock_orig );
       clear_kbnode_flags( keyblock );
       n_uids = n_sigs = n_subk = n_uids_cleaned = 0;
-      rc = merge_blocks (ctrl, keyblock_orig, keyblock,
-                         keyid, &n_uids, &n_sigs, &n_subk );
+      rc = merge_blocks (ctrl, options, keyblock_orig, keyblock, keyid,
+                         origin, url,
+                         &n_uids, &n_sigs, &n_subk );
       if (rc )
         {
           keydb_release (hd);
@@ -3193,11 +3224,14 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock)
  * Note: We indicate newly inserted packets with NODE_FLAG_A.
  */
 static int
-merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
-	      u32 *keyid, int *n_uids, int *n_sigs, int *n_subk )
+merge_blocks (ctrl_t ctrl, unsigned int options,
+              kbnode_t keyblock_orig, kbnode_t keyblock,
+              u32 *keyid, int origin, const char *url,
+	      int *n_uids, int *n_sigs, int *n_subk )
 {
   kbnode_t onode, node;
   int rc, found;
+  u32 curtime = make_timestamp ();
 
   /* 1st: handle revocation certificates */
   for (node=keyblock->next; node; node=node->next )
@@ -3308,7 +3342,8 @@ merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
               break;
           if (!onode ) /* this is a new user id: append */
             {
-              rc = append_uid (keyblock_orig, node, n_sigs);
+              rc = append_new_uid (options, keyblock_orig, node,
+                                   curtime, origin, url, n_sigs);
               if (rc )
                 return rc;
               ++*n_uids;
@@ -3384,17 +3419,23 @@ merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
 
 
 /* Helper function for merge_blocks.
- * Append the userid starting with NODE and all signatures to KEYBLOCK.
+ *
+ * Append the new userid starting with NODE and all signatures to
+ * KEYBLOCK.  ORIGIN and URL conveys the usual key origin info.  The
+ * integer at N_SIGS is updated with the number of new signatures.
  */
-static int
-append_uid (kbnode_t keyblock, kbnode_t node, int *n_sigs)
+static gpg_error_t
+append_new_uid (unsigned int options,
+                kbnode_t keyblock, kbnode_t node, u32 curtime,
+                int origin, const char *url, int *n_sigs)
 {
+  gpg_error_t err;
   kbnode_t n;
   kbnode_t n_where = NULL;
 
-  log_assert (node->pkt->pkttype == PKT_USER_ID );
+  log_assert (node->pkt->pkttype == PKT_USER_ID);
 
-  /* find the position */
+  /* Find the right position for the new user id and its signatures.  */
   for (n = keyblock; n; n_where = n, n = n->next)
     {
       if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY
@@ -3408,8 +3449,17 @@ append_uid (kbnode_t keyblock, kbnode_t node, int *n_sigs)
   while (node)
     {
       /* we add a clone to the original keyblock, because this
-       * one is released first */
+       * one is released first. */
       n = clone_kbnode(node);
+      if (n->pkt->pkttype == PKT_USER_ID
+          && !(options & IMPORT_RESTORE) )
+        {
+          err = insert_key_origin_uid (n->pkt->pkt.user_id,
+                                       curtime, origin, url);
+          if (err)
+            return err;
+        }
+
       if (n_where)
         {
           insert_kbnode( n_where, n, 0 );

-----------------------------------------------------------------------

Summary of changes:
 g10/import.c | 347 +++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 245 insertions(+), 102 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list