[git] GnuPG - branch, master, updated. gnupg-2.2.7-337-g9325c92

by Werner Koch cvs at cvs.gnupg.org
Tue Jan 29 09:32:41 CET 2019


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  9325c92284bb346d11c3591bb2ea88095989361a (commit)
       via  237880175f59d372011cd2e20bb49726eeccf058 (commit)
      from  02a2633a7f0b7d91aa48ea615fb3a0edfd6ed6bb (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 9325c92284bb346d11c3591bb2ea88095989361a
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Jan 29 09:30:15 2019 +0100

    card: Print keyinfo for PIV cards.
    
    * scd/app-piv.c (do_learn_status): Print CHV-STATUS.
    * tools/card-tool.h (struct card_info_s): Rename chvretry to chvinfo.
    * tools/card-call-scd.c (learn_status_cb): Depend CHV-STATUS on app
    type.
    * tools/gpg-card-tool.c (list_piv): New.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/scd/app-piv.c b/scd/app-piv.c
index 011b552..69f12f4 100644
--- a/scd/app-piv.c
+++ b/scd/app-piv.c
@@ -569,7 +569,7 @@ send_keypair_and_cert_info (app_t app, ctrl_t ctrl, data_object_t dobj,
 }
 
 
-/* Handle the LEARN command for OpenPGP.  */
+/* Handle the LEARN command.  */
 static gpg_error_t
 do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
 {
@@ -577,10 +577,13 @@ do_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
 
   (void)flags;
 
+  do_getattr (app, ctrl, "CHV-STATUS");
+
   for (i=0; data_objects[i].tag; i++)
     if (data_objects[i].keypair)
       send_keypair_and_cert_info (app, ctrl, data_objects + i, !!(flags & 1));
 
+
   return 0;
 }
 
diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c
index abf35ed..2551b19 100644
--- a/tools/card-call-scd.c
+++ b/tools/card-call-scd.c
@@ -808,9 +808,13 @@ learn_status_cb (void *opaque, const char *line)
 
           buf = p = unescape_status_string (line);
           if (buf)
+            while (spacep (p))
+              p++;
+
+          if (!buf)
+            ;
+          else if (parm->apptype == APP_TYPE_OPENPGP)
             {
-              while (spacep (p))
-                p++;
               parm->chv1_cached = atoi (p);
               while (*p && !spacep (p))
                 p++;
@@ -826,14 +830,26 @@ learn_status_cb (void *opaque, const char *line)
                 }
               for (i=0; *p && i < 3; i++)
                 {
-                  parm->chvretry[i] = atoi (p);
+                  parm->chvinfo[i] = atoi (p);
+                  while (*p && !spacep (p))
+                    p++;
+                  while (spacep (p))
+                    p++;
+                }
+            }
+          else if (parm->apptype == APP_TYPE_PIV)
+            {
+              for (i=0; *p && DIM (parm->chvinfo); i++)
+                {
+                  parm->chvinfo[i] = atoi (p);
                   while (*p && !spacep (p))
                     p++;
                   while (spacep (p))
                     p++;
                 }
-              xfree (buf);
             }
+
+          xfree (buf);
         }
       break;
 
diff --git a/tools/card-tool.h b/tools/card-tool.h
index 0af6186..bcc257c 100644
--- a/tools/card-tool.h
+++ b/tools/card-tool.h
@@ -122,12 +122,12 @@ struct card_info_s
   char cafpr3[20];
   key_info_t kinfo;  /* Linked list with all keypair related data.  */
   unsigned long sig_counter;
-  int chv1_cached;   /* True if a PIN is not required for each
-                        signing.  Note that the gpg-agent might cache
-                        it anyway. */
-  int is_v2;         /* True if this is a v2 card.  */
+  int chv1_cached;   /* For openpgp this is true if a PIN is not
+                        required for each signing.  Note that the
+                        gpg-agent might cache it anyway. */
+  int is_v2;         /* True if this is a v2 openpgp card.  */
   int chvmaxlen[3];  /* Maximum allowed length of a CHV. */
-  int chvretry[3];   /* Allowed retries for the CHV; 0 = blocked. */
+  int chvinfo[3];    /* Allowed retries for the CHV; 0 = blocked. */
   struct key_attr key_attr[3]; /* OpenPGP card key attributes.  */
   struct {
     unsigned int ki:1;     /* Key import available.  */
diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c
index 31d9c22..5ba44fc 100644
--- a/tools/gpg-card-tool.c
+++ b/tools/gpg-card-tool.c
@@ -723,7 +723,7 @@ list_openpgp (card_info_t info, estream_t fp)
   tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n",
                info->chvmaxlen[0], info->chvmaxlen[1], info->chvmaxlen[2]);
   tty_fprintf (fp, "PIN retry counter : %d %d %d\n",
-               info->chvretry[0], info->chvretry[1], info->chvretry[2]);
+               info->chvinfo[0], info->chvinfo[1], info->chvinfo[2]);
   tty_fprintf (fp, "Signature counter : %lu\n", info->sig_counter);
   if (info->extcap.kdf)
     {
@@ -758,6 +758,44 @@ list_openpgp (card_info_t info, estream_t fp)
 }
 
 
+/* List PIV card specific data.  */
+static void
+list_piv (card_info_t info, estream_t fp)
+{
+  static struct keyinfolabel_s keyinfolabels[] = {
+    { "PIV Authentication:", "PIV.9A" },
+    { "Card Authenticat. :", "PIV.9E" },
+    { "Digital Signature :", "PIV.9C" },
+    { "Key Management ...:", "PIV.9D" },
+    { NULL, NULL }
+  };
+  const char *s;
+  int i;
+
+  tty_fprintf (fp, "PIN retry counter :");
+  for (i=0; i < DIM (info->chvinfo); i++)
+    {
+      if (info->chvinfo[i] > 0)
+        tty_fprintf (fp, " %d", info->chvinfo[i]);
+      else
+        {
+          switch (info->chvinfo[i])
+            {
+            case -1: s = "[error]"; break;
+            case -2: s = "-"; break;  /* No such PIN */
+            case -3: s = "[blocked]"; break;
+            case -5: s = "[verified]"; break;
+            default: s = "[?]"; break;
+            }
+          tty_fprintf (fp, " %s", s);
+        }
+    }
+  tty_fprintf (fp, "\n", s);
+  list_all_kinfo (info, keyinfolabels, fp);
+
+}
+
+
 /* Print all available information about the current card. */
 static void
 list_card (card_info_t info)
@@ -781,6 +819,7 @@ list_card (card_info_t info)
   switch (info->apptype)
     {
     case APP_TYPE_OPENPGP: list_openpgp (info, fp); break;
+    case APP_TYPE_PIV:     list_piv (info, fp); break;
     default: break;
     }
 }
@@ -1740,7 +1779,7 @@ cmd_unblock (card_info_t info)
 
   if (info->apptype == APP_TYPE_OPENPGP && !info->is_v2)
     log_error (_("This command is only available for version 2 cards\n"));
-  else if (info->apptype == APP_TYPE_OPENPGP && !info->chvretry[1])
+  else if (info->apptype == APP_TYPE_OPENPGP && !info->chvinfo[1])
     log_error (_("Reset Code not or not anymore available\n"));
   else if (info->apptype == APP_TYPE_OPENPGP)
     {

commit 237880175f59d372011cd2e20bb49726eeccf058
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Jan 29 08:48:53 2019 +0100

    card: Make printing of key information more flexible.
    
    * tools/card-tool-misc.c: New.
    * tools/card-tool.h: Rewored data structures for key infos.
    * tools/gpg-card-tool.c: Ditto.
    * tools/card-call-scd.c: Ditto.
    --
    
    Note that this also changes the way the key information is printed.
    Formerly we printed it like:
    
      Signature key ....: <openpgp-fingerprint>
            created ....: <timestamp>
            keygrip ... : <keygrip>
    
    now we do:
    
      Signature key ....: <keygrip>
            fingerprint : <openpgp-fingerprint>
            created ....: <timestamp>
    
    This is because a keygrip is always available but a fingerprint and
    the creation date are properties of an OpenPGP card.  A standard way
    of listing keys is better than one depending on the type of card.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/tools/Makefile.am b/tools/Makefile.am
index e29e6a2..f74221b 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -123,7 +123,13 @@ gpg_connect_agent_LDADD = ../common/libgpgrl.a $(common_libs) \
                           $(LIBREADLINE) $(LIBINTL) $(NETLIBS) $(LIBICONV) \
                           $(gpg_connect_agent_rc_objs)
 
-gpg_card_tool_SOURCES   = gpg-card-tool.c card-tool.h card-call-scd.c
+
+gpg_card_tool_SOURCES   = \
+	gpg-card-tool.c \
+	card-tool.h     \
+	card-call-scd.c \
+	card-tool-misc.c
+
 gpg_card_tool_LDADD     = ../common/libgpgrl.a $(common_libs) \
 	                  $(LIBASSUAN_LIBS) $(LIBGCRYPT_LIBS) \
 			  $(GPG_ERROR_LIBS) \
diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c
index 7df7861..abf35ed 100644
--- a/tools/card-call-scd.c
+++ b/tools/card-call-scd.c
@@ -132,6 +132,7 @@ release_card_info (card_info_t info)
 {
   int i;
 
+
   if (!info)
     return;
 
@@ -145,12 +146,18 @@ release_card_info (card_info_t info)
   xfree (info->pubkey_url); info->pubkey_url = NULL;
   xfree (info->login_data); info->login_data = NULL;
   info->cafpr1len = info->cafpr2len = info->cafpr3len = 0;
-  info->fpr1len = info->fpr2len = info->fpr3len = 0;
   for (i=0; i < DIM(info->private_do); i++)
     {
       xfree (info->private_do[i]);
       info->private_do[i] = NULL;
     }
+  while (info->kinfo)
+    {
+      key_info_t kinfo = info->kinfo->next;
+      xfree (info->kinfo);
+      info->kinfo = kinfo;
+    }
+
 }
 
 
@@ -534,6 +541,48 @@ get_serialno_cb (void *opaque, const char *line)
 }
 
 
+
+/* For historical reasons OpenPGP cards simply use the numbers 1 to 3
+ * for the <keyref>.  Other cards and future versions of
+ * scd/app-openpgp.c may print the full keyref; i.e. "OpenPGP.1"
+ * instead of "1".  This is a helper to cope with that. */
+static const char *
+parse_keyref_helper (const char *string)
+{
+  if (*string == '1' && spacep (string+1))
+    return "OPENPGP.1";
+  else if (*string == '2' && spacep (string+1))
+    return "OPENPGP.2";
+  else if (*string == '3' && spacep (string+1))
+    return "OPENPGP.3";
+  else
+    return string;
+}
+
+
+/* Create a new key info object with KEYREF.  All fields but the
+ * keyref are zeroed out.  Never returns NULL.  The created object is
+ * appended to the list at INFO. */
+static key_info_t
+create_kinfo (card_info_t info, const char *keyref)
+{
+  key_info_t kinfo, ki;
+
+  kinfo = xcalloc (1, sizeof *kinfo + strlen (keyref));
+  strcpy (kinfo->keyref, keyref);
+
+  if (!info->kinfo)
+    info->kinfo = kinfo;
+  else
+    {
+      for (ki=info->kinfo; ki->next; ki = ki->next)
+        ;
+      ki->next = kinfo;
+    }
+  return kinfo;
+}
+
+
 /* The status callback to handle the LEARN and GETATTR commands.  */
 static gpg_error_t
 learn_status_cb (void *opaque, const char *line)
@@ -541,6 +590,10 @@ learn_status_cb (void *opaque, const char *line)
   struct card_info_s *parm = opaque;
   const char *keyword = line;
   int keywordlen;
+  char *line_buffer = NULL; /* In case we need a copy.  */
+  char *pline;
+  key_info_t kinfo;
+  const char *keyref;
   int i;
 
   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
@@ -635,18 +688,31 @@ learn_status_cb (void *opaque, const char *line)
         }
       else if (!memcmp (keyword, "KEY-FPR", keywordlen))
         {
-          int no = atoi (line);
-
-          while (*line && !spacep (line))
-            line++;
-          while (spacep (line))
-            line++;
-          if (no == 1)
-            parm->fpr1len = unhexify_fpr (line, parm->fpr1, sizeof parm->fpr1);
-          else if (no == 2)
-            parm->fpr2len = unhexify_fpr (line, parm->fpr2, sizeof parm->fpr2);
-          else if (no == 3)
-            parm->fpr3len = unhexify_fpr (line, parm->fpr3, sizeof parm->fpr3);
+          /* The format of such a line is:
+           *   KEY-FPR <keyref> <fingerprintinhex>
+           */
+          const char *fpr;
+
+          line_buffer = pline = xstrdup (line);
+
+          keyref = parse_keyref_helper (pline);
+          while (*pline && !spacep (pline))
+            pline++;
+          if (*pline)
+            *pline++ = 0; /* Terminate keyref.  */
+          while (spacep (pline)) /* Skip to the fingerprint.  */
+            pline++;
+          fpr = pline;
+
+          /* Check whether we already have an item for the keyref.  */
+          kinfo = find_kinfo (parm, keyref);
+          if (!kinfo)  /* No: new entry.  */
+            kinfo = create_kinfo (parm, keyref);
+          else /* Existing entry - clear the fpr.  */
+            memset (kinfo->fpr, 0, sizeof kinfo->fpr);
+
+          /* Set or update or the fingerprint.  */
+          kinfo->fprlen = unhexify_fpr (fpr, kinfo->fpr, sizeof kinfo->fpr);
         }
       break;
 
@@ -664,17 +730,28 @@ learn_status_cb (void *opaque, const char *line)
         }
       else if (!memcmp (keyword, "KEY-TIME", keywordlen))
         {
-          int no = atoi (line);
-          while (* line && !spacep (line))
-            line++;
-          while (spacep (line))
-            line++;
-          if (no == 1)
-            parm->fpr1time = strtoul (line, NULL, 10);
-          else if (no == 2)
-            parm->fpr2time = strtoul (line, NULL, 10);
-          else if (no == 3)
-            parm->fpr3time = strtoul (line, NULL, 10);
+          /* The format of such a line is:
+           *   KEY-TIME <keyref> <timestamp>
+           */
+          const char *timestamp;
+
+          line_buffer = pline = xstrdup (line);
+
+          keyref = parse_keyref_helper (pline);
+          while (*pline && !spacep (pline))
+            pline++;
+          if (*pline)
+            *pline++ = 0; /* Terminate keyref.  */
+          while (spacep (pline)) /* Skip to the timestamp.  */
+            pline++;
+          timestamp = pline;
+
+          /* Check whether we already have an item for the keyref.  */
+          kinfo = find_kinfo (parm, keyref);
+          if (!kinfo)  /* No: new entry.  */
+            kinfo = create_kinfo (parm, keyref);
+
+          kinfo->created = strtoul (timestamp, NULL, 10);
         }
       else if (!memcmp (keyword, "KEY-ATTR", keywordlen))
         {
@@ -767,21 +844,29 @@ learn_status_cb (void *opaque, const char *line)
         }
       else if (!memcmp (keyword, "KEYPAIRINFO", keywordlen))
         {
+          /* The format of such a line is:
+           *   KEYPARINFO <hexgrip> <keyref>
+           */
           const char *hexgrp = line;
-          int no;
 
           while (*line && !spacep (line))
             line++;
           while (spacep (line))
             line++;
-          if (strncmp (line, "OPENPGP.", 8))
-            ;
-          else if ((no = atoi (line+8)) == 1)
-            unhexify_fpr (hexgrp, parm->grp1, sizeof parm->grp1);
-          else if (no == 2)
-            unhexify_fpr (hexgrp, parm->grp2, sizeof parm->grp2);
-          else if (no == 3)
-            unhexify_fpr (hexgrp, parm->grp3, sizeof parm->grp3);
+
+          keyref = line;
+
+          /* Check whether we already have an item for the keyref.  */
+          kinfo = find_kinfo (parm, keyref);
+          if (!kinfo)  /* New entry.  */
+            kinfo = create_kinfo (parm, keyref);
+          else /* Existing entry - clear the grip.  */
+            memset (kinfo->grip, 0, sizeof kinfo->grip);
+
+          /* Set or update the grip.  Note that due to the
+           * calloc/memset an erroneous too short grip will be nul
+           * padded on the right. */
+          unhexify_fpr (hexgrp, kinfo->grip, sizeof kinfo->grip);
         }
       break;
 
@@ -809,6 +894,7 @@ learn_status_cb (void *opaque, const char *line)
       break;
     }
 
+  xfree (line_buffer);
   return 0;
 }
 
diff --git a/tools/card-tool-misc.c b/tools/card-tool-misc.c
new file mode 100644
index 0000000..0f5fcc0
--- /dev/null
+++ b/tools/card-tool-misc.c
@@ -0,0 +1,44 @@
+/* card-tool-misc.c - Helper functions for gpg-card-tool
+ * Copyright (C) 2019 g10 Code GmbH
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "../common/util.h"
+#include "../common/i18n.h"
+#include "../common/openpgpdefs.h"
+#include "card-tool.h"
+
+/* Return the key info object for the key KEYREF.  If it is not found
+ * NULL is returned.  */
+key_info_t
+find_kinfo (card_info_t info, const char *keyref)
+{
+  key_info_t kinfo;
+
+  for (kinfo = info->kinfo; kinfo; kinfo = kinfo->next)
+    if (!strcmp (kinfo->keyref, keyref))
+      return kinfo;
+  return NULL;
+}
diff --git a/tools/card-tool.h b/tools/card-tool.h
index d51698c..0af6186 100644
--- a/tools/card-tool.h
+++ b/tools/card-tool.h
@@ -76,6 +76,26 @@ struct key_attr
   };
 };
 
+/* An object to store information pertaining to a key pair.  This is
+ * commonly used as a linked list with all keys known for the current
+ * card.  */
+struct key_info_s
+{
+  struct key_info_s *next;
+
+  unsigned char grip[20];/* The keygrip.  */
+
+  unsigned char xflag;   /* Temporary flag to help processing a list. */
+
+  /* The three next items are mostly useful for OpenPGP cards.  */
+  unsigned char fprlen;  /* Use length of the next item.  */
+  unsigned char fpr[32]; /* The binary fingerprint of length FPRLEN.  */
+  u32 created;           /* The time the key was created.  */
+
+  char keyref[1];        /* String with the keyref (e.g. OPENPGP.1).  */
+};
+typedef struct key_info_s *key_info_t;
+
 
 /*
  * The object used to store information about a card.
@@ -100,18 +120,7 @@ struct card_info_s
   char cafpr1[20];
   char cafpr2[20];
   char cafpr3[20];
-  unsigned char fpr1len; /* Length of the fingerprint or 0 if invalid.  */
-  unsigned char fpr2len;
-  unsigned char fpr3len;
-  char fpr1[20];
-  char fpr2[20];
-  char fpr3[20];
-  u32  fpr1time;
-  u32  fpr2time;
-  u32  fpr3time;
-  char grp1[20];     /* The keygrip for OPENPGP.1 */
-  char grp2[20];     /* The keygrip for OPENPGP.2 */
-  char grp3[20];     /* The keygrip for OPENPGP.3 */
+  key_info_t kinfo;  /* Linked list with all keypair related data.  */
   unsigned long sig_counter;
   int chv1_cached;   /* True if a PIN is not required for each
                         signing.  Note that the gpg-agent might cache
@@ -133,6 +142,10 @@ struct card_info_s
 typedef struct card_info_s *card_info_t;
 
 
+/*-- card-tool-misc.c --*/
+key_info_t find_kinfo (card_info_t info, const char *keyref);
+
+
 /*-- card-call-scd.c --*/
 void release_card_info (card_info_t info);
 const char *app_type_string (app_type_t app_type);
diff --git a/tools/gpg-card-tool.c b/tools/gpg-card-tool.c
index b40914a..31d9c22 100644
--- a/tools/gpg-card-tool.c
+++ b/tools/gpg-card-tool.c
@@ -107,10 +107,19 @@ static struct debug_flags_s debug_flags [] =
   };
 
 
+/* An object to create lists of labels and keyrefs.  */
+struct keyinfolabel_s
+{
+  const char *label;
+  const char *keyref;
+};
+typedef struct keyinfolabel_s *keyinfolabel_t;
+
+
 /* Limit of size of data we read from a file for certain commands.  */
 #define MAX_GET_DATA_FROM_FILE 16384
 
-/* Constats for OpenPGP cards.  */
+/* Constants for OpenPGP cards.  */
 #define OPENPGP_USER_PIN_DEFAULT  "123456"
 #define OPENPGP_ADMIN_PIN_DEFAULT "12345678"
 #define OPENPGP_KDF_DATA_LENGTH_MIN  90
@@ -544,35 +553,101 @@ print_isoname (estream_t fp, const char *name)
 }
 
 
-/* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
+/* Return true if the buffer MEM of length memlen consists only of zeroes. */
 static int
-fpr_is_zero (const char *fpr, unsigned int fprlen)
+mem_is_zero (const char *mem, unsigned int memlen)
 {
   int i;
 
-  for (i=0; i < fprlen && !fpr[i]; i++)
+  for (i=0; i < memlen && !mem[i]; i++)
     ;
-  return (i == fprlen);
+  return (i == memlen);
 }
 
 
-/* Return true if the fingerprint FPR consists only of 0xFF. */
+/* Return true if the buffer MEM or length MEMLEN consists only of 0xFF. */
 static int
-fpr_is_ff (const char *fpr, unsigned int fprlen)
+mem_is_ff (const char *mem, unsigned int memlen)
 {
   int i;
 
-  for (i=0; i < fprlen && fpr[i] == '\xff'; i++)
+  for (i=0; i < memlen && mem[i] == '\xff'; i++)
     ;
-  return (i == fprlen);
+  return (i == memlen);
 }
 
 
 

+/* Helper to list a single keyref.  */
+static void
+list_one_kinfo (key_info_t kinfo, estream_t fp)
+{
+  if (kinfo)
+    {
+      tty_fprintf (fp, " ");
+      if (mem_is_zero (kinfo->grip, sizeof kinfo->grip))
+        tty_fprintf (fp, "[none]\n");
+      else
+        print_keygrip (fp, kinfo->grip);
+
+      if (kinfo->fprlen && kinfo->created)
+        {
+          tty_fprintf (fp, "      fingerprint :");
+          print_shax_fpr (fp, kinfo->fpr, kinfo->fprlen);
+          tty_fprintf (fp, "      created ....: %s\n",
+                       isotimestamp (kinfo->created));
+        }
+    }
+  else
+    tty_fprintf (fp, " [none]\n");
+}
+
+
+/* List all keyinfo in INFO using the list of LABELS.  */
+static void
+list_all_kinfo (card_info_t info, keyinfolabel_t labels, estream_t fp)
+{
+  key_info_t kinfo;
+  int idx, i;
+
+  /* Print the keyinfo.  We first print those we known and then all
+   * remaining item.  */
+  for (kinfo = info->kinfo; kinfo; kinfo = kinfo->next)
+    kinfo->xflag = 0;
+  if (labels)
+    {
+      for (idx=0; labels[idx].label; idx++)
+        {
+          tty_fprintf (fp, "%s", labels[idx].label);
+          kinfo = find_kinfo (info, labels[idx].keyref);
+          list_one_kinfo (kinfo, fp);
+          if (kinfo)
+            kinfo->xflag = 1;
+        }
+    }
+  for (kinfo = info->kinfo; kinfo; kinfo = kinfo->next)
+    {
+      if (kinfo->xflag)
+        continue;
+      tty_fprintf (fp, "Key %s ", kinfo->keyref);
+      for (i=5+strlen (kinfo->keyref); i < 18; i++)
+        tty_fprintf (fp, ".");
+      tty_fprintf (fp, ":");
+      list_one_kinfo (kinfo, fp);
+    }
+}
+
+
 /* List OpenPGP card specific data.  */
 static void
 list_openpgp (card_info_t info, estream_t fp)
 {
+  static struct keyinfolabel_s keyinfolabels[] = {
+    { "Signature key ....:", "OPENPGP.1" },
+    { "Encryption key....:", "OPENPGP.2" },
+    { "Authentication key:", "OPENPGP.3" },
+    { NULL, NULL }
+  };
   int i;
 
   if (!info->serialno
@@ -661,33 +736,8 @@ list_openpgp (card_info_t info, estream_t fp)
                    info->uif[0] ? "on" : "off", info->uif[1] ? "on" : "off",
                    info->uif[2] ? "on" : "off");
     }
-  tty_fprintf (fp, "Signature key ....:");
-  print_shax_fpr (fp, info->fpr1len? info->fpr1:NULL, info->fpr1len);
-  if (info->fpr1len && info->fpr1time)
-    {
-      tty_fprintf (fp, "      created ....: %s\n",
-                   isotimestamp (info->fpr1time));
-      tty_fprintf (fp, "      keygrip ....: ");
-      print_keygrip (fp, info->grp1);
-    }
-  tty_fprintf (fp, "Encryption key....:");
-  print_shax_fpr (fp, info->fpr2len? info->fpr2:NULL, info->fpr2len);
-  if (info->fpr2len && info->fpr2time)
-    {
-      tty_fprintf (fp, "      created ....: %s\n",
-                   isotimestamp (info->fpr2time));
-      tty_fprintf (fp, "      keygrip ....: ");
-      print_keygrip (fp, info->grp2);
-    }
-  tty_fprintf (fp, "Authentication key:");
-  print_shax_fpr (fp, info->fpr3len? info->fpr3:NULL, info->fpr3len);
-  if (info->fpr3len && info->fpr3time)
-    {
-      tty_fprintf (fp, "      created ....: %s\n",
-                   isotimestamp (info->fpr3time));
-      tty_fprintf (fp, "      keygrip ....: ");
-      print_keygrip (fp, info->grp3);
-    }
+
+  list_all_kinfo (info, keyinfolabels, fp);
 
   /* tty_fprintf (fp, "General key info->.: "); */
   /* thefpr = (info->fpr1len? info->fpr1 : info->fpr2len? info->fpr2 : */
@@ -696,7 +746,7 @@ list_openpgp (card_info_t info, estream_t fp)
   /*              info->fpr3len? info->fpr3len : 0); */
   /* If the fingerprint is all 0xff, the key has no associated
      OpenPGP certificate.  */
-  /* if ( thefpr && !fpr_is_ff (thefpr, thefprlen) */
+  /* if ( thefpr && !mem_is_ff (thefpr, thefprlen) */
   /*      && !get_pubkey_byfprint (ctrl, pk, &keyblock, thefpr, thefprlen)) */
   /*   { */
       /* print_pubkey_info (ctrl, fp, pk); */
@@ -900,6 +950,7 @@ static gpg_error_t
 cmd_fetch (card_info_t info)
 {
   gpg_error_t err;
+  key_info_t kinfo;
 
   if (!info)
     return print_help
@@ -916,7 +967,7 @@ cmd_fetch (card_info_t info)
       /* free_strlist (sl); */
       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);  /* FIXME */
     }
-  else if (info->fpr1len)
+  else if ((kinfo = find_kinfo (info, "OPENPGP.1")) && kinfo->fprlen)
     {
       /* rc = keyserver_import_fprint (ctrl, info.fpr1, info.fpr1len, */
       /*                               opt.keyserver, 0); */
@@ -1479,6 +1530,7 @@ cmd_generate (card_info_t info)
   int forced_chv1 = -1;
   int want_backup;
   char *answer = NULL;
+  key_info_t kinfo1, kinfo2, kinfo3;
 
   if (!info)
     return print_help
@@ -1507,9 +1559,15 @@ cmd_generate (card_info_t info)
   else
     want_backup = 0;
 
-  if ( (info->fpr1len && !fpr_is_zero (info->fpr1, info->fpr1len))
-       || (info->fpr2len && !fpr_is_zero (info->fpr2, info->fpr2len))
-       || (info->fpr3len && !fpr_is_zero (info->fpr3, info->fpr3len)))
+
+  kinfo1 = find_kinfo (info, "OPENPGP.1");
+  kinfo2 = find_kinfo (info, "OPENPGP.2");
+  kinfo3 = find_kinfo (info, "OPENPGP.3");
+
+  if ((kinfo1 && kinfo1->fprlen && !mem_is_zero (kinfo1->fpr,kinfo1->fprlen))
+      || (kinfo2 && kinfo2->fprlen && !mem_is_zero (kinfo2->fpr,kinfo2->fprlen))
+      || (kinfo3 && kinfo3->fprlen && !mem_is_zero (kinfo3->fpr,kinfo3->fprlen))
+      )
     {
       tty_printf ("\n");
       log_info (_("Note: keys are already stored on the card!\n"));

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

Summary of changes:
 scd/app-piv.c                                |   5 +-
 tools/Makefile.am                            |   8 +-
 tools/card-call-scd.c                        | 176 ++++++++++++++++++++------
 g13/be-truecrypt.c => tools/card-tool-misc.c |  25 ++--
 tools/card-tool.h                            |  47 ++++---
 tools/gpg-card-tool.c                        | 183 ++++++++++++++++++++-------
 6 files changed, 336 insertions(+), 108 deletions(-)
 copy g13/be-truecrypt.c => tools/card-tool-misc.c (60%)


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




More information about the Gnupg-commits mailing list