w32: Add icons and version information.
[gnupg.git] / scd / ccid-driver.c
index fcc71ba..42a219f 100644 (file)
@@ -212,9 +212,10 @@ enum {
   VENDOR_OMNIKEY= 0x076b,
   VENDOR_GEMPC  = 0x08e6,
   VENDOR_VEGA   = 0x0982,
+  VENDOR_REINER = 0x0c4b,
   VENDOR_KAAN   = 0x0d46,
+  VENDOR_VASCO  = 0x1a44,
   VENDOR_FSIJ   = 0x234b,
-  VENDOR_VASCO  = 0x1a44
 };
 
 /* Some product ids.  */
@@ -227,6 +228,7 @@ enum {
 #define VASCO_920       0x0920
 #define GEMPC_PINPAD    0x3478
 #define VEGA_ALPHA      0x0008
+#define CYBERJACK_GO    0x0504
 
 /* A list and a table with special transport descriptions. */
 enum {
@@ -305,6 +307,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. */
@@ -1526,7 +1531,30 @@ ccid_get_reader_list (void)
 }
 
 
-/* Open the reader with the internal number READERNO and return a 
+/* 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. */
 int 
 ccid_open_reader (ccid_driver_t *handle, const char *readerid)
@@ -1634,6 +1662,8 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid)
         }
     }
 
+  rc = ccid_vendor_specific_init (*handle);
+
  leave:
   free (ifcdesc_extra);
   if (rc)
@@ -2812,7 +2842,7 @@ ccid_transceive_apdu_level (ccid_driver_t handle,
   /* The maximum length for a short APDU T=1 block is 261.  For an
      extended APDU T=1 block the maximum length 65544; however
      extended APDU exchange level is not fully supported yet.  */
-  if (apdulen > 289)
+  if (apdulen > sizeof (send_buffer) - 10)
     return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */
   
   msg[0] = PC_to_RDR_XfrBlock;
@@ -3325,12 +3355,12 @@ ccid_transceive_secure (ccid_driver_t handle,
   else if (apdu_buflen >= 4 && apdu_buf[1] == 0x24 && (handle->has_pinpad & 2))
     ;
   else
-    return CCID_DRIVER_ERR_NO_KEYPAD;
+    return CCID_DRIVER_ERR_NO_PINPAD;
 
   if (!pininfo->minlen)
     pininfo->minlen = 1;
   if (!pininfo->maxlen)
-    pininfo->maxlen = 25;
+    pininfo->maxlen = 15;
 
   /* Note that the 25 is the maximum value the SPR532 allows.  */
   if (pininfo->minlen < 1 || pininfo->minlen > 25
@@ -3345,13 +3375,15 @@ 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 Gnuk (0.21). */
+      pininfo->maxlen = 25;
       enable_varlen = 1;
       break;
+    case VENDOR_REINER: /* Tested with cyberJack go */
     case VENDOR_VASCO: /* Tested with DIGIPASS 920 */
       enable_varlen = 1;
-      pininfo->maxlen = 15;
       break;
     case VENDOR_CHERRY:
+      pininfo->maxlen = 25;
       enable_varlen = 1;
       /* The CHERRY XX44 keyboard echos an asterisk for each entered
          character on the keyboard channel.  We use a special variant