[git] GnuPG - branch, master, updated. gnupg-2.1.18-122-ge3944f3

by Werner Koch cvs at cvs.gnupg.org
Wed Feb 22 15:51:59 CET 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  e3944f34e3220f96fb1be449eb6f3d7360bc2d0b (commit)
      from  6488ffb767733a2cf92ca5ba3e61fc0c53e0f673 (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 e3944f34e3220f96fb1be449eb6f3d7360bc2d0b
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Feb 22 13:03:52 2017 +0100

    scd: Improve the prompts for OpenPGP cards.
    
    * scd/app-openpgp.c (get_disp_name): New.
    (get_disp_serialno): New.
    (get_prompt_info): New.
    (build_enter_admin_pin_prompt): Rework the prompt texts.  Factor some
    code out to ...
    (get_remaining_tries): New.
    (verify_a_chv): Print a remaining counter also for the standard PIN.
    Rework the prompt texts.
    
    * agent/divert-scd.c (ask_for_card): Pretty format an OpenPGP serial
    no.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/agent/divert-scd.c b/agent/divert-scd.c
index 3164404..d9d734c 100644
--- a/agent/divert-scd.c
+++ b/agent/divert-scd.c
@@ -39,22 +39,39 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
   char *serialno;
   int no_card = 0;
   char *desc;
-  char *want_sn, *want_kid;
-  int want_sn_displen;
+  char *want_sn, *want_kid, *want_sn_disp;
+  int len;
 
   *r_kid = NULL;
 
   rc = parse_shadow_info (shadow_info, &want_sn, &want_kid, NULL);
   if (rc)
     return rc;
+  want_sn_disp = xtrystrdup (want_sn);
+  if (!want_sn_disp)
+    {
+      rc = gpg_error_from_syserror ();
+      xfree (want_sn);
+      return rc;
+    }
 
-  /* We assume that a 20 byte serial number is a standard one which
-     has the property to have a zero in the last nibble (Due to BCD
-     representation).  We don't display this '0' because it may
-     confuse the user.  */
-  want_sn_displen = strlen (want_sn);
-  if (want_sn_displen == 20 && want_sn[19] == '0')
-    want_sn_displen--;
+  len = strlen (want_sn_disp);
+  if (len == 32 && !strncmp (want_sn_disp, "D27600012401", 12))
+    {
+      /* This is an OpenPGP card - reformat  */
+      memmove (want_sn_disp, want_sn_disp+16, 4);
+      want_sn_disp[4] = ' ';
+      memmove (want_sn_disp+5, want_sn_disp+20, 8);
+      want_sn_disp[13] = 0;
+    }
+  else if (len == 20 && want_sn_disp[19] == '0')
+    {
+      /* We assume that a 20 byte serial number is a standard one
+       * which has the property to have a zero in the last nibble (Due
+       * to BCD representation).  We don't display this '0' because it
+       * may confuse the user.  */
+      want_sn_disp[19] = 0;
+    }
 
   for (;;)
     {
@@ -93,12 +110,12 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
         {
           if (asprintf (&desc,
                     "%s:%%0A%%0A"
-                    "  \"%.*s\"",
+                    "  %s",
                         no_card
                         ? L_("Please insert the card with serial number")
                         : L_("Please remove the current card and "
                              "insert the one with serial number"),
-                    want_sn_displen, want_sn) < 0)
+                        want_sn_disp) < 0)
             {
               rc = out_of_core ();
             }
@@ -114,6 +131,7 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
         }
       if (rc)
         {
+          xfree (want_sn_disp);
           xfree (want_sn);
           xfree (want_kid);
           return rc;
@@ -312,7 +330,8 @@ getpin_cb (void *opaque, const char *desc_text, const char *info,
                              info, NULL);
         else
           desc2 = NULL;
-        rc = agent_askpin (ctrl, desc2, prompt, again_text, pi, NULL, 0);
+        rc = agent_askpin (ctrl, desc2? desc2 : info,
+                           prompt, again_text, pi, NULL, 0);
         xfree (desc2);
       }
       again_text = NULL;
@@ -401,6 +420,8 @@ divert_pksign (ctrl_t ctrl, const char *desc_text,
   size_t siglen;
   unsigned char *sigval = NULL;
 
+  (void)desc_text;
+
   rc = ask_for_card (ctrl, shadow_info, &kid);
   if (rc)
     return rc;
@@ -409,7 +430,7 @@ divert_pksign (ctrl_t ctrl, const char *desc_text,
     {
       int save = ctrl->use_auth_call;
       ctrl->use_auth_call = 1;
-      rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, desc_text,
+      rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, NULL,
                               algo, digest, digestlen, &sigval, &siglen);
       ctrl->use_auth_call = save;
     }
@@ -421,7 +442,7 @@ divert_pksign (ctrl_t ctrl, const char *desc_text,
       rc = encode_md_for_card (digest, digestlen, algo, &data, &ndata);
       if (!rc)
         {
-          rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, desc_text,
+          rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, NULL,
                                   algo, data, ndata, &sigval, &siglen);
           xfree (data);
         }
@@ -458,6 +479,8 @@ divert_pkdecrypt (ctrl_t ctrl, const char *desc_text,
   char *plaintext;
   size_t plaintextlen;
 
+  (void)desc_text;
+
   *r_padding = -1;
 
   s = cipher;
@@ -523,7 +546,7 @@ divert_pkdecrypt (ctrl_t ctrl, const char *desc_text,
   if (rc)
     return rc;
 
-  rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl, desc_text,
+  rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl, NULL,
                              ciphertext, ciphertextlen,
                              &plaintext, &plaintextlen, r_padding);
   if (!rc)
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 608e3cc..90c2661 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -1082,6 +1082,104 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
   return rc;
 }
 
+
+/* Return the DISP-NAME without any padding characters.  Caller must
+ * free the result.  If not found or empty NULL is returned.  */
+static char *
+get_disp_name (app_t app)
+{
+  int rc;
+  void *relptr;
+  unsigned char *value;
+  size_t valuelen;
+  char *string;
+  char *p, *given;
+  char *result;
+
+  relptr = get_one_do (app, 0x005B, &value, &valuelen, &rc);
+  if (!relptr)
+    return NULL;
+
+  string = xtrymalloc (valuelen + 1);
+  if (!string)
+    {
+      xfree (relptr);
+      return NULL;
+    }
+  memcpy (string, value, valuelen);
+  string[valuelen] = 0;
+  xfree (relptr);
+
+  /* Swap surname and given name.  */
+  given = strstr (string, "<<");
+  for (p = string; *p; p++)
+    if (*p == '<')
+      *p = ' ';
+
+  if (given && given[2])
+    {
+      *given = 0;
+      given += 2;
+      result = strconcat (given, " ", string, NULL);
+    }
+  else
+    {
+      result = string;
+      string = NULL;
+    }
+
+  xfree (string);
+  return result;
+}
+
+
+/* Return the pretty formatted serialnumber.  On error NULL is
+ * returned.  */
+static char *
+get_disp_serialno (app_t app)
+{
+  char *serial = app_get_serialno (app);
+
+  /* For our OpenPGP cards we do not want to show the entire serial
+   * number but a nicely reformatted actual serial number.  */
+  if (serial && strlen (serial) > 16+12)
+    {
+      memmove (serial, serial+16, 4);
+      serial[4] = ' ';
+      /* memmove (serial+5, serial+20, 4); */
+      /* serial[9] = ' '; */
+      /* memmove (serial+10, serial+24, 4); */
+      /* serial[14] = 0; */
+      memmove (serial+5, serial+20, 8);
+      serial[13] = 0;
+    }
+  return serial;
+}
+
+
+/* Return the number of remaining tries for the standard or the admin
+ * pw.  Returns -1 on card error.  */
+static int
+get_remaining_tries (app_t app, int adminpw)
+{
+  void *relptr;
+  unsigned char *value;
+  size_t valuelen;
+  int remaining;
+
+  relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL);
+  if (!relptr || valuelen < 7)
+    {
+      log_error (_("error retrieving CHV status from card\n"));
+      xfree (relptr);
+      return -1;
+    }
+  remaining = value[adminpw? 6 : 4];
+  xfree (relptr);
+  return remaining;
+}
+
+
 /* Retrieve the fingerprint from the card inserted in SLOT and write
    the according hex representation to FPR.  Caller must have provide
    a buffer at FPR of least 41 bytes.  Returns 0 on success or an
@@ -1874,6 +1972,62 @@ check_pinpad_request (app_t app, pininfo_t *pininfo, int admin_pin)
 }
 
 
+/* Return a string with information about the card for use in a
+ * prompt.  Returns NULL on memory failure.  */
+static char *
+get_prompt_info (app_t app, int chvno, unsigned long sigcount, int remaining)
+{
+  char *serial, *disp_name, *rembuf, *tmpbuf, *result;
+
+  serial = get_disp_serialno (app);
+  if (!serial)
+    return NULL;
+
+  disp_name = get_disp_name (app);
+  if (chvno == 1)
+    {
+      result = xtryasprintf (_("Card number:\t%s%%0A"
+                               "Signatures:\t%lu%%0A"
+                               "Cardholder:\t%s"),
+                             serial,
+                             sigcount,
+                             disp_name? disp_name:"");
+    }
+  else
+    {
+      result = xtryasprintf (_("Card number:\t%s%%0A"
+                               "Cardholder:\t%s"),
+                             serial,
+                             disp_name? disp_name:"");
+    }
+  xfree (disp_name);
+  xfree (serial);
+
+  if (remaining != -1)
+    {
+      /* TRANSLATORS: This is the number of remaining attempts to
+       * enter a PIN.  Use %%0A (double-percent,0A) for a linefeed. */
+      rembuf = xtryasprintf (_("Remaining attempts: %d"), remaining);
+      if (!rembuf)
+        {
+          xfree (result);
+          return NULL;
+        }
+      tmpbuf = strconcat (result, "%0A%0A", rembuf, NULL);
+      xfree (rembuf);
+      if (!tmpbuf)
+        {
+          xfree (result);
+          return NULL;
+        }
+      xfree (result);
+      result = tmpbuf;
+    }
+
+  return result;
+}
+
+
 /* Verify a CHV either using the pinentry or if possible by
    using a pinpad.  PINCB and PINCB_ARG describe the usual callback
    for the pinentry.  CHVNO must be either 1 or 2. SIGCOUNT is only
@@ -1895,11 +2049,16 @@ verify_a_chv (app_t app,
   const char *prompt;
   pininfo_t pininfo;
   int minlen = 6;
+  int remaining;
 
-  assert (chvno == 1 || chvno == 2);
+  log_assert (chvno == 1 || chvno == 2);
 
   *pinvalue = NULL;
 
+  remaining = get_remaining_tries (app, 0);
+  if (remaining == -1)
+    return gpg_error (GPG_ERR_CARD);
+
   if (chvno == 2 && app->app_local->flags.def_chv2)
     {
       /* Special case for def_chv2 mechanism. */
@@ -1923,22 +2082,19 @@ verify_a_chv (app_t app,
   pininfo.fixedlen = -1;
   pininfo.minlen = minlen;
 
+  {
+    const char *firstline = _("||Please unlock the card");
+    char *infoblock = get_prompt_info (app, chvno, sigcount,
+                                       remaining < 3? remaining : -1);
 
-  if (chvno == 1)
-    {
-#define PROMPTSTRING  _("||Please enter the PIN%%0A[sigs done: %lu]")
-      size_t promptsize = strlen (PROMPTSTRING) + 50;
-
-      prompt_buffer = xtrymalloc (promptsize);
-      if (!prompt_buffer)
-        return gpg_error_from_syserror ();
-      snprintf (prompt_buffer, promptsize, PROMPTSTRING, sigcount);
+    prompt_buffer = strconcat (firstline, "%0A%0A", infoblock, NULL);
+    if (prompt_buffer)
       prompt = prompt_buffer;
-#undef PROMPTSTRING
-    }
-  else
-    prompt = _("||Please enter the PIN");
+    else
+      prompt = firstline;  /* ENOMEM fallback.  */
 
+    xfree (infoblock);
+  }
 
   if (!opt.disable_pinpad
       && !iso7816_check_pinpad (app->slot, ISO7816_VERIFY, &pininfo)
@@ -1961,7 +2117,7 @@ verify_a_chv (app_t app,
       /* Dismiss the prompt. */
       pincb (pincb_arg, NULL, NULL);
 
-      assert (!*pinvalue);
+      log_assert (!*pinvalue);
     }
   else
     {
@@ -2049,29 +2205,20 @@ verify_chv2 (app_t app,
 static gpg_error_t
 build_enter_admin_pin_prompt (app_t app, char **r_prompt)
 {
-  void *relptr;
-  unsigned char *value;
-  size_t valuelen;
   int remaining;
   char *prompt;
+  char *infoblock;
 
   *r_prompt = NULL;
 
-  relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL);
-  if (!relptr || valuelen < 7)
-    {
-      log_error (_("error retrieving CHV status from card\n"));
-      xfree (relptr);
-      return gpg_error (GPG_ERR_CARD);
-    }
-  if (value[6] == 0)
+  remaining = get_remaining_tries (app, 1);
+  if (remaining == -1)
+    return gpg_error (GPG_ERR_CARD);
+  if (!remaining)
     {
       log_info (_("card is permanently locked!\n"));
-      xfree (relptr);
       return gpg_error (GPG_ERR_BAD_PIN);
     }
-  remaining = value[6];
-  xfree (relptr);
 
   log_info (ngettext("%d Admin PIN attempt remaining before card"
                      " is permanently locked\n",
@@ -2079,16 +2226,13 @@ build_enter_admin_pin_prompt (app_t app, char **r_prompt)
                      " is permanently locked\n",
                      remaining), remaining);
 
-  if (remaining < 3)
-    {
-      /* TRANSLATORS: Do not translate the "|A|" prefix but keep it at
-         the start of the string.  Use %%0A to force a linefeed.  */
-      prompt = xtryasprintf (_("|A|Please enter the Admin PIN%%0A"
-                               "[remaining attempts: %d]"), remaining);
-    }
-  else
-    prompt = xtrystrdup (_("|A|Please enter the Admin PIN"));
+  infoblock = get_prompt_info (app, 3, 0, remaining < 3? remaining : -1);
 
+  /* TRANSLATORS: Do not translate the "|A|" prefix but keep it at
+     the start of the string.  Use %0A (single percent) for a linefeed.  */
+  prompt = strconcat (_("|A|Please enter the Admin PIN"),
+                      "%0A%0A", infoblock, NULL);
+  xfree (infoblock);
   if (!prompt)
     return gpg_error_from_syserror ();
 

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

Summary of changes:
 agent/divert-scd.c |  53 +++++++++----
 scd/app-openpgp.c  | 220 ++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 220 insertions(+), 53 deletions(-)


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




More information about the Gnupg-commits mailing list