Adjust for changed macro names in libgpg-error master.
[gnupg.git] / g10 / keylist.c
index cc5009d..bcbad45 100644 (file)
@@ -44,6 +44,8 @@
 #include "../common/mbox-util.h"
 #include "../common/zb32.h"
 #include "tofu.h"
+#include "../common/compliance.h"
+#include "../common/pkscreening.h"
 
 
 static void list_all (ctrl_t, int, int);
@@ -192,7 +194,7 @@ print_seckey_info (ctrl_t ctrl, PKT_public_key *pk)
 }
 
 /* Print information about the public key.  With FP passed as NULL,
-   the tty output interface is used, otherwise output is directted to
+   the tty output interface is used, otherwise output is directed to
    the given stream.  */
 void
 print_pubkey_info (ctrl_t ctrl, estream_t fp, PKT_public_key *pk)
@@ -375,7 +377,7 @@ show_keyserver_url (PKT_signature * sig, int indent, int mode)
          if (mode > 0)
            log_info ("%s", str);
          else
-           tty_fprintf (es_stdout, "%s", str);
+           tty_fprintf (fp, "%s", str);
          tty_print_utf8_string2 (fp, p, len, 0);
          tty_fprintf (fp, "\n");
        }
@@ -428,7 +430,7 @@ show_notation (PKT_signature * sig, int indent, int mode, int which)
              if (mode > 0)
                log_info ("%s", str);
              else
-               tty_fprintf (es_stdout, "%s", str);
+               tty_fprintf (fp, "%s", str);
              /* This is all UTF8 */
              tty_print_utf8_string2 (fp, nd->name, strlen (nd->name), 0);
              tty_fprintf (fp, "=");
@@ -596,7 +598,7 @@ list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret)
     listctx.check_sigs = 1;
 
   /* fixme: using the bynames function has the disadvantage that we
-   * don't know wether one of the names given was not found.  OTOH,
+   * don't know whether one of the names given was not found.  OTOH,
    * this function has the advantage to list the names in the
    * sequence as defined by the keyDB and does not duplicate
    * outputs.  A solution could be do test whether all given have
@@ -608,7 +610,7 @@ list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret)
   if (rc)
     {
       log_error ("error reading key: %s\n", gpg_strerror (rc));
-      getkey_end (ctx);
+      getkey_end (ctrl, ctx);
       return;
     }
 
@@ -627,7 +629,7 @@ list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret)
       release_kbnode (keyblock);
     }
   while (!getkey_next (ctrl, ctx, NULL, &keyblock));
-  getkey_end (ctx);
+  getkey_end (ctrl, ctx);
 
   if (opt.check_sigs && !opt.with_colons)
     print_signature_stats (&listctx);
@@ -668,7 +670,7 @@ locate_one (ctrl_t ctrl, strlist_t names)
              release_kbnode (keyblock);
            }
          while (ctx && !getkey_next (ctrl, ctx, NULL, &keyblock));
-         getkey_end (ctx);
+         getkey_end (ctrl, ctx);
          ctx = NULL;
        }
     }
@@ -695,6 +697,37 @@ print_key_data (PKT_public_key * pk)
     }
 }
 
+
+/* Various public key screenings.  (Right now just ROCA).  With
+ * COLON_MODE set the output is formatted for use in the compliance
+ * field of a colon listing.
+ */
+static void
+print_pk_screening (PKT_public_key *pk, int colon_mode)
+{
+  gpg_error_t err;
+
+  if (is_RSA (pk->pubkey_algo) && pubkey_get_npkey (pk->pubkey_algo))
+    {
+      err = screen_key_for_roca (pk->pkey[0]);
+      if (!err)
+        ;
+      else if (gpg_err_code (err) == GPG_ERR_TRUE)
+        {
+          if (colon_mode)
+            es_fprintf (es_stdout, colon_mode > 1? " %d":"%d", 6001);
+          else
+            es_fprintf (es_stdout,
+                        "      Screening: ROCA vulnerability detected\n");
+        }
+      else if (!colon_mode)
+        es_fprintf (es_stdout, "      Screening: [ROCA check failed: %s]\n",
+                    gpg_strerror (err));
+    }
+
+}
+
+
 static void
 print_capabilities (ctrl_t ctrl, PKT_public_key *pk, KBNODE keyblock)
 {
@@ -921,6 +954,24 @@ 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_screening)
+    print_pk_screening (pk, 0);
+
+  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)
@@ -986,6 +1037,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),
+                          uid->updateurl? "url=":"");
+              if (uid->updateurl)
+                print_utf8_string (es_stdout, uid->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);
        }
@@ -1016,7 +1083,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
               if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
                 secret = serialno? 3 : 1;
               else
-                secret = '2';  /* Key not found.  */
+                secret = 2;  /* Key not found.  */
             }
 
           /* Print the "sub" line.  */
@@ -1031,6 +1098,8 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
             es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
          if (opt.with_key_data)
            print_key_data (pk2);
+          if (opt.with_key_screening)
+            print_pk_screening (pk2, 0);
        }
       else if (opt.list_sigs
               && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
@@ -1180,16 +1249,24 @@ print_compliance_flags (PKT_public_key *pk,
 {
   int any = 0;
 
+  if (!keylength)
+    keylength = nbits_from_pk (pk);
+
   if (pk->version == 5)
     {
-      es_fputs ("8", es_stdout);
+      es_fputs (gnupg_status_compliance_flag (CO_GNUPG), es_stdout);
       any++;
     }
-  if (gnupg_pk_is_compliant (CO_DE_VS, pk, keylength, curvename))
+  if (gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
+                            keylength, curvename))
     {
-      es_fputs (any? " 23":"23", es_stdout);
+      es_fprintf (es_stdout, any ? " %s" : "%s",
+                 gnupg_status_compliance_flag (CO_DE_VS));
       any++;
     }
+
+  if (opt.with_key_screening)
+    print_pk_screening (pk, 1+any);
 }
 
 
@@ -1309,7 +1386,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);
 
@@ -1361,7 +1444,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
@@ -1856,6 +1946,9 @@ print_card_serialno (const char *serialno)
  * pub   dsa2048 2007-12-31 [SC] [expires: 2018-12-31]
  *       80615870F5BAD690333686D0F2AD85AC1E42B367
  *
+ * pub   rsa2048 2017-12-31 [SC] [expires: 2028-12-31]
+ *       80615870F5BAD690333686D0F2AD85AC1E42B3671122334455
+ *
  * Some global options may result in a different output format.  If
  * SECRET is set, "sec" or "ssb" is used instead of "pub" or "sub" and
  * depending on the value a flag character is shown: