card: Print keyinfo for PIV cards.
authorWerner Koch <wk@gnupg.org>
Tue, 29 Jan 2019 08:30:15 +0000 (09:30 +0100)
committerWerner Koch <wk@gnupg.org>
Tue, 29 Jan 2019 08:32:20 +0000 (09:32 +0100)
* 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@gnupg.org>
scd/app-piv.c
tools/card-call-scd.c
tools/card-tool.h
tools/gpg-card-tool.c

index 011b552..69f12f4 100644 (file)
@@ -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;
 }
 
index abf35ed..2551b19 100644 (file)
@@ -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;
 
index 0af6186..bcc257c 100644 (file)
@@ -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.  */
index 31d9c22..5ba44fc 100644 (file)
@@ -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)
     {