[git] GnuPG - branch, scd-work, created. gnupg-2.1.0beta3-130-g943ce30

by NIIBE Yutaka cvs at cvs.gnupg.org
Wed Jan 9 08:52:38 CET 2013


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, scd-work has been created
        at  943ce30e29cdd803588d1b6c316f52986f2a7d8b (commit)

- Log -----------------------------------------------------------------
commit 943ce30e29cdd803588d1b6c316f52986f2a7d8b
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Wed Jan 9 16:40:41 2013 +0900

    SCD: Support fixed length PIN input for keypad (PC/SC).
    
    * scd/apdu.c (pcsc_keypad_verify): SUpport fixed length PIN input for
    keypad.
    (pcsc_keypad_modify): Likewise.
    * scd/ccid-driver.c (ccid_transceive_secure): Clean up.

diff --git a/scd/apdu.c b/scd/apdu.c
index 8c968b7..4c73283 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -2042,7 +2042,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1,
 {
   int sw;
   unsigned char *pin_verify;
-  int len = PIN_VERIFY_STRUCTURE_SIZE;
+  int len = PIN_VERIFY_STRUCTURE_SIZE + pininfo->fixedlen;
   unsigned char result[2];
   size_t resultlen = 2;
 
@@ -2050,7 +2050,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1,
       && (sw = reset_pcsc_reader (slot)))
     return sw;
 
-  if (pininfo->fixedlen != 0)
+  if (pininfo->fixedlen < 0 || pininfo->fixedlen >= 16)
     return SW_NOT_SUPPORTED;
 
   if (!pininfo->minlen)
@@ -2071,7 +2071,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1,
   pin_verify[0] = 0x00; /* bTimerOut */
   pin_verify[1] = 0x00; /* bTimerOut2 */
   pin_verify[2] = 0x82; /* bmFormatString: Byte, pos=0, left, ASCII. */
-  pin_verify[3] = 0x00; /* bmPINBlockString */
+  pin_verify[3] = pininfo->fixedlen; /* bmPINBlockString */
   pin_verify[4] = 0x00; /* bmPINLengthFormat */
   pin_verify[5] = pininfo->maxlen; /* wPINMaxExtraDigit */
   pin_verify[6] = pininfo->minlen; /* wPINMaxExtraDigit */
@@ -2085,7 +2085,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1,
   pin_verify[12] = 0x00; /* bTeoPrologue[0] */
   pin_verify[13] = 0x00; /* bTeoPrologue[1] */
   pin_verify[14] = 0x00; /* bTeoPrologue[2] */
-  pin_verify[15] = 0x05; /* ulDataLength */
+  pin_verify[15] = pininfo->fixedlen + 0x05; /* ulDataLength */
   pin_verify[16] = 0x00; /* ulDataLength */
   pin_verify[17] = 0x00; /* ulDataLength */
   pin_verify[18] = 0x00; /* ulDataLength */
@@ -2093,7 +2093,9 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1,
   pin_verify[20] = ins; /* abData[1] */
   pin_verify[21] = p0; /* abData[2] */
   pin_verify[22] = p1; /* abData[3] */
-  pin_verify[23] = 0x00; /* abData[4] */
+  pin_verify[23] = pininfo->fixedlen; /* abData[4] */
+  if (pininfo->fixedlen)
+    memset (&pin_verify[24], 0xff, pininfo->fixedlen);
 
   if (DBG_CARD_IO)
     log_debug ("send secure: c=%02X i=%02X p1=%02X p2=%02X len=%d pinmax=%d\n",
@@ -2123,7 +2125,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1,
 {
   int sw;
   unsigned char *pin_modify;
-  int len = PIN_MODIFY_STRUCTURE_SIZE;
+  int len = PIN_MODIFY_STRUCTURE_SIZE + 2 * pininfo->fixedlen;
   unsigned char result[2];
   size_t resultlen = 2;
 
@@ -2131,7 +2133,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1,
       && (sw = reset_pcsc_reader (slot)))
     return sw;
 
-  if (pininfo->fixedlen != 0)
+  if (pininfo->fixedlen < 0 || pininfo->fixedlen >= 16)
     return SW_NOT_SUPPORTED;
 
   if (!pininfo->minlen)
@@ -2152,10 +2154,10 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1,
   pin_modify[0] = 0x00; /* bTimerOut */
   pin_modify[1] = 0x00; /* bTimerOut2 */
   pin_modify[2] = 0x82; /* bmFormatString: Byte, pos=0, left, ASCII. */
-  pin_modify[3] = 0x00; /* bmPINBlockString */
+  pin_modify[3] = pininfo->fixedlen; /* bmPINBlockString */
   pin_modify[4] = 0x00; /* bmPINLengthFormat */
   pin_modify[5] = 0x00; /* bInsertionOffsetOld */
-  pin_modify[6] = 0x00; /* bInsertionOffsetNew */
+  pin_modify[6] = pininfo->fixedlen; /* bInsertionOffsetNew */
   pin_modify[7] = pininfo->maxlen; /* wPINMaxExtraDigit */
   pin_modify[8] = pininfo->minlen; /* wPINMaxExtraDigit */
   pin_modify[9] = (p0 == 0 ? 0x03 : 0x01);
@@ -2177,7 +2179,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1,
   pin_modify[17] = 0x00; /* bTeoPrologue[0] */
   pin_modify[18] = 0x00; /* bTeoPrologue[1] */
   pin_modify[19] = 0x00; /* bTeoPrologue[2] */
-  pin_modify[20] = 0x05; /* ulDataLength */
+  pin_modify[20] = 2 * pininfo->fixedlen + 0x05; /* ulDataLength */
   pin_modify[21] = 0x00; /* ulDataLength */
   pin_modify[22] = 0x00; /* ulDataLength */
   pin_modify[23] = 0x00; /* ulDataLength */
@@ -2185,7 +2187,9 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1,
   pin_modify[25] = ins; /* abData[1] */
   pin_modify[26] = p0; /* abData[2] */
   pin_modify[27] = p1; /* abData[3] */
-  pin_modify[28] = 0x00; /* abData[4] */
+  pin_modify[28] = 2 * pininfo->fixedlen; /* abData[4] */
+  if (pininfo->fixedlen)
+    memset (&pin_modify[29], 0xff, 2 * pininfo->fixedlen);
 
   if (DBG_CARD_IO)
     log_debug ("send secure: c=%02X i=%02X p1=%02X p2=%02X len=%d pinmax=%d\n",
diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c
index 3244c71..83b419a 100644
--- a/scd/ccid-driver.c
+++ b/scd/ccid-driver.c
@@ -3411,14 +3411,9 @@ ccid_transceive_secure (ccid_driver_t handle,
     }
   else
     {
-      if (pininfo->fixedlen == 0)
-	msg[13] = 0x00; /* bmPINBlockString:
-			   0 bits of pin length to insert.
-			   0 bytes of PIN block size.  */
-      else
-	msg[13] = pininfo->fixedlen; /* bmPINBlockString:
-					0 bits of pin length to insert.
-					PIN block size by fixedlen.  */
+      msg[13] = pininfo->fixedlen; /* bmPINBlockString:
+				      0 bits of pin length to insert.
+				      PIN block size by fixedlen.  */
       msg[14] = 0x00; /* bmPINLengthFormat:
                          Units are bytes, position is 0. */
     }
@@ -3427,10 +3422,7 @@ ccid_transceive_secure (ccid_driver_t handle,
   if (apdu_buf[1] == 0x24)
     {
       msg[msglen++] = 0;    /* bInsertionOffsetOld */
-      if (pininfo->fixedlen == 0)
-	msg[msglen++] = 0;    /* bInsertionOffsetNew */
-      else
-	msg[msglen++] = pininfo->fixedlen;    /* bInsertionOffsetNew */
+      msg[msglen++] = pininfo->fixedlen;    /* bInsertionOffsetNew */
     }
 
   /* The following is a little endian word. */

commit 638b84f93b6325b3db016e7a0621554d6d8a1c7f
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Wed Jan 9 16:23:55 2013 +0900

    SCD: Support fixed length PIN input for keypad.
    
    * scd/iso7816.h (struct pininfo_s): Remove MODE and add FIXEDLEN.
    * scd/app-dinsig.c (verify_pin): Initialize FIXEDLEN to unknown.
    * scd/app-nks.c (verify_pin): Likewise.
    * scd/app-openpgp.c (verify_a_chv, verify_chv3, do_change_pin):
    Likewise.
    * scd/apdu.c (check_pcsc_keypad): Add comment.
    (pcsc_keypad_verify, pcsc_keypad_modify): PC/SC driver only support
    readers with the feature of variable length input (yet).
    (apdu_check_keypad): Set FIXEDLEN.
    * scd/ccid-driver.c (ccid_transceive_secure): Add GEMPC_PINPAD
    specific settings.
    Support fixed length PIN input for keypad.

diff --git a/scd/apdu.c b/scd/apdu.c
index 1e776df..8c968b7 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -1986,7 +1986,7 @@ check_pcsc_keypad (int slot, int command, pininfo_t *pininfo)
   size_t len = 256;
   int sw;
 
-  (void)pininfo;
+  (void)pininfo;      /* XXX: Identify reader and set pininfo->fixedlen.  */
 
  check_again:
   if (command == ISO7816_VERIFY)
@@ -2050,7 +2050,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1,
       && (sw = reset_pcsc_reader (slot)))
     return sw;
 
-  if (pininfo->mode != 1)
+  if (pininfo->fixedlen != 0)
     return SW_NOT_SUPPORTED;
 
   if (!pininfo->minlen)
@@ -2131,7 +2131,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1,
       && (sw = reset_pcsc_reader (slot)))
     return sw;
 
-  if (pininfo->mode != 1)
+  if (pininfo->fixedlen != 0)
     return SW_NOT_SUPPORTED;
 
   if (!pininfo->minlen)
@@ -3397,7 +3397,7 @@ apdu_check_keypad (int slot, int command, pininfo_t *pininfo)
     return SW_HOST_NO_DRIVER;
 
   if (opt.enable_keypad_varlen)
-    pininfo->mode = 0;
+    pininfo->fixedlen = 0;
 
   if (reader_table[slot].check_keypad)
     return reader_table[slot].check_keypad (slot, command, pininfo);
diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c
index f3f7d4b..9d4ebe2 100644
--- a/scd/app-dinsig.c
+++ b/scd/app-dinsig.c
@@ -288,7 +288,7 @@ verify_pin (app_t app,
     return 0;  /* No need to verify it again.  */
 
   memset (&pininfo, 0, sizeof pininfo);
-  pininfo.mode = 1;
+  pininfo.fixedlen = -1;
   pininfo.minlen = 6;
   pininfo.maxlen = 8;
 
diff --git a/scd/app-nks.c b/scd/app-nks.c
index 4e7a43c..8a48871 100644
--- a/scd/app-nks.c
+++ b/scd/app-nks.c
@@ -788,7 +788,7 @@ verify_pin (app_t app, int pwid, const char *desc,
     desc = "PIN";
 
   memset (&pininfo, 0, sizeof pininfo);
-  pininfo.mode = 1;
+  pininfo.fixedlen = -1;
   pininfo.minlen = 6;
   pininfo.maxlen = 16;
 
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 968ef98..dcc3120 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -1516,7 +1516,7 @@ verify_a_chv (app_t app,
     }
 
   memset (&pininfo, 0, sizeof pininfo);
-  pininfo.mode = 1;
+  pininfo.fixedlen = -1;
   pininfo.minlen = minlen;
 
 
@@ -1712,7 +1712,7 @@ verify_chv3 (app_t app,
       char *prompt;
 
       memset (&pininfo, 0, sizeof pininfo);
-      pininfo.mode = 1;
+      pininfo.fixedlen = -1;
       pininfo.minlen = minlen;
 
       rc = build_enter_admin_pin_prompt (app, &prompt);
@@ -1923,7 +1923,7 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *chvnostr,
 
   (void)ctrl;
   memset (&pininfo, 0, sizeof pininfo);
-  pininfo.mode = 1;
+  pininfo.fixedlen = -1;
   pininfo.minlen = minlen;
 
   if (reset_mode && chvno == 3)
diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c
index c16c7ac..3244c71 100644
--- a/scd/ccid-driver.c
+++ b/scd/ccid-driver.c
@@ -3361,23 +3361,27 @@ ccid_transceive_secure (ccid_driver_t handle,
         cherry_mode = 1;
       break;
     case VENDOR_GEMPC:
-      enable_varlen = 0;
       if (handle->id_product == GEMPC_PINPAD)
-	break;
+	{
+	  enable_varlen = 0;
+	  pininfo->minlen = 4;
+	  pininfo->maxlen = 8;
+	  break;
+	}
       /* fall through */
     default:
      return CCID_DRIVER_ERR_NOT_SUPPORTED;
     }
 
   if (enable_varlen)
-    pininfo->mode = 0;
-
-  if (pininfo->mode != 0 && pininfo->mode != 1)
-    return CCID_DRIVER_ERR_NOT_SUPPORTED;
+    pininfo->fixedlen = 0;
 
   if (testmode)
     return 0; /* Success */
 
+  if (pininfo->fixedlen < 0 || pininfo->fixedlen >= 16)
+    return CCID_DRIVER_ERR_NOT_SUPPORTED;
+
   msg = send_buffer;
   if (handle->id_vendor == VENDOR_SCM)
     {
@@ -3407,9 +3411,14 @@ ccid_transceive_secure (ccid_driver_t handle,
     }
   else
     {
-      msg[13] = 0x00; /* bmPINBlockString:
-                         0 bits of pin length to insert.
-                         0 bytes of PIN block size.  */
+      if (pininfo->fixedlen == 0)
+	msg[13] = 0x00; /* bmPINBlockString:
+			   0 bits of pin length to insert.
+			   0 bytes of PIN block size.  */
+      else
+	msg[13] = pininfo->fixedlen; /* bmPINBlockString:
+					0 bits of pin length to insert.
+					PIN block size by fixedlen.  */
       msg[14] = 0x00; /* bmPINLengthFormat:
                          Units are bytes, position is 0. */
     }
@@ -3418,7 +3427,10 @@ ccid_transceive_secure (ccid_driver_t handle,
   if (apdu_buf[1] == 0x24)
     {
       msg[msglen++] = 0;    /* bInsertionOffsetOld */
-      msg[msglen++] = 0;    /* bInsertionOffsetNew */
+      if (pininfo->fixedlen == 0)
+	msg[msglen++] = 0;    /* bInsertionOffsetNew */
+      else
+	msg[msglen++] = pininfo->fixedlen;    /* bInsertionOffsetNew */
     }
 
   /* The following is a little endian word. */
@@ -3457,10 +3469,18 @@ ccid_transceive_secure (ccid_driver_t handle,
       msg[msglen++] = 2;    /* bMsgIndex3. */
     }
 
+  /* Calculate Lc.  */
+  n = pininfo->fixedlen;
+  if (apdu_buf[1] == 0x24)
+    n += pininfo->fixedlen;
+
   /* bTeoProlog follows: */
   msg[msglen++] = handle->nonnull_nad? ((1 << 4) | 0): 0;
   msg[msglen++] = ((handle->t1_ns & 1) << 6); /* I-block */
-  msg[msglen++] = 0; /* The apdulen will be filled in by the reader.  */
+  if (n)
+    msg[msglen++] = n + 5; /* apdulen should be filled for fixed length.  */
+  else
+    msg[msglen++] = 0; /* The apdulen will be filled in by the reader.  */
   /* APDU follows:  */
   msg[msglen++] = apdu_buf[0]; /* CLA */
   msg[msglen++] = apdu_buf[1]; /* INS */
@@ -3468,6 +3488,12 @@ ccid_transceive_secure (ccid_driver_t handle,
   msg[msglen++] = apdu_buf[3]; /* P2 */
   if (cherry_mode)
     msg[msglen++] = 0;
+  else if (pininfo->fixedlen != 0)
+    {
+      msg[msglen++] = n;
+      memset (&msg[msglen], 0xff, n);
+      msglen += n;
+    }
   /* An EDC is not required. */
   set_msg_len (msg, msglen - 10);
 
diff --git a/scd/iso7816.h b/scd/iso7816.h
index e6dfecd..bf195ea 100644
--- a/scd/iso7816.h
+++ b/scd/iso7816.h
@@ -34,7 +34,12 @@
    ccid-driver.c for details. */
 struct pininfo_s
 {
-  int mode;    /* 0: Use variable length input.  1: Use fixed length input. */
+  int fixedlen;  /*
+		  * -1: Variable length input is not supported,
+		  *     no information of fixed length yet.
+		  *  0: Use variable length input.
+		  * >0: Fixed length of PIN.
+		  */
   int minlen;
   int maxlen;
 };

commit a3be9e586f9a58295dbae0a23ec230d1f7d6af93
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Wed Jan 9 14:10:08 2013 +0900

    SCD: API cleanup for keypad handling.
    
    * scd/iso7816.h (struct pininfo_s): Rename from iso7816_pininfo_s.
    Change meaning of MODE.
    (pininfo_t): Rename from iso7816_pininfo_t.
    * scd/sc-copykeys.c: Include "iso7816.h".
    * scd/scdaemon.c, scd/command.c: Likewise.
    * scd/ccid-driver.c: Include "scdaemon.h" and "iso7816.h".
    (ccid_transceive_secure): Follow the change of PININFO_T.
    * scd/app.c: Include "apdu.h" after "iso7816.h".
    * scd/iso7816.c (iso7816_check_keypad, iso7816_verify_kp)
    (iso7816_change_reference_data_kp): Follow the change of API.
    * scd/apdu.c (struct reader_table_s): Change API of CHECK_KEYPAD,
    KEYPAD_VERIFY, KEYPAD_MODIFY to have arg of PININFO_T.
    (check_pcsc_keypad, check_ccid_keypad): Likewise.
    (apdu_check_keypad, apdu_keypad_verify, apdu_keypad_modify): Likewise.
    (pcsc_keypad_verify, pcsc_keypad_modify, ct_send_apdu)
    (pcsc_send_apdu_direct,  pcsc_send_apdu_wrapped, pcsc_send_apdu)
    (send_apdu_ccid, ccid_keypad_operation, my_rapdu_send_apdu, send_apdu)
    (send_le): Follow the change of API.
    * scd/apdu.h (apdu_check_keypad, apdu_keypad_verify)
    (apdu_keypad_modify): Change the API.
    * scd/app-dinsig.c, scd/app-nks.c, scd/app-openpgp.c: Follow the
    change.

diff --git a/scd/apdu.c b/scd/apdu.c
index 9f4c288..1e776df 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -60,10 +60,9 @@
 #include "exechelp.h"
 #endif /* GNUPG_MAJOR_VERSION != 1 */
 
+#include "iso7816.h"
 #include "apdu.h"
 #include "ccid-driver.h"
-#include "iso7816.h"
-
 
 /* Due to conflicting use of threading libraries we usually can't link
    against libpcsclite.   Instead we use a wrapper program.  */
@@ -83,8 +82,6 @@
 #define DLSTDCALL
 #endif
 
-#define pininfo_s iso7816_pininfo_s
-
 /* A structure to collect information pertaining to one reader
    slot. */
 struct reader_table_s {
@@ -99,12 +96,12 @@ struct reader_table_s {
   int (*reset_reader)(int);
   int (*get_status_reader)(int, unsigned int *);
   int (*send_apdu_reader)(int,unsigned char *,size_t,
-                          unsigned char *, size_t *, struct pininfo_s *);
-  int (*check_keypad)(int, int, int, int, int);
+                          unsigned char *, size_t *, pininfo_t *);
+  int (*check_keypad)(int, int, pininfo_t *);
   void (*dump_status_reader)(int);
   int (*set_progress_cb)(int, gcry_handler_progress_t, void*);
-  int (*keypad_verify)(int, int, int, int, int, struct pininfo_s *);
-  int (*keypad_modify)(int, int, int, int, int, struct pininfo_s *);
+  int (*keypad_verify)(int, int, int, int, int, pininfo_t *);
+  int (*keypad_modify)(int, int, int, int, int, pininfo_t *);
 
   struct {
     ccid_driver_t handle;
@@ -322,12 +319,11 @@ static int reset_pcsc_reader (int slot);
 static int apdu_get_status_internal (int slot, int hang, int no_atr_reset,
                                      unsigned int *status,
                                      unsigned int *changed);
-static int check_pcsc_keypad (int slot, int command, int pin_mode,
-                              int pinlen_min, int pinlen_max);
+static int check_pcsc_keypad (int slot, int command, pininfo_t *pininfo);
 static int pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1,
-                               struct pininfo_s *pininfo);
+                               pininfo_t *pininfo);
 static int pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1,
-                               struct pininfo_s *pininfo);
+                               pininfo_t *pininfo);
 
 
 
@@ -600,7 +596,7 @@ ct_get_status (int slot, unsigned int *status)
    set to BUFLEN.  Returns: CT API error code. */
 static int
 ct_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
-              unsigned char *buffer, size_t *buflen, struct pininfo_s *pininfo)
+              unsigned char *buffer, size_t *buflen, pininfo_t *pininfo)
 {
   int rc;
   unsigned char dad[1], sad[1];
@@ -1031,7 +1027,7 @@ pcsc_get_status (int slot, unsigned int *status)
 static int
 pcsc_send_apdu_direct (int slot, unsigned char *apdu, size_t apdulen,
                        unsigned char *buffer, size_t *buflen,
-                       struct pininfo_s *pininfo)
+                       pininfo_t *pininfo)
 {
   long err;
   struct pcsc_io_request_s send_pci;
@@ -1067,7 +1063,7 @@ pcsc_send_apdu_direct (int slot, unsigned char *apdu, size_t apdulen,
 static int
 pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen,
                         unsigned char *buffer, size_t *buflen,
-                        struct pininfo_s *pininfo)
+                        pininfo_t *pininfo)
 {
   long err;
   reader_table_t slotp;
@@ -1187,7 +1183,7 @@ pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen,
 static int
 pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
                 unsigned char *buffer, size_t *buflen,
-                struct pininfo_s *pininfo)
+                pininfo_t *pininfo)
 {
 #ifdef NEED_PCSC_WRAPPER
   return pcsc_send_apdu_wrapped (slot, apdu, apdulen, buffer, buflen, pininfo);
@@ -1984,16 +1980,13 @@ open_pcsc_reader (const char *portstr)
 /* Check whether the reader supports the ISO command code COMMAND
    on the keypad.  Return 0 on success.  */
 static int
-check_pcsc_keypad (int slot, int command, int pin_mode,
-                   int pinlen_min, int pinlen_max)
+check_pcsc_keypad (int slot, int command, pininfo_t *pininfo)
 {
   unsigned char buf[256];
   size_t len = 256;
   int sw;
 
-  (void)pin_mode;
-  (void)pinlen_min;
-  (void)pinlen_max;
+  (void)pininfo;
 
  check_again:
   if (command == ISO7816_VERIFY)
@@ -2045,7 +2038,7 @@ check_pcsc_keypad (int slot, int command, int pin_mode,
 #define PIN_VERIFY_STRUCTURE_SIZE 24
 static int
 pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1,
-                    struct pininfo_s *pininfo)
+                    pininfo_t *pininfo)
 {
   int sw;
   unsigned char *pin_verify;
@@ -2126,7 +2119,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1,
 #define PIN_MODIFY_STRUCTURE_SIZE 29
 static int
 pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1,
-                    struct pininfo_s *pininfo)
+                    pininfo_t *pininfo)
 {
   int sw;
   unsigned char *pin_modify;
@@ -2297,7 +2290,7 @@ get_status_ccid (int slot, unsigned int *status)
 static int
 send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen,
                 unsigned char *buffer, size_t *buflen,
-                struct pininfo_s *pininfo)
+                pininfo_t *pininfo)
 {
   long err;
   size_t maxbuflen;
@@ -2313,10 +2306,7 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen,
   maxbuflen = *buflen;
   if (pininfo)
     err = ccid_transceive_secure (reader_table[slot].ccid.handle,
-                                  apdu, apdulen,
-                                  pininfo->mode,
-                                  pininfo->minlen,
-                                  pininfo->maxlen,
+                                  apdu, apdulen, pininfo,
                                   buffer, maxbuflen, buflen);
   else
     err = ccid_transceive (reader_table[slot].ccid.handle,
@@ -2334,22 +2324,19 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen,
    on the keypad.  Return 0 on success.  For a description of the pin
    parameters, see ccid-driver.c */
 static int
-check_ccid_keypad (int slot, int command, int pin_mode,
-                   int pinlen_min, int pinlen_max)
+check_ccid_keypad (int slot, int command, pininfo_t *pininfo)
 {
   unsigned char apdu[] = { 0, 0, 0, 0x81 };
 
   apdu[1] = command;
-  return ccid_transceive_secure (reader_table[slot].ccid.handle,
-                                 apdu, sizeof apdu,
-                                 pin_mode, pinlen_min, pinlen_max,
-                                 NULL, 0, NULL);
+  return ccid_transceive_secure (reader_table[slot].ccid.handle, apdu,
+				 sizeof apdu, pininfo, NULL, 0, NULL);
 }
 
 
 static int
 ccid_keypad_operation (int slot, int class, int ins, int p0, int p1,
-		       struct pininfo_s *pininfo)
+		       pininfo_t *pininfo)
 {
   unsigned char apdu[4];
   int err, sw;
@@ -2361,8 +2348,7 @@ ccid_keypad_operation (int slot, int class, int ins, int p0, int p1,
   apdu[2] = p0;
   apdu[3] = p1;
   err = ccid_transceive_secure (reader_table[slot].ccid.handle,
-                                apdu, sizeof apdu,
-                                pininfo->mode, pininfo->minlen, pininfo->maxlen,
+                                apdu, sizeof apdu, pininfo,
                                 result, 2, &resultlen);
   if (err)
     return err;
@@ -2580,7 +2566,7 @@ my_rapdu_get_status (int slot, unsigned int *status)
 static int
 my_rapdu_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
                     unsigned char *buffer, size_t *buflen,
-                    struct pininfo_s *pininfo)
+                    pininfo_t *pininfo)
 {
   int err;
   reader_table_t slotp;
@@ -3405,57 +3391,46 @@ apdu_get_status (int slot, int hang,
    the keypad.  Return 0 on success.  For a description of the pin
    parameters, see ccid-driver.c */
 int
-apdu_check_keypad (int slot, int command, int pin_mode,
-                   int pinlen_min, int pinlen_max)
+apdu_check_keypad (int slot, int command, pininfo_t *pininfo)
 {
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
     return SW_HOST_NO_DRIVER;
 
+  if (opt.enable_keypad_varlen)
+    pininfo->mode = 0;
+
   if (reader_table[slot].check_keypad)
-    return reader_table[slot].check_keypad (slot, command,
-                                            pin_mode, pinlen_min, pinlen_max);
+    return reader_table[slot].check_keypad (slot, command, pininfo);
   else
     return SW_HOST_NOT_SUPPORTED;
 }
 
 
 int
-apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, int pin_mode,
-                    int pinlen_min, int pinlen_max)
+apdu_keypad_verify (int slot, int class, int ins, int p0, int p1,
+		    pininfo_t *pininfo)
 {
-  struct pininfo_s pininfo;
-
-  pininfo.mode = pin_mode;
-  pininfo.minlen = pinlen_min;
-  pininfo.maxlen = pinlen_max;
-
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
     return SW_HOST_NO_DRIVER;
 
   if (reader_table[slot].keypad_verify)
     return reader_table[slot].keypad_verify (slot, class, ins, p0, p1,
-                                             &pininfo);
+					     pininfo);
   else
     return SW_HOST_NOT_SUPPORTED;
 }
 
 
 int
-apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, int pin_mode,
-                    int pinlen_min, int pinlen_max)
+apdu_keypad_modify (int slot, int class, int ins, int p0, int p1,
+		    pininfo_t *pininfo)
 {
-  struct pininfo_s pininfo;
-
-  pininfo.mode = pin_mode;
-  pininfo.minlen = pinlen_min;
-  pininfo.maxlen = pinlen_max;
-
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
     return SW_HOST_NO_DRIVER;
 
   if (reader_table[slot].keypad_modify)
     return reader_table[slot].keypad_modify (slot, class, ins, p0, p1,
-                                             &pininfo);
+                                             pininfo);
   else
     return SW_HOST_NOT_SUPPORTED;
 }
@@ -3465,7 +3440,7 @@ apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, int pin_mode,
    function should be called in locked state. */
 static int
 send_apdu (int slot, unsigned char *apdu, size_t apdulen,
-           unsigned char *buffer, size_t *buflen, struct pininfo_s *pininfo)
+           unsigned char *buffer, size_t *buflen, pininfo_t *pininfo)
 {
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
     return SW_HOST_NO_DRIVER;
@@ -3497,7 +3472,7 @@ static int
 send_le (int slot, int class, int ins, int p0, int p1,
          int lc, const char *data, int le,
          unsigned char **retbuf, size_t *retbuflen,
-         struct pininfo_s *pininfo, int extended_mode)
+         pininfo_t *pininfo, int extended_mode)
 {
 #define SHORT_RESULT_BUFFER_SIZE 258
   /* We allocate 8 extra bytes as a safety margin towards a driver bug.  */
diff --git a/scd/apdu.h b/scd/apdu.h
index 6bf6176..c69fe36 100644
--- a/scd/apdu.h
+++ b/scd/apdu.h
@@ -114,12 +114,11 @@ int apdu_set_progress_cb (int slot, gcry_handler_progress_t cb, void *cb_arg);
 int apdu_reset (int slot);
 int apdu_get_status (int slot, int hang,
                      unsigned int *status, unsigned int *changed);
-int apdu_check_keypad (int slot, int command, int pin_mode,
-                       int pinlen_min, int pinlen_max);
+int apdu_check_keypad (int slot, int command, pininfo_t *pininfo);
 int apdu_keypad_verify (int slot, int class, int ins, int p0, int p1,
-                        int pin_mode, int pinlen_min, int pinlen_max);
+			pininfo_t *pininfo);
 int apdu_keypad_modify (int slot, int class, int ins, int p0, int p1,
-                        int pin_mode, int pinlen_min, int pinlen_max);
+			pininfo_t *pininfo);
 int apdu_send_simple (int slot, int extended_mode,
                       int class, int ins, int p0, int p1,
                       int lc, const char *data);
diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c
index 50db78e..f3f7d4b 100644
--- a/scd/app-dinsig.c
+++ b/scd/app-dinsig.c
@@ -282,7 +282,7 @@ verify_pin (app_t app,
 {
   const char *s;
   int rc;
-  iso7816_pininfo_t pininfo;
+  pininfo_t pininfo;
 
   if ( app->did_chv1 && !app->force_chv1 )
     return 0;  /* No need to verify it again.  */
diff --git a/scd/app-nks.c b/scd/app-nks.c
index 28ccb9a..4e7a43c 100644
--- a/scd/app-nks.c
+++ b/scd/app-nks.c
@@ -781,7 +781,7 @@ verify_pin (app_t app, int pwid, const char *desc,
             gpg_error_t (*pincb)(void*, const char *, char **),
             void *pincb_arg)
 {
-  iso7816_pininfo_t pininfo;
+  pininfo_t pininfo;
   int rc;
 
   if (!desc)
@@ -1144,7 +1144,7 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr,
   int is_sigg;
   const char *newdesc;
   int pwid;
-  iso7816_pininfo_t pininfo;
+  pininfo_t pininfo;
 
   (void)ctrl;
 
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 5928ec6..968ef98 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -1489,7 +1489,7 @@ verify_a_chv (app_t app,
   int rc = 0;
   char *prompt_buffer = NULL;
   const char *prompt;
-  iso7816_pininfo_t pininfo;
+  pininfo_t pininfo;
   int minlen = 6;
 
   assert (chvno == 1 || chvno == 2);
@@ -1707,7 +1707,7 @@ verify_chv3 (app_t app,
 
   if (!app->did_chv3)
     {
-      iso7816_pininfo_t pininfo;
+      pininfo_t pininfo;
       int minlen = 8;
       char *prompt;
 
@@ -1917,7 +1917,7 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *chvnostr,
   char *pinvalue = NULL;
   int reset_mode = !!(flags & APP_CHANGE_FLAG_RESET);
   int set_resetcode = 0;
-  iso7816_pininfo_t pininfo;
+  pininfo_t pininfo;
   int use_keypad = 0;
   int minlen = 6;
 
diff --git a/scd/app.c b/scd/app.c
index dfb5991..e6a663e 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -26,8 +26,8 @@
 
 #include "scdaemon.h"
 #include "app-common.h"
-#include "apdu.h"
 #include "iso7816.h"
+#include "apdu.h"
 #include "tlv.h"
 
 /* This table is used to keep track of locks on a per reader base.
diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c
index 710d0e2..c16c7ac 100644
--- a/scd/ccid-driver.c
+++ b/scd/ccid-driver.c
@@ -89,6 +89,8 @@
 
 #include <usb.h>
 
+#include "scdaemon.h"
+#include "iso7816.h"
 #include "ccid-driver.h"
 
 #define DRVNAME "ccid-driver: "
@@ -3296,7 +3298,7 @@ ccid_transceive (ccid_driver_t handle,
 int
 ccid_transceive_secure (ccid_driver_t handle,
                         const unsigned char *apdu_buf, size_t apdu_buflen,
-                        int pin_mode, int pinlen_min, int pinlen_max,
+			pininfo_t *pininfo,
                         unsigned char *resp, size_t maxresplen, size_t *nresp)
 {
   int rc;
@@ -3307,7 +3309,7 @@ ccid_transceive_secure (ccid_driver_t handle,
   size_t dummy_nresp;
   int testmode;
   int cherry_mode = 0;
-  int enable_varlen = opt.enable_keypad_varlen;
+  int enable_varlen = 0;
 
   testmode = !resp && !nresp;
 
@@ -3322,18 +3324,15 @@ ccid_transceive_secure (ccid_driver_t handle,
   else
     return CCID_DRIVER_ERR_NO_KEYPAD;
 
-  if (pin_mode != 1)
-    return CCID_DRIVER_ERR_NOT_SUPPORTED;
-
-  if (!pinlen_min)
-    pinlen_min = 1;
-  if (!pinlen_max)
-    pinlen_max = 25;
+  if (!pininfo->minlen)
+    pininfo->minlen = 1;
+  if (!pininfo->maxlen)
+    pininfo->maxlen = 25;
 
   /* Note that the 25 is the maximum value the SPR532 allows.  */
-  if (pinlen_min < 1 || pinlen_min > 25
-      || pinlen_max < 1 || pinlen_max > 25
-      || pinlen_min > pinlen_max)
+  if (pininfo->minlen < 1 || pininfo->minlen > 25
+      || pininfo->maxlen < 1 || pininfo->maxlen > 25
+      || pininfo->minlen > pininfo->maxlen)
     return CCID_DRIVER_ERR_INV_VALUE;
 
   /* We have only tested a few readers so better don't risk anything
@@ -3347,7 +3346,7 @@ ccid_transceive_secure (ccid_driver_t handle,
       break;
     case VENDOR_VASCO: /* Tested with DIGIPASS 920 */
       enable_varlen = 1;
-      pinlen_max = 15;
+      pininfo->maxlen = 15;
       break;
     case VENDOR_CHERRY:
       enable_varlen = 1;
@@ -3370,6 +3369,12 @@ ccid_transceive_secure (ccid_driver_t handle,
      return CCID_DRIVER_ERR_NOT_SUPPORTED;
     }
 
+  if (enable_varlen)
+    pininfo->mode = 0;
+
+  if (pininfo->mode != 0 && pininfo->mode != 1)
+    return CCID_DRIVER_ERR_NOT_SUPPORTED;
+
   if (testmode)
     return 0; /* Success */
 
@@ -3417,8 +3422,8 @@ ccid_transceive_secure (ccid_driver_t handle,
     }
 
   /* The following is a little endian word. */
-  msg[msglen++] = pinlen_max;   /* wPINMaxExtraDigit-Maximum.  */
-  msg[msglen++] = pinlen_min;   /* wPINMaxExtraDigit-Minimum.  */
+  msg[msglen++] = pininfo->maxlen;   /* wPINMaxExtraDigit-Maximum.  */
+  msg[msglen++] = pininfo->minlen;   /* wPINMaxExtraDigit-Minimum.  */
 
   if (apdu_buf[1] == 0x24)
     msg[msglen++] = apdu_buf[2] == 0 ? 0x03 : 0x01;
@@ -3431,7 +3436,7 @@ ccid_transceive_secure (ccid_driver_t handle,
 
   msg[msglen] = 0x02; /* bEntryValidationCondition:
                          Validation key pressed */
-  if (pinlen_min && pinlen_max && pinlen_min == pinlen_max)
+  if (pininfo->minlen && pininfo->maxlen && pininfo->minlen == pininfo->maxlen)
     msg[msglen] |= 0x01; /* Max size reached.  */
   msglen++;
 
diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h
index e0f4895..217bb72 100644
--- a/scd/ccid-driver.h
+++ b/scd/ccid-driver.h
@@ -93,8 +93,7 @@ int ccid_transceive (ccid_driver_t handle,
                      unsigned char *resp, size_t maxresplen, size_t *nresp);
 int ccid_transceive_secure (ccid_driver_t handle,
                      const unsigned char *apdu, size_t apdulen,
-                     int pin_mode,
-                     int pinlen_min, int pinlen_max,
+		     pininfo_t *pininfo,
                      unsigned char *resp, size_t maxresplen, size_t *nresp);
 int ccid_transceive_escape (ccid_driver_t handle,
                             const unsigned char *data, size_t datalen,
diff --git a/scd/command.c b/scd/command.c
index 40e61a4..343830a 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -34,6 +34,7 @@
 #include <assuan.h>
 #include <ksba.h>
 #include "app-common.h"
+#include "iso7816.h"
 #include "apdu.h" /* Required for apdu_*_reader (). */
 #include "atr.h"
 #include "exechelp.h"
diff --git a/scd/iso7816.c b/scd/iso7816.c
index 966a741..b2324b4 100644
--- a/scd/iso7816.c
+++ b/scd/iso7816.c
@@ -269,12 +269,11 @@ iso7816_apdu_direct (int slot, const void *apdudata, size_t apdudatalen,
 /* Check whether the reader supports the ISO command code COMMAND on
    the keypad.  Returns 0 on success.  */
 gpg_error_t
-iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo)
+iso7816_check_keypad (int slot, int command, pininfo_t *pininfo)
 {
   int sw;
 
-  sw = apdu_check_keypad (slot, command,
-                          pininfo->mode, pininfo->minlen, pininfo->maxlen);
+  sw = apdu_check_keypad (slot, command, pininfo);
   return iso7816_map_sw (sw);
 }
 
@@ -283,12 +282,11 @@ iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo)
    vector CHVNO.  With PININFO non-NULL the keypad of the reader will
    be used.  Returns 0 on success. */
 gpg_error_t
-iso7816_verify_kp (int slot, int chvno, iso7816_pininfo_t *pininfo)
+iso7816_verify_kp (int slot, int chvno, pininfo_t *pininfo)
 {
   int sw;
 
-  sw = apdu_keypad_verify (slot, 0x00, CMD_VERIFY, 0, chvno,
-                           pininfo->mode, pininfo->minlen, pininfo->maxlen);
+  sw = apdu_keypad_verify (slot, 0x00, CMD_VERIFY, 0, chvno, pininfo);
   return map_sw (sw);
 }
 
@@ -309,14 +307,12 @@ iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen)
    data" is done, otherwise an "exchange reference data".  */
 gpg_error_t
 iso7816_change_reference_data_kp (int slot, int chvno, int is_exchange,
-                                  iso7816_pininfo_t *pininfo)
+                                  pininfo_t *pininfo)
 {
   int sw;
 
   sw = apdu_keypad_modify (slot, 0x00, CMD_CHANGE_REFERENCE_DATA,
-			   is_exchange ? 1 : 0,
-			   chvno, pininfo->mode, pininfo->minlen,
-			   pininfo->maxlen);
+			   is_exchange ? 1 : 0, chvno, pininfo);
   return map_sw (sw);
 }
 
diff --git a/scd/iso7816.h b/scd/iso7816.h
index a4e5b70..e6dfecd 100644
--- a/scd/iso7816.h
+++ b/scd/iso7816.h
@@ -32,13 +32,13 @@
 
 /* Information to be passed to keypad equipped readers.  See
    ccid-driver.c for details. */
-struct iso7816_pininfo_s
+struct pininfo_s
 {
-  int mode;    /* A mode of 0 means: Do not use the keypad. */
+  int mode;    /* 0: Use variable length input.  1: Use fixed length input. */
   int minlen;
   int maxlen;
 };
-typedef struct iso7816_pininfo_s iso7816_pininfo_t;
+typedef struct pininfo_s pininfo_t;
 
 
 gpg_error_t iso7816_map_sw (int sw);
@@ -58,16 +58,16 @@ gpg_error_t iso7816_apdu_direct (int slot,
                                  int handle_more,
                                  unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_check_keypad (int slot, int command,
-                                  iso7816_pininfo_t *pininfo);
+                                  pininfo_t *pininfo);
 gpg_error_t iso7816_verify (int slot,
                             int chvno, const char *chv, size_t chvlen);
-gpg_error_t iso7816_verify_kp (int slot, int chvno, iso7816_pininfo_t *pininfo);
+gpg_error_t iso7816_verify_kp (int slot, int chvno, pininfo_t *pininfo);
 gpg_error_t iso7816_change_reference_data (int slot, int chvno,
                                const char *oldchv, size_t oldchvlen,
                                const char *newchv, size_t newchvlen);
 gpg_error_t iso7816_change_reference_data_kp (int slot, int chvno,
 					      int is_exchange,
-                                              iso7816_pininfo_t *pininfo);
+                                              pininfo_t *pininfo);
 gpg_error_t iso7816_reset_retry_counter (int slot, int chvno,
                                          const char *newchv, size_t newchvlen);
 gpg_error_t iso7816_reset_retry_counter_with_rc (int slot, int chvno,
diff --git a/scd/sc-copykeys.c b/scd/sc-copykeys.c
index 3f34d69..e503d36 100644
--- a/scd/sc-copykeys.c
+++ b/scd/sc-copykeys.c
@@ -33,6 +33,7 @@
 
 #include "../common/ttyio.h"
 #include "../common/simple-pwquery.h"
+#include "iso7816.h"
 #include "apdu.h" /* for open_reader */
 #include "atr.h"
 #include "app-common.h"
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index 1b61894..f8a86c8 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -48,6 +48,7 @@
 #include "i18n.h"
 #include "sysutils.h"
 #include "app-common.h"
+#include "iso7816.h"
 #include "apdu.h"
 #include "ccid-driver.h"
 #include "mkdtemp.h"

commit d75de701f52ad2c0dd27bee16446ae9ca8f52c32
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Mon Jan 7 14:20:55 2013 +0900

    SCD: Clean up.  Remove PADLEN for keypad input.
    
    * scd/apdu.c (struct pininfo_s): Use iso7816_pininfo_s.
    (struct reader_table_s): Remove last arg from check_keypad method.
    (check_pcsc_keypad, check_pcsc_keypad): Remove PIN_PADLEN.
    (pcsc_keypad_verify, pcsc_keypad_modify): Don't check PIN_PADLEN.
    (send_apdu_ccid, ccid_keypad_operation): Remove PIN_PADLEN.
    (apdu_check_keypad, apdu_keypad_verify, apdu_keypad_modify):
    Likewise.
    
    * scd/apdu.h (apdu_check_keypad, apdu_keypad_verify)
    (apdu_keypad_modify): Remove PIN_PADLEN.
    
    * scd/ccid-driver.c (ccid_transceive_secure): Remove PIN_PADLEN.
    
    * scd/ccid-driver.h (ccid_transceive_secure): Remove PIN_PADLEN.
    
    * scd/iso7816.c (iso7816_check_keypad, iso7816_verify_kp)
    (iso7816_change_reference_data_kp): Remove PADLEN.
    
    * scd/iso7816.h (struct iso7816_pininfo_s): Remove PADLEN, PADCHAR.
    --
    In the OpenPGPcard specification, password comes with no padding.  In
    GnuPG, we support keypad input for OpenPGPcard only.  Thus, it is
    useless to try to support padding for keypad input.

diff --git a/scd/apdu.c b/scd/apdu.c
index 68d4e99..9f4c288 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -83,15 +83,7 @@
 #define DLSTDCALL
 #endif
 
-
-/* Helper to pass parameters related to keypad based operations. */
-struct pininfo_s
-{
-  int mode;
-  int minlen;
-  int maxlen;
-  int padlen;
-};
+#define pininfo_s iso7816_pininfo_s
 
 /* A structure to collect information pertaining to one reader
    slot. */
@@ -108,7 +100,7 @@ struct reader_table_s {
   int (*get_status_reader)(int, unsigned int *);
   int (*send_apdu_reader)(int,unsigned char *,size_t,
                           unsigned char *, size_t *, struct pininfo_s *);
-  int (*check_keypad)(int, int, int, int, int, int);
+  int (*check_keypad)(int, int, int, int, int);
   void (*dump_status_reader)(int);
   int (*set_progress_cb)(int, gcry_handler_progress_t, void*);
   int (*keypad_verify)(int, int, int, int, int, struct pininfo_s *);
@@ -331,7 +323,7 @@ static int apdu_get_status_internal (int slot, int hang, int no_atr_reset,
                                      unsigned int *status,
                                      unsigned int *changed);
 static int check_pcsc_keypad (int slot, int command, int pin_mode,
-                              int pinlen_min, int pinlen_max, int pin_padlen);
+                              int pinlen_min, int pinlen_max);
 static int pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1,
                                struct pininfo_s *pininfo);
 static int pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1,
@@ -1993,7 +1985,7 @@ open_pcsc_reader (const char *portstr)
    on the keypad.  Return 0 on success.  */
 static int
 check_pcsc_keypad (int slot, int command, int pin_mode,
-                   int pinlen_min, int pinlen_max, int pin_padlen)
+                   int pinlen_min, int pinlen_max)
 {
   unsigned char buf[256];
   size_t len = 256;
@@ -2002,7 +1994,6 @@ check_pcsc_keypad (int slot, int command, int pin_mode,
   (void)pin_mode;
   (void)pinlen_min;
   (void)pinlen_max;
-  (void)pin_padlen;
 
  check_again:
   if (command == ISO7816_VERIFY)
@@ -2069,9 +2060,6 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1,
   if (pininfo->mode != 1)
     return SW_NOT_SUPPORTED;
 
-  if (pininfo->padlen != 0)
-    return SW_NOT_SUPPORTED;
-
   if (!pininfo->minlen)
     pininfo->minlen = 1;
   if (!pininfo->maxlen)
@@ -2153,9 +2141,6 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1,
   if (pininfo->mode != 1)
     return SW_NOT_SUPPORTED;
 
-  if (pininfo->padlen != 0)
-    return SW_NOT_SUPPORTED;
-
   if (!pininfo->minlen)
     pininfo->minlen = 1;
   if (!pininfo->maxlen)
@@ -2332,7 +2317,6 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen,
                                   pininfo->mode,
                                   pininfo->minlen,
                                   pininfo->maxlen,
-                                  pininfo->padlen,
                                   buffer, maxbuflen, buflen);
   else
     err = ccid_transceive (reader_table[slot].ccid.handle,
@@ -2351,14 +2335,14 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen,
    parameters, see ccid-driver.c */
 static int
 check_ccid_keypad (int slot, int command, int pin_mode,
-                   int pinlen_min, int pinlen_max, int pin_padlen)
+                   int pinlen_min, int pinlen_max)
 {
   unsigned char apdu[] = { 0, 0, 0, 0x81 };
 
   apdu[1] = command;
   return ccid_transceive_secure (reader_table[slot].ccid.handle,
                                  apdu, sizeof apdu,
-                                 pin_mode, pinlen_min, pinlen_max, pin_padlen,
+                                 pin_mode, pinlen_min, pinlen_max,
                                  NULL, 0, NULL);
 }
 
@@ -2379,7 +2363,6 @@ ccid_keypad_operation (int slot, int class, int ins, int p0, int p1,
   err = ccid_transceive_secure (reader_table[slot].ccid.handle,
                                 apdu, sizeof apdu,
                                 pininfo->mode, pininfo->minlen, pininfo->maxlen,
-                                pininfo->padlen,
                                 result, 2, &resultlen);
   if (err)
     return err;
@@ -3423,15 +3406,14 @@ apdu_get_status (int slot, int hang,
    parameters, see ccid-driver.c */
 int
 apdu_check_keypad (int slot, int command, int pin_mode,
-                   int pinlen_min, int pinlen_max, int pin_padlen)
+                   int pinlen_min, int pinlen_max)
 {
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
     return SW_HOST_NO_DRIVER;
 
   if (reader_table[slot].check_keypad)
     return reader_table[slot].check_keypad (slot, command,
-                                            pin_mode, pinlen_min, pinlen_max,
-                                            pin_padlen);
+                                            pin_mode, pinlen_min, pinlen_max);
   else
     return SW_HOST_NOT_SUPPORTED;
 }
@@ -3439,14 +3421,13 @@ apdu_check_keypad (int slot, int command, int pin_mode,
 
 int
 apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, int pin_mode,
-                    int pinlen_min, int pinlen_max, int pin_padlen)
+                    int pinlen_min, int pinlen_max)
 {
   struct pininfo_s pininfo;
 
   pininfo.mode = pin_mode;
   pininfo.minlen = pinlen_min;
   pininfo.maxlen = pinlen_max;
-  pininfo.padlen = pin_padlen;
 
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
     return SW_HOST_NO_DRIVER;
@@ -3461,14 +3442,13 @@ apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, int pin_mode,
 
 int
 apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, int pin_mode,
-                    int pinlen_min, int pinlen_max, int pin_padlen)
+                    int pinlen_min, int pinlen_max)
 {
   struct pininfo_s pininfo;
 
   pininfo.mode = pin_mode;
   pininfo.minlen = pinlen_min;
   pininfo.maxlen = pinlen_max;
-  pininfo.padlen = pin_padlen;
 
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
     return SW_HOST_NO_DRIVER;
diff --git a/scd/apdu.h b/scd/apdu.h
index bf55346..6bf6176 100644
--- a/scd/apdu.h
+++ b/scd/apdu.h
@@ -115,13 +115,11 @@ int apdu_reset (int slot);
 int apdu_get_status (int slot, int hang,
                      unsigned int *status, unsigned int *changed);
 int apdu_check_keypad (int slot, int command, int pin_mode,
-                       int pinlen_min, int pinlen_max, int pin_padlen);
+                       int pinlen_min, int pinlen_max);
 int apdu_keypad_verify (int slot, int class, int ins, int p0, int p1,
-                        int pin_mode, int pinlen_min, int pinlen_max,
-                        int pin_padlen);
+                        int pin_mode, int pinlen_min, int pinlen_max);
 int apdu_keypad_modify (int slot, int class, int ins, int p0, int p1,
-                        int pin_mode, int pinlen_min, int pinlen_max,
-                        int pin_padlen);
+                        int pin_mode, int pinlen_min, int pinlen_max);
 int apdu_send_simple (int slot, int extended_mode,
                       int class, int ins, int p0, int p1,
                       int lc, const char *data);
diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c
index f545c71..710d0e2 100644
--- a/scd/ccid-driver.c
+++ b/scd/ccid-driver.c
@@ -3288,7 +3288,7 @@ ccid_transceive (ccid_driver_t handle,
           The APDU should me made up of 4 bytes without Lc.
 
    PINLEN_MIN and PINLEN_MAX define the limits for the pin length. 0
-   may be used t enable reasonable defaults.  PIN_PADLEN should be 0.
+   may be used t enable reasonable defaults.
 
    When called with RESP and NRESP set to NULL, the function will
    merely check whether the reader supports the secure command for the
@@ -3297,7 +3297,6 @@ int
 ccid_transceive_secure (ccid_driver_t handle,
                         const unsigned char *apdu_buf, size_t apdu_buflen,
                         int pin_mode, int pinlen_min, int pinlen_max,
-                        int pin_padlen,
                         unsigned char *resp, size_t maxresplen, size_t *nresp)
 {
   int rc;
@@ -3326,9 +3325,6 @@ ccid_transceive_secure (ccid_driver_t handle,
   if (pin_mode != 1)
     return CCID_DRIVER_ERR_NOT_SUPPORTED;
 
-  if (pin_padlen != 0)
-    return CCID_DRIVER_ERR_NOT_SUPPORTED;
-
   if (!pinlen_min)
     pinlen_min = 1;
   if (!pinlen_max)
diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h
index 121cb94..e0f4895 100644
--- a/scd/ccid-driver.h
+++ b/scd/ccid-driver.h
@@ -94,7 +94,7 @@ int ccid_transceive (ccid_driver_t handle,
 int ccid_transceive_secure (ccid_driver_t handle,
                      const unsigned char *apdu, size_t apdulen,
                      int pin_mode,
-                     int pinlen_min, int pinlen_max, int pin_padlen,
+                     int pinlen_min, int pinlen_max,
                      unsigned char *resp, size_t maxresplen, size_t *nresp);
 int ccid_transceive_escape (ccid_driver_t handle,
                             const unsigned char *data, size_t datalen,
diff --git a/scd/iso7816.c b/scd/iso7816.c
index 45f5e08..966a741 100644
--- a/scd/iso7816.c
+++ b/scd/iso7816.c
@@ -274,8 +274,7 @@ iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo)
   int sw;
 
   sw = apdu_check_keypad (slot, command,
-                          pininfo->mode, pininfo->minlen, pininfo->maxlen,
-                          pininfo->padlen);
+                          pininfo->mode, pininfo->minlen, pininfo->maxlen);
   return iso7816_map_sw (sw);
 }
 
@@ -289,8 +288,7 @@ iso7816_verify_kp (int slot, int chvno, iso7816_pininfo_t *pininfo)
   int sw;
 
   sw = apdu_keypad_verify (slot, 0x00, CMD_VERIFY, 0, chvno,
-                           pininfo->mode, pininfo->minlen, pininfo->maxlen,
-                           pininfo->padlen);
+                           pininfo->mode, pininfo->minlen, pininfo->maxlen);
   return map_sw (sw);
 }
 
@@ -318,7 +316,7 @@ iso7816_change_reference_data_kp (int slot, int chvno, int is_exchange,
   sw = apdu_keypad_modify (slot, 0x00, CMD_CHANGE_REFERENCE_DATA,
 			   is_exchange ? 1 : 0,
 			   chvno, pininfo->mode, pininfo->minlen,
-			   pininfo->maxlen, pininfo->padlen);
+			   pininfo->maxlen);
   return map_sw (sw);
 }
 
diff --git a/scd/iso7816.h b/scd/iso7816.h
index 336208a..a4e5b70 100644
--- a/scd/iso7816.h
+++ b/scd/iso7816.h
@@ -37,8 +37,6 @@ struct iso7816_pininfo_s
   int mode;    /* A mode of 0 means: Do not use the keypad. */
   int minlen;
   int maxlen;
-  int padlen;
-  int padchar;
 };
 typedef struct iso7816_pininfo_s iso7816_pininfo_t;
 

commit 23edafc0327a39331535dd162024e09a90d6733c
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Wed Jan 9 13:24:57 2013 +0900

    SCD: Add option enable-keypad-varlen and support for GEMPC_PINPAD.
    
    * scd/scdaemon.h (opt): Add enable_keypad_varlen.
    * scd/scdaemon.c (cmd_and_opt_values): Add oEnableKeypadVarlen.
    (opts, main): Add oEnableKeypadVarlen.
    * scd/ccid-driver.c (GEMPC_PINPAD): New.
    (ccid_transceive_secure): Add enable_varlen handling.
    Enable GEMPC_PINPAD.
    --
    Note that GEMPC_PINPAD doesn't support variable length keypad input.
    The feature of fixed length keypad input will be added soon.

diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c
index 5b3bcaf..f545c71 100644
--- a/scd/ccid-driver.c
+++ b/scd/ccid-driver.c
@@ -220,6 +220,7 @@ enum {
 #define SCM_SPR532      0xe003
 #define CHERRY_ST2000   0x003e
 #define VASCO_920       0x0920
+#define GEMPC_PINPAD	0x3478
 
 /* A list and a table with special transport descriptions. */
 enum {
@@ -3307,6 +3308,7 @@ ccid_transceive_secure (ccid_driver_t handle,
   size_t dummy_nresp;
   int testmode;
   int cherry_mode = 0;
+  int enable_varlen = opt.enable_keypad_varlen;
 
   testmode = !resp && !nresp;
 
@@ -3345,11 +3347,14 @@ ccid_transceive_secure (ccid_driver_t handle,
     case VENDOR_SCM:  /* Tested with SPR 532. */
     case VENDOR_KAAN: /* Tested with KAAN Advanced (1.02). */
     case VENDOR_FSIJ: /* Tested with the gnuk code (2011-01-05).  */
+      enable_varlen = 1;
       break;
     case VENDOR_VASCO: /* Tested with DIGIPASS 920 */
+      enable_varlen = 1;
       pinlen_max = 15;
       break;
     case VENDOR_CHERRY:
+      enable_varlen = 1;
       /* The CHERRY XX44 keyboard echos an asterisk for each entered
          character on the keyboard channel.  We use a special variant
          of PC_to_RDR_Secure which directs these characters to the
@@ -3360,6 +3365,11 @@ ccid_transceive_secure (ccid_driver_t handle,
       if (handle->id_product != CHERRY_ST2000)
         cherry_mode = 1;
       break;
+    case VENDOR_GEMPC:
+      enable_varlen = 0;
+      if (handle->id_product == GEMPC_PINPAD)
+	break;
+      /* fall through */
     default:
      return CCID_DRIVER_ERR_NOT_SUPPORTED;
     }
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index af4c9c1..1b61894 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -95,6 +95,7 @@ enum cmd_and_opt_values
   oAllowAdmin,
   oDenyAdmin,
   oDisableApplication,
+  oEnableKeypadVarlen,
   oDebugDisableTicker
 };
 
@@ -148,6 +149,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oDenyAdmin, "deny-admin",
                 N_("deny the use of admin card commands")),
   ARGPARSE_s_s (oDisableApplication, "disable-application", "@"),
+  ARGPARSE_s_n (oEnableKeypadVarlen, "enable-keypad-varlen",
+                N_("use variable length input for keypad")),
 
   ARGPARSE_end ()
 };
@@ -587,6 +590,8 @@ main (int argc, char **argv )
           add_to_strlist (&opt.disabled_applications, pargs.r.ret_str);
           break;
 
+	case oEnableKeypadVarlen: opt.enable_keypad_varlen = 1; break;
+
         default:
           pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
           break;
diff --git a/scd/scdaemon.h b/scd/scdaemon.h
index 74e8b7d..8f048d5 100644
--- a/scd/scdaemon.h
+++ b/scd/scdaemon.h
@@ -57,6 +57,7 @@ struct
   const char *reader_port;  /* NULL or reder port to use. */
   int disable_ccid;    /* Disable the use of the internal CCID driver. */
   int disable_keypad;  /* Do not use a keypad. */
+  int enable_keypad_varlen;  /* Use variable length input for keypad. */
   int allow_admin;     /* Allow the use of admin commands for certain
                           cards. */
   strlist_t disabled_applications;  /* Card applications we do not

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


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




More information about the Gnupg-commits mailing list