scd: pinpad workaround for PC/SC implementations. (was: scd: Fix Cherry ST-2000 support for pinpad input.)

NIIBE Yutaka gniibe at fsij.org
Tue Jun 23 03:24:48 CEST 2015


On 06/22/2015 02:41 PM, NIIBE Yutaka wrote:
> I believe that in-stock CCID driver works fine with this patch.  I'm
> not sure if the change is enough for PC/SC service on Windows.
> 
> For GNU/Linux, I recommend in-stock CCID driver.

Examining the source code of libccid and testing with it 1.4.18 and
1.4.19, I realized that we need following workaround now.  I don't
know if this is related to the behavior on Windows, but, this fixes
the case of mine with Gemalto USB GemPCPinpad SmartCard Reader.

Tested and worked fine.  I'm going to push this fix.

    scd: pinpad workaround for PC/SC implementations.

    * scd/adpu.c (pcsc_pinpad_verify, pcsc_pinpad_modify): Bigger buffer
    for TPDU card reader.

    --

    GnuPG-bug-id: 2003, 2004

    This is needed for PC/SC on Debian Jessie.  Note that it's not only
    for Cherry ST-2000, but also, for any TPDU card readers.

diff --git a/scd/apdu.c b/scd/apdu.c
index 82b2e1f..e8797cd 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -2290,8 +2290,16 @@ pcsc_pinpad_verify (int slot, int class, int ins, int p0, int p1,
   int sw;
   unsigned char *pin_verify;
   int len = PIN_VERIFY_STRUCTURE_SIZE + pininfo->fixedlen;
-  unsigned char result[2];
-  pcsc_dword_t resultlen = 2;
+  /*
+   * The result buffer is only expected to have two-byte result on
+   * return.  However, some implementation uses this buffer for lower
+   * layer too and it assumes that there is enough space for lower
+   * layer communication.  Such an implementation fails for TPDU
+   * readers with "insufficient buffer", as it needs header and
+   * trailer.  Six is the number for header + result + trailer (TPDU).
+   */
+  unsigned char result[6];
+  pcsc_dword_t resultlen = 6;
   int no_lc;

   if (!reader_table[slot].atrlen
@@ -2365,8 +2373,8 @@ pcsc_pinpad_modify (int slot, int class, int ins, int p0, int p1,
   int sw;
   unsigned char *pin_modify;
   int len = PIN_MODIFY_STRUCTURE_SIZE + 2 * pininfo->fixedlen;
-  unsigned char result[2];
-  pcsc_dword_t resultlen = 2;
+  unsigned char result[6];      /* See the comment at pinpad_verify.  */
+  pcsc_dword_t resultlen = 6;
   int no_lc;

   if (!reader_table[slot].atrlen
-- 



More information about the Gnupg-devel mailing list