gpg: New option --with-key-origin.
authorWerner Koch <wk@gnupg.org>
Thu, 20 Jul 2017 15:27:48 +0000 (17:27 +0200)
committerWerner Koch <wk@gnupg.org>
Thu, 20 Jul 2017 16:13:40 +0000 (18:13 +0200)
* g10/getkey.c (parse_key_origin): Factor list out as ...
(key_origin_list): new struct.
(key_origin_string): New.
* g10/gpg.c (oWithKeyOrigin): New const.
(opts): New option --with-key-origin.
(main): Implement option.
* g10/options.h (struct opt): New flag with_key_origin.
* g10/keylist.c (list_keyblock_print): Print key origin info.
(list_keyblock_colon): Ditto.

doc/DETAILS
doc/gpg.texi
g10/getkey.c
g10/gpg.c
g10/keydb.h
g10/keylist.c
g10/options.h

index 28fb55a..0be55f4 100644 (file)
@@ -241,8 +241,7 @@ described here.
 
     The origin of the key or the user ID.  This is an integer
     optionally followed by a space and an URL.  This goes along with
-    the previous field.  The values are not yet defined.
-
+    the previous field.  The URL is quoted in C style.
 
 ** Special fields
 
index 64dd502..cae351b 100644 (file)
@@ -2531,6 +2531,13 @@ Print the ICAO spelling of the fingerprint in addition to the hex digits.
 Include the keygrip in the key listings.  In @code{--with-colons} mode
 this is implicitly enable for secret keys.
 
+@item --with-key-origin
+@opindex with-key-origin
+Include the locally held information on the origin and last update of
+a key in a key listing.  In @code{--with-colons} mode this is always
+printed.  This data is currently experimental and shall not be
+considered part of the stable API.
+
 @item --with-wkd-hash
 @opindex with-wkd-hash
 Print a Web Key Directory identifier along with each user ID in key
index 2bec984..484063e 100644 (file)
@@ -4300,11 +4300,13 @@ parse_auto_key_locate (char *options)
 }
 
 
-/* Parse the argument for --key-origin.  Return false on error. */
-int
-parse_key_origin (char *string)
-{
-  struct { const char *name; int origin; } list[] = {
+\f
+/* The list of key origins. */
+static struct {
+  const char *name;
+  int origin;
+} key_origin_list[] =
+  {
     { "self",    KEYORG_SELF    },
     { "file",    KEYORG_FILE    },
     { "url",     KEYORG_URL     },
@@ -4314,27 +4316,45 @@ parse_key_origin (char *string)
     { "ks",      KEYORG_KS      },
     { "unknown", KEYORG_UNKNOWN }
   };
+
+/* Parse the argument for --key-origin.  Return false on error. */
+int
+parse_key_origin (char *string)
+{
   int i;
 
   if (!ascii_strcasecmp (string, "help"))
     {
       log_info (_("valid values for option '%s':\n"), "--key-origin");
-      for (i=0; i < DIM (list); i++)
-        log_info ("  %s\n", list[i].name);
+      for (i=0; i < DIM (key_origin_list); i++)
+        log_info ("  %s\n", key_origin_list[i].name);
       g10_exit (1);
     }
 
-  for (i=0; i < DIM (list); i++)
-    if (!ascii_strcasecmp (string, list[i].name))
+  for (i=0; i < DIM (key_origin_list); i++)
+    if (!ascii_strcasecmp (string, key_origin_list[i].name))
       {
-        opt.key_origin = list[i].origin;
+        opt.key_origin = key_origin_list[i].origin;
         return 1;
       }
 
   return 0;
 }
 
+/* Return a string or "?" for the key ORIGIN.  */
+const char *
+key_origin_string (int origin)
+{
+  int i;
 
+  for (i=0; i < DIM (key_origin_list); i++)
+    if (key_origin_list[i].origin == origin)
+      return key_origin_list[i].name;
+  return "?";
+}
+
+
+\f
 /* Returns true if a secret key is available for the public key with
    key id KEYID; returns false if not.  This function ignores legacy
    keys.  Note: this is just a fast check and does not tell us whether
index 5c60e1d..70b8011 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -201,6 +201,7 @@ enum cmd_and_opt_values
     oWithWKDHash,
     oWithColons,
     oWithKeyData,
+    oWithKeyOrigin,
     oWithTofuInfo,
     oWithSigList,
     oWithSigCheck,
@@ -785,6 +786,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oWithKeygrip,     "with-keygrip", "@"),
   ARGPARSE_s_n (oWithSecret,      "with-secret", "@"),
   ARGPARSE_s_n (oWithWKDHash,     "with-wkd-hash", "@"),
+  ARGPARSE_s_n (oWithKeyOrigin,   "with-key-origin", "@"),
   ARGPARSE_s_s (oDisableCipherAlgo,  "disable-cipher-algo", "@"),
   ARGPARSE_s_s (oDisablePubkeyAlgo,  "disable-pubkey-algo", "@"),
   ARGPARSE_s_n (oAllowNonSelfsignedUID,      "allow-non-selfsigned-uid", "@"),
@@ -2733,6 +2735,10 @@ main (int argc, char **argv)
             opt.with_wkd_hash = 1;
             break;
 
+         case oWithKeyOrigin:
+            opt.with_key_origin = 1;
+            break;
+
          case oSecretKeyring:
             /* Ignore this old option.  */
             break;
index 6416e63..15345bb 100644 (file)
@@ -398,6 +398,7 @@ char *get_user_id_byfpr_native (ctrl_t ctrl, const byte *fpr);
 void release_akl(void);
 int parse_auto_key_locate(char *options);
 int parse_key_origin (char *string);
+const char *key_origin_string (int origin);
 
 /*-- keyid.c --*/
 int pubkey_letter( int algo );
index e4d5d06..37a26dc 100644 (file)
@@ -922,6 +922,21 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
   if (opt.with_key_data)
     print_key_data (pk);
 
+  if (opt.with_key_origin
+      && (pk->keyorg || pk->keyupdate || pk->updateurl))
+    {
+      char updatestr[MK_DATESTR_SIZE];
+
+      es_fprintf (es_stdout, "      origin=%s last=%s %s",
+                  key_origin_string (pk->keyorg),
+                  mk_datestr (updatestr, sizeof updatestr, pk->keyupdate),
+                  pk->updateurl? "url=":"");
+      if (pk->updateurl)
+        print_utf8_string (es_stdout, pk->updateurl);
+      es_putc ('\n', es_stdout);
+    }
+
+
   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
     {
       if (node->pkt->pkttype == PKT_USER_ID)
@@ -987,6 +1002,22 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
               xfree (mbox);
             }
 
+          if (opt.with_key_origin
+              && (uid->keyorg || uid->keyupdate || uid->updateurl))
+            {
+              char updatestr[MK_DATESTR_SIZE];
+
+              es_fprintf (es_stdout, "   %*sorigin=%s last=%s %s",
+                          indent, "",
+                          key_origin_string (uid->keyorg),
+                          mk_datestr (updatestr, sizeof updatestr,
+                                      uid->keyupdate),
+                          pk->updateurl? "url=":"");
+              if (pk->updateurl)
+                print_utf8_string (es_stdout, pk->updateurl);
+              es_putc ('\n', es_stdout);
+            }
+
          if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
            show_photos (ctrl, uid->attribs, uid->numattribs, pk, uid);
        }
@@ -1315,7 +1346,13 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
   es_putc (':', es_stdout);            /* End of field 17. */
   print_compliance_flags (pk, keylength, curvename);
   es_putc (':', es_stdout);            /* End of field 18 (compliance). */
+  if (pk->keyupdate)
+    es_fputs (colon_strtime (pk->keyupdate), es_stdout);
   es_putc (':', es_stdout);            /* End of field 19 (last_update). */
+  es_fprintf (es_stdout, "%d%s", pk->keyorg, pk->updateurl? " ":"");
+  if (pk->updateurl)
+    es_write_sanitized (es_stdout, pk->updateurl, strlen (pk->updateurl),
+                        ":", NULL);
   es_putc (':', es_stdout);            /* End of field 20 (origin). */
   es_putc ('\n', es_stdout);
 
@@ -1367,7 +1404,14 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
          else
            es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
          es_fputs (":::::::::", es_stdout);
+          if (uid->keyupdate)
+            es_fputs (colon_strtime (uid->keyupdate), es_stdout);
           es_putc (':', es_stdout);    /* End of field 19 (last_update). */
+          es_fprintf (es_stdout, "%d%s", uid->keyorg, uid->updateurl? " ":"");
+          if (uid->updateurl)
+            es_write_sanitized (es_stdout,
+                                uid->updateurl, strlen (uid->updateurl),
+                                ":", NULL);
           es_putc (':', es_stdout);    /* End of field 20 (origin). */
          es_putc ('\n', es_stdout);
 #ifdef USE_TOFU
index 5bb506e..21249e9 100644 (file)
@@ -85,6 +85,7 @@ struct
   int with_tofu_info;   /* Option --with-tofu_info active.  */
   int with_secret;      /* Option --with-secret active.  */
   int with_wkd_hash;    /* Option --with-wkd-hash.  */
+  int with_key_origin;  /* Option --with-key-origin.  */
   int fingerprint; /* list fingerprints */
   int list_sigs;   /* list signatures */
   int no_armor;