[git] GnuPG - branch, master, updated. gnupg-2.1.21-131-gb55b72b

by Werner Koch cvs at cvs.gnupg.org
Fri Jul 21 18:20:30 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  b55b72bb815ad5870456b89c3a011fa00991b4a8 (commit)
       via  e888f7af6571ecd3994fd55cc18c9e2df7fd0c60 (commit)
       via  5818ff0ae314af08548fcc23df2b807736144a00 (commit)
      from  609bbdf3614fbadeba7a6cbdfdf5004b23516a64 (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 b55b72bb815ad5870456b89c3a011fa00991b4a8
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Jul 21 14:12:55 2017 +0200

    gpg: Extend --quick-set-expire to allow subkey expiration setting.
    
    * g10/keyedit.c (keyedit_quick_set_expire): Add new arg subkeyfprs.
    (menu_expire): Rename arg force_mainkey to unattended and allow
    unattended changing of subkey expiration.
    * g10/gpg.c (main): Extend --quick-set-expire.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/doc/gpg.texi b/doc/gpg.texi
index 8ee745c..1b5dee0 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -663,10 +663,16 @@ supplied passphrase is used for the new key and the agent does not ask
 for it.  To create a key without any protection @code{--passphrase ''}
 may be used.
 
- at item --quick-set-expire @code{fpr} @code{expire}
+ at item --quick-set-expire @var{fpr} @var{expire} [*|@var{subfprs}]
 @opindex quick-set-expire
-Directly set the expiration time of the primary key to @code{expire}.
-To remove the expiration time @code{0} can be used.
+With two arguments given, directly set the expiration time of the
+primary key identified by @var{fpr} to @var{expire}.  To remove the
+expiration time @code{0} can be used.  With three arguments and the
+third given as an asterisk, the expiration time of all non-revoked and
+not yet expired subkeys are set to @var{expire}.  With more than two
+arguments and a list of fingerprints given for @var{subfprs}, all
+non-revoked subkeys matching these fingerprints are set to
+ at var{expire}.
 
 
 @item --quick-add-key @code{fpr} [@code{algo} [@code{usage} [@code{expire}]]]
diff --git a/g10/gpg.c b/g10/gpg.c
index 70b8011..e32e14a 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -4491,11 +4491,11 @@ main (int argc, char **argv)
         {
           const char *x_fpr, *x_expire;
 
-          if (argc != 2)
-            wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE");
+          if (argc < 2)
+            wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE [SUBKEY-FPRS]");
           x_fpr = *argv++; argc--;
           x_expire = *argv++; argc--;
-          keyedit_quick_set_expire (ctrl, x_fpr, x_expire);
+          keyedit_quick_set_expire (ctrl, x_fpr, x_expire, argv);
         }
 	break;
 
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 29fe466..0a90cf5 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -73,7 +73,7 @@ static int menu_clean (ctrl_t ctrl, kbnode_t keyblock, int self_only);
 static void menu_delkey (KBNODE pub_keyblock);
 static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive);
 static gpg_error_t menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
-                                int force_mainkey, u32 newexpiration);
+                                int unattended, u32 newexpiration);
 static int menu_changeusage (ctrl_t ctrl, kbnode_t keyblock);
 static int menu_backsign (ctrl_t ctrl, kbnode_t pub_keyblock);
 static int menu_set_primary_uid (ctrl_t ctrl, kbnode_t pub_keyblock);
@@ -2808,18 +2808,24 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr,
 }
 
 
-/* Unattended expiration setting function for the main key.
- *
+/* Unattended expiration setting function for the main key.  If
+ * SUBKEYFPRS is not NULL and SUBKEYSFPRS[0] is neither NULL, it is
+ * expected to be an array of fingerprints for subkeys to change. It
+ * may also be an array which just one item "*" to indicate that all
+ * keys shall be set to that expiration date.
  */
 void
-keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr)
+keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr,
+                          char **subkeyfprs)
 {
   gpg_error_t err;
-  kbnode_t keyblock;
+  kbnode_t keyblock, node;
   KEYDB_HANDLE kdbhd;
   int modified = 0;
   PKT_public_key *pk;
   u32 expire;
+  int primary_only = 0;
+  int idx;
 
 #ifdef HAVE_W32_SYSTEM
   /* See keyedit_menu for why we need this.  */
@@ -2846,7 +2852,6 @@ keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr)
       goto leave;
     }
 
-
   expire = parse_expire_string (expirestr);
   if (expire == (u32)-1 )
     {
@@ -2857,8 +2862,78 @@ keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr)
   if (expire)
     expire += make_timestamp ();
 
+  /* Check whether a subkey's expiration time shall be changed or the
+   * expiration time of all keys.  */
+  if (!subkeyfprs || !subkeyfprs[0])
+    primary_only = 1;
+  else if ( !strcmp (subkeyfprs[0], "*") && !subkeyfprs[1])
+    {
+      /* Change all subkeys keys which have not been revoked and are
+       * not yet expired.  */
+      merge_keys_and_selfsig (ctrl, keyblock);
+      for (node = keyblock; node; node = node->next)
+        {
+          if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+              && (pk = node->pkt->pkt.public_key)
+              && !pk->flags.revoked
+              && !pk->has_expired)
+            node->flag |= NODFLG_SELKEY;
+        }
+    }
+  else
+    {
+      /* Change specified subkeys.  */
+      KEYDB_SEARCH_DESC desc;
+      byte fprbin[MAX_FINGERPRINT_LEN];
+      size_t fprlen;
+
+      err = 0;
+      merge_keys_and_selfsig (ctrl, keyblock);
+      for (idx=0; subkeyfprs[idx]; idx++)
+        {
+          int any = 0;
+
+          /* Parse the fingerprint.  */
+          if (classify_user_id (subkeyfprs[idx], &desc, 1)
+              || !(desc.mode == KEYDB_SEARCH_MODE_FPR
+                   || desc.mode == KEYDB_SEARCH_MODE_FPR20))
+            {
+              log_error (_("\"%s\" is not a proper fingerprint\n"),
+                         subkeyfprs[idx] );
+              if (!err)
+                err = gpg_error (GPG_ERR_INV_NAME);
+              continue;
+            }
+
+          /* Set the flag for the matching non revoked subkey.  */
+          for (node = keyblock; node; node = node->next)
+            {
+              if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+                  && (pk = node->pkt->pkt.public_key)
+                  && !pk->flags.revoked )
+                {
+                  fingerprint_from_pk (pk, fprbin, &fprlen);
+                  if (fprlen == 20 && !memcmp (fprbin, desc.u.fpr, 20))
+                    {
+                      node->flag |= NODFLG_SELKEY;
+                      any = 1;
+                    }
+                }
+            }
+          if (!any)
+            {
+              log_error (_("subkey \"%s\" not found\n"), subkeyfprs[idx]);
+              if (!err)
+                err = gpg_error (GPG_ERR_NOT_FOUND);
+            }
+        }
+
+      if (err)
+        goto leave;
+    }
+
   /* Set the new expiration date.  */
-  err = menu_expire (ctrl, keyblock, 1, expire);
+  err = menu_expire (ctrl, keyblock, primary_only? 1 : 2, expire);
   if (gpg_err_code (err) == GPG_ERR_TRUE)
     modified = 1;
   else if (err)
@@ -4283,30 +4358,34 @@ fail:
 
 
 /* With FORCE_MAINKEY cleared this function handles the interactive
- * menu option "expire".  With FORCE_MAINKEY set this functions only
+ * menu option "expire".  With UNATTENDED set to 1 this function only
  * sets the expiration date of the primary key to NEWEXPIRATION and
- * avoid all interactivity.  Retirns 0 if nothing was done,
+ * avoid all interactivity; with a value of 2 only the flagged subkeys
+ * are set to NEWEXPIRATION.  Returns 0 if nothing was done,
  * GPG_ERR_TRUE if the key was modified, or any other error code. */
 static gpg_error_t
 menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
-             int force_mainkey, u32 newexpiration)
+             int unattended, u32 newexpiration)
 {
   int signumber, rc;
   u32 expiredate;
-  int mainkey = 0;
+  int only_mainkey;  /* Set if only the mainkey is to be updated.  */
   PKT_public_key *main_pk, *sub_pk;
   PKT_user_id *uid;
   kbnode_t node;
   u32 keyid[2];
 
-  if (force_mainkey)
+  if (unattended)
     {
-      mainkey = 1;
+      only_mainkey = (unattended == 1);
       expiredate = newexpiration;
     }
   else
     {
-      int n1 = count_selected_keys (pub_keyblock);
+      int n1;
+
+      only_mainkey = 0;
+      n1 = count_selected_keys (pub_keyblock);
       if (n1 > 1)
         {
           if (!cpr_get_answer_is_yes
@@ -4320,7 +4399,7 @@ menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
       else
         {
           tty_printf (_("Changing expiration time for the primary key.\n"));
-          mainkey = 1;
+          only_mainkey = 1;
           no_primary_warning (pub_keyblock);
         }
 
@@ -4342,8 +4421,10 @@ menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
 	}
       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
 	{
-          if ((node->flag & NODFLG_SELKEY) && !force_mainkey)
+          if ((node->flag & NODFLG_SELKEY) && unattended != 1)
             {
+              /* The flag is set and we do not want to set the
+               * expiration date only for the main key.  */
               sub_pk = node->pkt->pkt.public_key;
               sub_pk->expiredate = expiredate;
             }
@@ -4353,14 +4434,14 @@ menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
       else if (node->pkt->pkttype == PKT_USER_ID)
 	uid = node->pkt->pkt.user_id;
       else if (main_pk && node->pkt->pkttype == PKT_SIGNATURE
-	       && (mainkey || sub_pk))
+	       && (only_mainkey || sub_pk))
 	{
 	  PKT_signature *sig = node->pkt->pkt.signature;
 
 	  if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
-	      && ((mainkey && uid
+	      && ((only_mainkey && uid
 		   && uid->created && (sig->sig_class & ~3) == 0x10)
-		  || (!mainkey && sig->sig_class == 0x18))
+		  || (!only_mainkey && sig->sig_class == 0x18))
 	      && sig->flags.chosen_selfsig)
 	    {
 	      /* This is a self-signature which is to be replaced.  */
@@ -4369,15 +4450,15 @@ menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
 
 	      signumber++;
 
-	      if ((mainkey && main_pk->version < 4)
-		  || (!mainkey && sub_pk->version < 4))
+	      if ((only_mainkey && main_pk->version < 4)
+		  || (!only_mainkey && sub_pk->version < 4))
 		{
 		  log_info
                     (_("You can't change the expiration date of a v3 key\n"));
 		  return gpg_error (GPG_ERR_LEGACY_KEY);
 		}
 
-	      if (mainkey)
+	      if (only_mainkey)
 		rc = update_keysig_packet (ctrl,
                                            &newsig, sig, main_pk, uid, NULL,
 					   main_pk, keygen_add_key_expire,
diff --git a/g10/keyedit.h b/g10/keyedit.h
index d4c9632..23a126b 100644
--- a/g10/keyedit.h
+++ b/g10/keyedit.h
@@ -46,7 +46,8 @@ void keyedit_quick_revuid (ctrl_t ctrl, const char *username,
 void keyedit_quick_sign (ctrl_t ctrl, const char *fpr,
                          strlist_t uids, strlist_t locusr, int local);
 void keyedit_quick_set_expire (ctrl_t ctrl,
-                               const char *fpr, const char *expirestr);
+                               const char *fpr, const char *expirestr,
+                               char **subkeyfprs);
 void keyedit_quick_set_primary (ctrl_t ctrl, const char *username,
                                 const char *primaryuid);
 void show_basic_key_info (ctrl_t ctrl, kbnode_t keyblock);

commit e888f7af6571ecd3994fd55cc18c9e2df7fd0c60
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Jul 21 17:48:40 2017 +0200

    gpg: Fix possible double free of the card serialno.
    
    * g10/free-packet.c (copy_public_key): Copy fields serialno and
    updateurl.
    --
    
    The PK->serialno is used to get the version of the card to decide
    whether it does support other algorithms than SHA-1.  This value is
    cached but no deep copy was done when calling copy_public_key.
    
    Bug detected by importing some public keys and then importing a secret
    key which led to a double free.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/free-packet.c b/g10/free-packet.c
index cd222a2..e15ad3f 100644
--- a/g10/free-packet.c
+++ b/g10/free-packet.c
@@ -224,6 +224,12 @@ copy_public_key (PKT_public_key *d, PKT_public_key *s)
     }
   else
     d->revkey = NULL;
+
+  if (s->serialno)
+    d->serialno = xstrdup (s->serialno);
+  if (s->updateurl)
+    d->updateurl = xstrdup (s->updateurl);
+
   return d;
 }
 

commit 5818ff0ae314af08548fcc23df2b807736144a00
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Jul 21 17:38:03 2017 +0200

    gpg: Use macros to check the signature class.
    
    * g10/import.c: Use the extistin macros for better readability.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/import.c b/g10/import.c
index c450367..02440ff 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -575,7 +575,7 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct import_stats_s *stats,
                                 opt.batch, options, 0,
                                 screener, screener_arg);
       else if (keyblock->pkt->pkttype == PKT_SIGNATURE
-               && keyblock->pkt->pkt.signature->sig_class == 0x20 )
+               && IS_KEY_REV (keyblock->pkt->pkt.signature) )
         rc = import_revoke_cert (ctrl, keyblock, stats);
       else
         {
@@ -822,7 +822,7 @@ read_block( IOBUF a, int with_meta,
         in_v3key = 0;
 
 	if (!root && pkt->pkttype == PKT_SIGNATURE
-		  && pkt->pkt.signature->sig_class == 0x20 )
+            && IS_KEY_REV (pkt->pkt.signature) )
           {
 	    /* This is a revocation certificate which is handled in a
 	     * special way.  */
@@ -925,7 +925,7 @@ fix_pks_corruption (ctrl_t ctrl, kbnode_t keyblock)
 	    sknode=node;
 	}
       else if (node->pkt->pkttype == PKT_SIGNATURE
-               && node->pkt->pkt.signature->sig_class == 0x18
+               && IS_SUBKEY_SIG (node->pkt->pkt.signature)
                && keycount >= 2
                && !node->next)
 	{
@@ -2398,7 +2398,7 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats)
 
   log_assert (!node->next );
   log_assert (node->pkt->pkttype == PKT_SIGNATURE );
-  log_assert (node->pkt->pkt.signature->sig_class == 0x20 );
+  log_assert (IS_KEY_REV (node->pkt->pkt.signature));
 
   keyid[0] = node->pkt->pkt.signature->keyid[0];
   keyid[1] = node->pkt->pkt.signature->keyid[1];
@@ -2451,8 +2451,8 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, struct import_stats_s *stats)
     }
 
   /* it is okay, that node is not in keyblock because
-   * check_key_signature works fine for sig_class 0x20 in this
-   * special case. */
+   * check_key_signature works fine for sig_class 0x20 (KEY_REV) in
+   * this special case. */
   rc = check_key_signature (ctrl, keyblock, node, NULL);
   if (rc )
     {
@@ -2797,7 +2797,7 @@ delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
           delete_kbnode( node );
         }
       else if (node->pkt->pkttype == PKT_SIGNATURE
-               && node->pkt->pkt.signature->sig_class == 0x20)
+               && IS_KEY_REV (node->pkt->pkt.signature))
         {
           if (uid_seen )
             {
@@ -2829,8 +2829,8 @@ delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
 	    }
 	}
       else if (node->pkt->pkttype == PKT_SIGNATURE
-               && (node->pkt->pkt.signature->sig_class == 0x18
-                   || node->pkt->pkt.signature->sig_class == 0x28)
+               && (IS_SUBKEY_SIG (node->pkt->pkt.signature)
+                   || IS_SUBKEY_REV (node->pkt->pkt.signature))
                && !subkey_seen )
         {
           if(opt.verbose)
@@ -3006,9 +3006,9 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock)
       if(onode->pkt->pkttype==PKT_USER_ID)
 	break;
 
-      if(onode->pkt->pkttype==PKT_SIGNATURE &&
-	 onode->pkt->pkt.signature->sig_class==0x1F &&
-	 onode->pkt->pkt.signature->revkey)
+      if (onode->pkt->pkttype == PKT_SIGNATURE
+          && IS_KEY_SIG (onode->pkt->pkt.signature)
+          && onode->pkt->pkt.signature->revkey)
 	{
 	  int idx;
 	  PKT_signature *sig=onode->pkt->pkt.signature;
@@ -3026,14 +3026,14 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock)
 		  if(inode->pkt->pkttype==PKT_USER_ID)
 		    break;
 
-		  if(inode->pkt->pkttype==PKT_SIGNATURE &&
-		     inode->pkt->pkt.signature->sig_class==0x20 &&
-		     inode->pkt->pkt.signature->keyid[0]==keyid[0] &&
-		     inode->pkt->pkt.signature->keyid[1]==keyid[1])
+		  if (inode->pkt->pkttype == PKT_SIGNATURE
+                      && IS_KEY_REV (inode->pkt->pkt.signature)
+                      && inode->pkt->pkt.signature->keyid[0]==keyid[0]
+                      && inode->pkt->pkt.signature->keyid[1]==keyid[1])
 		    {
 		      /* Okay, we have a revocation key, and a
-                         revocation issued by it.  Do we have the key
-                         itself? */
+                       * revocation issued by it.  Do we have the key
+                       * itself?  */
 		      int rc;
 
 		      rc=get_pubkey_byfprint_fast (NULL,sig->revkey[idx].fpr,
@@ -3102,7 +3102,7 @@ merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
       if (node->pkt->pkttype == PKT_USER_ID )
         break;
       else if (node->pkt->pkttype == PKT_SIGNATURE
-               && node->pkt->pkt.signature->sig_class == 0x20)
+               && IS_KEY_REV (node->pkt->pkt.signature))
         {
           /* check whether we already have this */
           found = 0;
@@ -3111,7 +3111,7 @@ merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
               if (onode->pkt->pkttype == PKT_USER_ID )
                 break;
               else if (onode->pkt->pkttype == PKT_SIGNATURE
-                       && onode->pkt->pkt.signature->sig_class == 0x20
+                       && IS_KEY_REV (onode->pkt->pkt.signature)
                        && !cmp_signatures(onode->pkt->pkt.signature,
                                           node->pkt->pkt.signature))
                 {
@@ -3142,7 +3142,7 @@ merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
       if (node->pkt->pkttype == PKT_USER_ID )
         break;
       else if (node->pkt->pkttype == PKT_SIGNATURE
-               && node->pkt->pkt.signature->sig_class == 0x1F)
+               && IS_KEY_SIG (node->pkt->pkt.signature))
         {
           /* check whether we already have this */
           found = 0;
@@ -3151,7 +3151,7 @@ merge_blocks (ctrl_t ctrl, kbnode_t keyblock_orig, kbnode_t keyblock,
               if (onode->pkt->pkttype == PKT_USER_ID)
                 break;
               else if (onode->pkt->pkttype == PKT_SIGNATURE
-                       && onode->pkt->pkt.signature->sig_class == 0x1F
+                       && IS_KEY_SIG (onode->pkt->pkt.signature)
                        && !cmp_signatures(onode->pkt->pkt.signature,
                                           node->pkt->pkt.signature))
                 {
@@ -3345,8 +3345,8 @@ merge_sigs (kbnode_t dst, kbnode_t src, int *n_sigs)
     {
       if (n->pkt->pkttype != PKT_SIGNATURE )
         continue;
-      if (n->pkt->pkt.signature->sig_class == 0x18
-          || n->pkt->pkt.signature->sig_class == 0x28 )
+      if (IS_SUBKEY_SIG (n->pkt->pkt.signature)
+          || IS_SUBKEY_REV (n->pkt->pkt.signature) )
         continue; /* skip signatures which are only valid on subkeys */
 
       found = 0;

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

Summary of changes:
 doc/gpg.texi      |  12 ++++--
 g10/free-packet.c |   6 +++
 g10/gpg.c         |   6 +--
 g10/import.c      |  48 ++++++++++-----------
 g10/keyedit.c     | 125 ++++++++++++++++++++++++++++++++++++++++++++----------
 g10/keyedit.h     |   3 +-
 6 files changed, 147 insertions(+), 53 deletions(-)


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




More information about the Gnupg-commits mailing list