scd: Reader specific initialization code (scd-work branch)

NIIBE Yutaka gniibe at
Wed Jan 30 09:23:34 CET 2013


I pushed the following changes to scd-work branch.

This is to add vendor specific custom initialization.

This kind of scheme is needed for a reader named Vega Alpha.

Vega Alpha has a feature that the reader examines retry counter by
itself and shows the number to the display when authentication is
requested by pinpad.  This would be great feature, but it doesn't work
for OpenPGP card, as OpenPGP card doesn't support assumed command
sequence (of VERIFY command with empty data).

We need to disable this feature at initialization time, to reliably
use pinpad authentication.

diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c
index e9f39f4..6d6c3db 100644
--- a/scd/ccid-driver.c
+++ b/scd/ccid-driver.c
@@ -303,6 +303,9 @@ static int bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
                     size_t *nread, int expected_type, int seqno, int timeout,
                     int no_debug);
 static int abort_cmd (ccid_driver_t handle, int seqno);
+static int send_escape_cmd (ccid_driver_t handle, const unsigned char *data,
+                            size_t datalen, unsigned char *result,
+                            size_t resultmax, size_t *resultlen);
 /* Convert a little endian stored 4 byte value into an unsigned
    integer. */
@@ -1525,6 +1528,29 @@ ccid_get_reader_list (void)

+/* Vendor specific custom initialization.  */
+static int
+ccid_vendor_specific_init (ccid_driver_t handle)
+  if (handle->id_vendor == VENDOR_VEGA && handle->id_product == VEGA_ALPHA)
+    {
+      /*
+       * Vega alpha has a feature to show retry counter on the pinpad
+       * display.  But it assumes that the card returns the value of
+       * retry counter by VERIFY with empty data (return code of
+       * 63Cx).  Unfortunately, existing OpenPGP cards don't support
+       * VERIFY command with empty data.  This vendor specific command
+       * sequence is to disable the feature.
+       */
+      const unsigned char cmd[] = "\xb5\x01\x00\x03\x00";
+      return send_escape_cmd (handle, cmd, sizeof (cmd), NULL, 0, NULL);
+    }
+  return 0;
 /* Open the reader with the internal number READERNO and return a
    pointer to be used as handle in HANDLE.  Returns 0 on success. */
@@ -1633,6 +1659,8 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid)
+  rc = ccid_vendor_specific_init (*handle);
   free (ifcdesc_extra);
   if (rc)


More information about the Gnupg-devel mailing list