LCOV - code coverage report
Current view: top level - scd - ccid-driver.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1619 0.0 %
Date: 2016-11-29 15:00:56 Functions: 0 60 0.0 %

          Line data    Source code
       1             : /* ccid-driver.c - USB ChipCardInterfaceDevices driver
       2             :  * Copyright (C) 2003, 2004, 2005, 2006, 2007
       3             :  *               2008, 2009, 2013  Free Software Foundation, Inc.
       4             :  * Written by Werner Koch.
       5             :  *
       6             :  * This file is part of GnuPG.
       7             :  *
       8             :  * GnuPG is free software; you can redistribute it and/or modify
       9             :  * it under the terms of the GNU General Public License as published by
      10             :  * the Free Software Foundation; either version 3 of the License, or
      11             :  * (at your option) any later version.
      12             :  *
      13             :  * GnuPG is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  * GNU General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU General Public License
      19             :  * along with this program; if not, see <https://www.gnu.org/licenses/>.
      20             :  *
      21             :  * ALTERNATIVELY, this file may be distributed under the terms of the
      22             :  * following license, in which case the provisions of this license are
      23             :  * required INSTEAD OF the GNU General Public License. If you wish to
      24             :  * allow use of your version of this file only under the terms of the
      25             :  * GNU General Public License, and not to allow others to use your
      26             :  * version of this file under the terms of the following license,
      27             :  * indicate your decision by deleting this paragraph and the license
      28             :  * below.
      29             :  *
      30             :  * Redistribution and use in source and binary forms, with or without
      31             :  * modification, are permitted provided that the following conditions
      32             :  * are met:
      33             :  * 1. Redistributions of source code must retain the above copyright
      34             :  *    notice, and the entire permission notice in its entirety,
      35             :  *    including the disclaimer of warranties.
      36             :  * 2. Redistributions in binary form must reproduce the above copyright
      37             :  *    notice, this list of conditions and the following disclaimer in the
      38             :  *    documentation and/or other materials provided with the distribution.
      39             :  * 3. The name of the author may not be used to endorse or promote
      40             :  *    products derived from this software without specific prior
      41             :  *    written permission.
      42             :  *
      43             :  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
      44             :  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      45             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      46             :  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
      47             :  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      48             :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      49             :  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      50             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      51             :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      52             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      53             :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      54             :  */
      55             : 
      56             : 
      57             : /* CCID (ChipCardInterfaceDevices) is a specification for accessing
      58             :    smartcard via a reader connected to the USB.
      59             : 
      60             :    This is a limited driver allowing to use some CCID drivers directly
      61             :    without any other specila drivers. This is a fallback driver to be
      62             :    used when nothing else works or the system should be kept minimal
      63             :    for security reasons.  It makes use of the libusb library to gain
      64             :    portable access to USB.
      65             : 
      66             :    This driver has been tested with the SCM SCR335 and SPR532
      67             :    smartcard readers and requires that a reader implements APDU or
      68             :    TPDU level exchange and does fully automatic initialization.
      69             : */
      70             : 
      71             : #ifdef HAVE_CONFIG_H
      72             : # include <config.h>
      73             : #endif
      74             : 
      75             : #if defined(HAVE_LIBUSB) || defined(TEST)
      76             : 
      77             : #include <errno.h>
      78             : #include <stdio.h>
      79             : #include <stdlib.h>
      80             : #include <string.h>
      81             : #include <assert.h>
      82             : #include <sys/types.h>
      83             : #include <sys/stat.h>
      84             : #include <fcntl.h>
      85             : #include <time.h>
      86             : #include <unistd.h>
      87             : #ifdef HAVE_NPTH
      88             : # include <npth.h>
      89             : #endif /*HAVE_NPTH*/
      90             : 
      91             : #include <libusb.h>
      92             : 
      93             : #include "scdaemon.h"
      94             : #include "iso7816.h"
      95             : #define CCID_DRIVER_INCLUDE_USB_IDS 1
      96             : #include "ccid-driver.h"
      97             : 
      98             : #define DRVNAME "ccid-driver: "
      99             : 
     100             : /* Max length of buffer with out CCID message header of 10-byte
     101             :    Sending: 547 for RSA-4096 key import
     102             :         APDU size = 540 (24+4+256+256)
     103             :         commnd + lc + le = 4 + 3 + 0
     104             :    Sending: write data object of cardholder certificate
     105             :         APDU size = 2048
     106             :         commnd + lc + le = 4 + 3 + 0
     107             :    Receiving: 2048 for cardholder certificate
     108             : */
     109             : #define CCID_MAX_BUF (2048+7+10)
     110             : 
     111             : /* CCID command timeout.  OpenPGPcard v2.1 requires timeout of 13 seconds.  */
     112             : #define CCID_CMD_TIMEOUT (13*1000)
     113             : 
     114             : /* Depending on how this source is used we either define our error
     115             :    output to go to stderr or to the GnuPG based logging functions.  We
     116             :    use the latter when GNUPG_MAJOR_VERSION or GNUPG_SCD_MAIN_HEADER
     117             :    are defined.  */
     118             : #if defined(GNUPG_MAJOR_VERSION) || defined(GNUPG_SCD_MAIN_HEADER)
     119             : 
     120             : #if defined(GNUPG_SCD_MAIN_HEADER)
     121             : #  include GNUPG_SCD_MAIN_HEADER
     122             : #elif GNUPG_MAJOR_VERSION == 1 /* GnuPG Version is < 1.9. */
     123             : #  include "options.h"
     124             : #  include "util.h"
     125             : #  include "memory.h"
     126             : #  include "cardglue.h"
     127             : # else /* This is the modularized GnuPG 1.9 or later. */
     128             : #  include "scdaemon.h"
     129             : #endif
     130             : 
     131             : 
     132             : # define DEBUGOUT(t)         do { if (debug_level) \
     133             :                                   log_debug (DRVNAME t); } while (0)
     134             : # define DEBUGOUT_1(t,a)     do { if (debug_level) \
     135             :                                   log_debug (DRVNAME t,(a)); } while (0)
     136             : # define DEBUGOUT_2(t,a,b)   do { if (debug_level) \
     137             :                                   log_debug (DRVNAME t,(a),(b)); } while (0)
     138             : # define DEBUGOUT_3(t,a,b,c) do { if (debug_level) \
     139             :                                   log_debug (DRVNAME t,(a),(b),(c));} while (0)
     140             : # define DEBUGOUT_4(t,a,b,c,d) do { if (debug_level) \
     141             :                               log_debug (DRVNAME t,(a),(b),(c),(d));} while (0)
     142             : # define DEBUGOUT_CONT(t)    do { if (debug_level) \
     143             :                                   log_printf (t); } while (0)
     144             : # define DEBUGOUT_CONT_1(t,a)  do { if (debug_level) \
     145             :                                   log_printf (t,(a)); } while (0)
     146             : # define DEBUGOUT_CONT_2(t,a,b)   do { if (debug_level) \
     147             :                                   log_printf (t,(a),(b)); } while (0)
     148             : # define DEBUGOUT_CONT_3(t,a,b,c) do { if (debug_level) \
     149             :                                   log_printf (t,(a),(b),(c)); } while (0)
     150             : # define DEBUGOUT_LF()       do { if (debug_level) \
     151             :                                   log_printf ("\n"); } while (0)
     152             : 
     153             : #else /* Other usage of this source - don't use gnupg specifics. */
     154             : 
     155             : # define DEBUGOUT(t)          do { if (debug_level) \
     156             :                      fprintf (stderr, DRVNAME t); } while (0)
     157             : # define DEBUGOUT_1(t,a)      do { if (debug_level) \
     158             :                      fprintf (stderr, DRVNAME t, (a)); } while (0)
     159             : # define DEBUGOUT_2(t,a,b)    do { if (debug_level) \
     160             :                      fprintf (stderr, DRVNAME t, (a), (b)); } while (0)
     161             : # define DEBUGOUT_3(t,a,b,c)  do { if (debug_level) \
     162             :                      fprintf (stderr, DRVNAME t, (a), (b), (c)); } while (0)
     163             : # define DEBUGOUT_4(t,a,b,c,d)  do { if (debug_level) \
     164             :                      fprintf (stderr, DRVNAME t, (a), (b), (c), (d));} while(0)
     165             : # define DEBUGOUT_CONT(t)     do { if (debug_level) \
     166             :                      fprintf (stderr, t); } while (0)
     167             : # define DEBUGOUT_CONT_1(t,a) do { if (debug_level) \
     168             :                      fprintf (stderr, t, (a)); } while (0)
     169             : # define DEBUGOUT_CONT_2(t,a,b) do { if (debug_level) \
     170             :                      fprintf (stderr, t, (a), (b)); } while (0)
     171             : # define DEBUGOUT_CONT_3(t,a,b,c) do { if (debug_level) \
     172             :                      fprintf (stderr, t, (a), (b), (c)); } while (0)
     173             : # define DEBUGOUT_LF()        do { if (debug_level) \
     174             :                      putc ('\n', stderr); } while (0)
     175             : 
     176             : #endif /* This source not used by scdaemon. */
     177             : 
     178             : 
     179             : #ifndef EAGAIN
     180             : #define EAGAIN  EWOULDBLOCK
     181             : #endif
     182             : 
     183             : 
     184             : 
     185             : enum {
     186             :   RDR_to_PC_NotifySlotChange= 0x50,
     187             :   RDR_to_PC_HardwareError   = 0x51,
     188             : 
     189             :   PC_to_RDR_SetParameters   = 0x61,
     190             :   PC_to_RDR_IccPowerOn      = 0x62,
     191             :   PC_to_RDR_IccPowerOff     = 0x63,
     192             :   PC_to_RDR_GetSlotStatus   = 0x65,
     193             :   PC_to_RDR_Secure          = 0x69,
     194             :   PC_to_RDR_T0APDU          = 0x6a,
     195             :   PC_to_RDR_Escape          = 0x6b,
     196             :   PC_to_RDR_GetParameters   = 0x6c,
     197             :   PC_to_RDR_ResetParameters = 0x6d,
     198             :   PC_to_RDR_IccClock        = 0x6e,
     199             :   PC_to_RDR_XfrBlock        = 0x6f,
     200             :   PC_to_RDR_Mechanical      = 0x71,
     201             :   PC_to_RDR_Abort           = 0x72,
     202             :   PC_to_RDR_SetDataRate     = 0x73,
     203             : 
     204             :   RDR_to_PC_DataBlock       = 0x80,
     205             :   RDR_to_PC_SlotStatus      = 0x81,
     206             :   RDR_to_PC_Parameters      = 0x82,
     207             :   RDR_to_PC_Escape          = 0x83,
     208             :   RDR_to_PC_DataRate        = 0x84
     209             : };
     210             : 
     211             : 
     212             : /* Two macro to detect whether a CCID command has failed and to get
     213             :    the error code.  These macros assume that we can access the
     214             :    mandatory first 10 bytes of a CCID message in BUF. */
     215             : #define CCID_COMMAND_FAILED(buf) ((buf)[7] & 0x40)
     216             : #define CCID_ERROR_CODE(buf)     (((unsigned char *)(buf))[8])
     217             : 
     218             : 
     219             : /* A list and a table with special transport descriptions. */
     220             : enum {
     221             :   TRANSPORT_USB    = 0, /* Standard USB transport. */
     222             :   TRANSPORT_CM4040 = 1  /* As used by the Cardman 4040. */
     223             : };
     224             : 
     225             : static struct
     226             : {
     227             :   char *name;  /* Device name. */
     228             :   int  type;
     229             : 
     230             : } transports[] = {
     231             :   { "/dev/cmx0", TRANSPORT_CM4040 },
     232             :   { "/dev/cmx1", TRANSPORT_CM4040 },
     233             :   { NULL },
     234             : };
     235             : 
     236             : 
     237             : /* Store information on the driver's state.  A pointer to such a
     238             :    structure is used as handle for most functions. */
     239             : struct ccid_driver_s
     240             : {
     241             :   libusb_device_handle *idev;
     242             :   char *rid;
     243             :   int dev_fd;  /* -1 for USB transport or file descriptor of the
     244             :                    transport device. */
     245             :   unsigned short id_vendor;
     246             :   unsigned short id_product;
     247             :   unsigned short bcd_device;
     248             :   int ifc_no;
     249             :   int ep_bulk_out;
     250             :   int ep_bulk_in;
     251             :   int ep_intr;
     252             :   int seqno;
     253             :   unsigned char t1_ns;
     254             :   unsigned char t1_nr;
     255             :   unsigned char nonnull_nad;
     256             :   int max_ifsd;
     257             :   int max_ccid_msglen;
     258             :   int ifsc;
     259             :   unsigned char apdu_level:2;     /* Reader supports short APDU level
     260             :                                      exchange.  With a value of 2 short
     261             :                                      and extended level is supported.*/
     262             :   unsigned int auto_voltage:1;
     263             :   unsigned int auto_param:1;
     264             :   unsigned int auto_pps:1;
     265             :   unsigned int auto_ifsd:1;
     266             :   unsigned int powered_off:1;
     267             :   unsigned int has_pinpad:2;
     268             :   unsigned int enodev_seen:1;
     269             : 
     270             :   time_t last_progress; /* Last time we sent progress line.  */
     271             : 
     272             :   /* The progress callback and its first arg as supplied to
     273             :      ccid_set_progress_cb.  */
     274             :   void (*progress_cb)(void *, const char *, int, int, int);
     275             :   void *progress_cb_arg;
     276             : };
     277             : 
     278             : 
     279             : static int initialized_usb; /* Tracks whether USB has been initialized. */
     280             : static int debug_level;     /* Flag to control the debug output.
     281             :                                0 = No debugging
     282             :                                1 = USB I/O info
     283             :                                2 = Level 1 + T=1 protocol tracing
     284             :                                3 = Level 2 + USB/I/O tracing of SlotStatus.
     285             :                               */
     286             : 
     287             : 
     288             : static unsigned int compute_edc (const unsigned char *data, size_t datalen,
     289             :                                  int use_crc);
     290             : static int bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen,
     291             :                      int no_debug);
     292             : static int bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
     293             :                     size_t *nread, int expected_type, int seqno, int timeout,
     294             :                     int no_debug);
     295             : static int abort_cmd (ccid_driver_t handle, int seqno);
     296             : static int send_escape_cmd (ccid_driver_t handle, const unsigned char *data,
     297             :                             size_t datalen, unsigned char *result,
     298             :                             size_t resultmax, size_t *resultlen);
     299             : 
     300             : /* Convert a little endian stored 4 byte value into an unsigned
     301             :    integer. */
     302             : static unsigned int
     303           0 : convert_le_u32 (const unsigned char *buf)
     304             : {
     305           0 :   return buf[0] | (buf[1] << 8) | (buf[2] << 16) | ((unsigned int)buf[3] << 24);
     306             : }
     307             : 
     308             : 
     309             : /* Convert a little endian stored 2 byte value into an unsigned
     310             :    integer. */
     311             : static unsigned int
     312           0 : convert_le_u16 (const unsigned char *buf)
     313             : {
     314           0 :   return buf[0] | (buf[1] << 8);
     315             : }
     316             : 
     317             : static void
     318           0 : set_msg_len (unsigned char *msg, unsigned int length)
     319             : {
     320           0 :   msg[1] = length;
     321           0 :   msg[2] = length >> 8;
     322           0 :   msg[3] = length >> 16;
     323           0 :   msg[4] = length >> 24;
     324           0 : }
     325             : 
     326             : 
     327             : static void
     328           0 : my_sleep (int seconds)
     329             : {
     330             : #ifdef USE_NPTH
     331           0 :   npth_sleep (seconds);
     332             : #else
     333             : # ifdef HAVE_W32_SYSTEM
     334             :   Sleep (seconds*1000);
     335             : # else
     336             :   sleep (seconds);
     337             : # endif
     338             : #endif
     339           0 : }
     340             : 
     341             : static void
     342           0 : print_progress (ccid_driver_t handle)
     343             : {
     344           0 :   time_t ct = time (NULL);
     345             : 
     346             :   /* We don't want to print progress lines too often. */
     347           0 :   if (ct == handle->last_progress)
     348           0 :     return;
     349             : 
     350           0 :   if (handle->progress_cb)
     351           0 :     handle->progress_cb (handle->progress_cb_arg, "card_busy", 'w', 0, 0);
     352             : 
     353           0 :   handle->last_progress = ct;
     354             : }
     355             : 
     356             : 
     357             : 
     358             : /* Pint an error message for a failed CCID command including a textual
     359             :    error code.  MSG shall be the CCID message at a minimum of 10 bytes. */
     360             : static void
     361           0 : print_command_failed (const unsigned char *msg)
     362             : {
     363             :   const char *t;
     364             :   char buffer[100];
     365             :   int ec;
     366             : 
     367           0 :   if (!debug_level)
     368           0 :     return;
     369             : 
     370           0 :   ec = CCID_ERROR_CODE (msg);
     371           0 :   switch (ec)
     372             :     {
     373           0 :     case 0x00: t = "Command not supported"; break;
     374             : 
     375           0 :     case 0xE0: t = "Slot busy"; break;
     376           0 :     case 0xEF: t = "PIN cancelled"; break;
     377           0 :     case 0xF0: t = "PIN timeout"; break;
     378             : 
     379           0 :     case 0xF2: t = "Automatic sequence ongoing"; break;
     380           0 :     case 0xF3: t = "Deactivated Protocol"; break;
     381           0 :     case 0xF4: t = "Procedure byte conflict"; break;
     382           0 :     case 0xF5: t = "ICC class not supported"; break;
     383           0 :     case 0xF6: t = "ICC protocol not supported"; break;
     384           0 :     case 0xF7: t = "Bad checksum in ATR"; break;
     385           0 :     case 0xF8: t = "Bad TS in ATR"; break;
     386             : 
     387           0 :     case 0xFB: t = "An all inclusive hardware error occurred"; break;
     388           0 :     case 0xFC: t = "Overrun error while talking to the ICC"; break;
     389           0 :     case 0xFD: t = "Parity error while talking to the ICC"; break;
     390           0 :     case 0xFE: t = "CCID timed out while talking to the ICC"; break;
     391           0 :     case 0xFF: t = "Host aborted the current activity"; break;
     392             : 
     393             :     default:
     394           0 :       if (ec > 0 && ec < 128)
     395           0 :         sprintf (buffer, "Parameter error at offset %d", ec);
     396             :       else
     397           0 :         sprintf (buffer, "Error code %02X", ec);
     398           0 :       t = buffer;
     399           0 :       break;
     400             :     }
     401           0 :   DEBUGOUT_1 ("CCID command failed: %s\n", t);
     402             : }
     403             : 
     404             : 
     405             : static void
     406           0 : print_pr_data (const unsigned char *data, size_t datalen, size_t off)
     407             : {
     408           0 :   int any = 0;
     409             : 
     410           0 :   for (; off < datalen; off++)
     411             :     {
     412           0 :       if (!any || !(off % 16))
     413             :         {
     414           0 :           if (any)
     415           0 :             DEBUGOUT_LF ();
     416           0 :           DEBUGOUT_1 ("  [%04lu] ", (unsigned long) off);
     417             :         }
     418           0 :       DEBUGOUT_CONT_1 (" %02X", data[off]);
     419           0 :       any = 1;
     420             :     }
     421           0 :   if (any && (off % 16))
     422           0 :     DEBUGOUT_LF ();
     423           0 : }
     424             : 
     425             : 
     426             : static void
     427           0 : print_p2r_header (const char *name, const unsigned char *msg, size_t msglen)
     428             : {
     429           0 :   DEBUGOUT_1 ("%s:\n", name);
     430           0 :   if (msglen < 7)
     431           0 :     return;
     432           0 :   DEBUGOUT_1 ("  dwLength ..........: %u\n", convert_le_u32 (msg+1));
     433           0 :   DEBUGOUT_1 ("  bSlot .............: %u\n", msg[5]);
     434           0 :   DEBUGOUT_1 ("  bSeq ..............: %u\n", msg[6]);
     435             : }
     436             : 
     437             : 
     438             : static void
     439           0 : print_p2r_iccpoweron (const unsigned char *msg, size_t msglen)
     440             : {
     441           0 :   print_p2r_header ("PC_to_RDR_IccPowerOn", msg, msglen);
     442           0 :   if (msglen < 10)
     443           0 :     return;
     444           0 :   DEBUGOUT_2 ("  bPowerSelect ......: 0x%02x (%s)\n", msg[7],
     445             :               msg[7] == 0? "auto":
     446             :               msg[7] == 1? "5.0 V":
     447             :               msg[7] == 2? "3.0 V":
     448             :               msg[7] == 3? "1.8 V":"");
     449           0 :   print_pr_data (msg, msglen, 8);
     450             : }
     451             : 
     452             : 
     453             : static void
     454           0 : print_p2r_iccpoweroff (const unsigned char *msg, size_t msglen)
     455             : {
     456           0 :   print_p2r_header ("PC_to_RDR_IccPowerOff", msg, msglen);
     457           0 :   print_pr_data (msg, msglen, 7);
     458           0 : }
     459             : 
     460             : 
     461             : static void
     462           0 : print_p2r_getslotstatus (const unsigned char *msg, size_t msglen)
     463             : {
     464           0 :   print_p2r_header ("PC_to_RDR_GetSlotStatus", msg, msglen);
     465           0 :   print_pr_data (msg, msglen, 7);
     466           0 : }
     467             : 
     468             : 
     469             : static void
     470           0 : print_p2r_xfrblock (const unsigned char *msg, size_t msglen)
     471             : {
     472             :   unsigned int val;
     473             : 
     474           0 :   print_p2r_header ("PC_to_RDR_XfrBlock", msg, msglen);
     475           0 :   if (msglen < 10)
     476           0 :     return;
     477           0 :   DEBUGOUT_1 ("  bBWI ..............: 0x%02x\n", msg[7]);
     478           0 :   val = convert_le_u16 (msg+8);
     479           0 :   DEBUGOUT_2 ("  wLevelParameter ...: 0x%04x%s\n", val,
     480             :               val == 1? " (continued)":
     481             :               val == 2? " (continues+ends)":
     482             :               val == 3? " (continues+continued)":
     483             :               val == 16? " (DataBlock-expected)":"");
     484           0 :   print_pr_data (msg, msglen, 10);
     485             : }
     486             : 
     487             : 
     488             : static void
     489           0 : print_p2r_getparameters (const unsigned char *msg, size_t msglen)
     490             : {
     491           0 :   print_p2r_header ("PC_to_RDR_GetParameters", msg, msglen);
     492           0 :   print_pr_data (msg, msglen, 7);
     493           0 : }
     494             : 
     495             : 
     496             : static void
     497           0 : print_p2r_resetparameters (const unsigned char *msg, size_t msglen)
     498             : {
     499           0 :   print_p2r_header ("PC_to_RDR_ResetParameters", msg, msglen);
     500           0 :   print_pr_data (msg, msglen, 7);
     501           0 : }
     502             : 
     503             : 
     504             : static void
     505           0 : print_p2r_setparameters (const unsigned char *msg, size_t msglen)
     506             : {
     507           0 :   print_p2r_header ("PC_to_RDR_SetParameters", msg, msglen);
     508           0 :   if (msglen < 10)
     509           0 :     return;
     510           0 :   DEBUGOUT_1 ("  bProtocolNum ......: 0x%02x\n", msg[7]);
     511           0 :   print_pr_data (msg, msglen, 8);
     512             : }
     513             : 
     514             : 
     515             : static void
     516           0 : print_p2r_escape (const unsigned char *msg, size_t msglen)
     517             : {
     518           0 :   print_p2r_header ("PC_to_RDR_Escape", msg, msglen);
     519           0 :   print_pr_data (msg, msglen, 7);
     520           0 : }
     521             : 
     522             : 
     523             : static void
     524           0 : print_p2r_iccclock (const unsigned char *msg, size_t msglen)
     525             : {
     526           0 :   print_p2r_header ("PC_to_RDR_IccClock", msg, msglen);
     527           0 :   if (msglen < 10)
     528           0 :     return;
     529           0 :   DEBUGOUT_1 ("  bClockCommand .....: 0x%02x\n", msg[7]);
     530           0 :   print_pr_data (msg, msglen, 8);
     531             : }
     532             : 
     533             : 
     534             : static void
     535           0 : print_p2r_to0apdu (const unsigned char *msg, size_t msglen)
     536             : {
     537           0 :   print_p2r_header ("PC_to_RDR_T0APDU", msg, msglen);
     538           0 :   if (msglen < 10)
     539           0 :     return;
     540           0 :   DEBUGOUT_1 ("  bmChanges .........: 0x%02x\n", msg[7]);
     541           0 :   DEBUGOUT_1 ("  bClassGetResponse .: 0x%02x\n", msg[8]);
     542           0 :   DEBUGOUT_1 ("  bClassEnvelope ....: 0x%02x\n", msg[9]);
     543           0 :   print_pr_data (msg, msglen, 10);
     544             : }
     545             : 
     546             : 
     547             : static void
     548           0 : print_p2r_secure (const unsigned char *msg, size_t msglen)
     549             : {
     550             :   unsigned int val;
     551             : 
     552           0 :   print_p2r_header ("PC_to_RDR_Secure", msg, msglen);
     553           0 :   if (msglen < 10)
     554           0 :     return;
     555           0 :   DEBUGOUT_1 ("  bBMI ..............: 0x%02x\n", msg[7]);
     556           0 :   val = convert_le_u16 (msg+8);
     557           0 :   DEBUGOUT_2 ("  wLevelParameter ...: 0x%04x%s\n", val,
     558             :               val == 1? " (continued)":
     559             :               val == 2? " (continues+ends)":
     560             :               val == 3? " (continues+continued)":
     561             :               val == 16? " (DataBlock-expected)":"");
     562           0 :   print_pr_data (msg, msglen, 10);
     563             : }
     564             : 
     565             : 
     566             : static void
     567           0 : print_p2r_mechanical (const unsigned char *msg, size_t msglen)
     568             : {
     569           0 :   print_p2r_header ("PC_to_RDR_Mechanical", msg, msglen);
     570           0 :   if (msglen < 10)
     571           0 :     return;
     572           0 :   DEBUGOUT_1 ("  bFunction .........: 0x%02x\n", msg[7]);
     573           0 :   print_pr_data (msg, msglen, 8);
     574             : }
     575             : 
     576             : 
     577             : static void
     578           0 : print_p2r_abort (const unsigned char *msg, size_t msglen)
     579             : {
     580           0 :   print_p2r_header ("PC_to_RDR_Abort", msg, msglen);
     581           0 :   print_pr_data (msg, msglen, 7);
     582           0 : }
     583             : 
     584             : 
     585             : static void
     586           0 : print_p2r_setdatarate (const unsigned char *msg, size_t msglen)
     587             : {
     588           0 :   print_p2r_header ("PC_to_RDR_SetDataRate", msg, msglen);
     589           0 :   if (msglen < 10)
     590           0 :     return;
     591           0 :   print_pr_data (msg, msglen, 7);
     592             : }
     593             : 
     594             : 
     595             : static void
     596           0 : print_p2r_unknown (const unsigned char *msg, size_t msglen)
     597             : {
     598           0 :   print_p2r_header ("Unknown PC_to_RDR command", msg, msglen);
     599           0 :   if (msglen < 10)
     600           0 :     return;
     601           0 :   print_pr_data (msg, msglen, 0);
     602             : }
     603             : 
     604             : 
     605             : static void
     606           0 : print_r2p_header (const char *name, const unsigned char *msg, size_t msglen)
     607             : {
     608           0 :   DEBUGOUT_1 ("%s:\n", name);
     609           0 :   if (msglen < 9)
     610           0 :     return;
     611           0 :   DEBUGOUT_1 ("  dwLength ..........: %u\n", convert_le_u32 (msg+1));
     612           0 :   DEBUGOUT_1 ("  bSlot .............: %u\n", msg[5]);
     613           0 :   DEBUGOUT_1 ("  bSeq ..............: %u\n", msg[6]);
     614           0 :   DEBUGOUT_1 ("  bStatus ...........: %u\n", msg[7]);
     615           0 :   if (msg[8])
     616           0 :     DEBUGOUT_1 ("  bError ............: %u\n", msg[8]);
     617             : }
     618             : 
     619             : 
     620             : static void
     621           0 : print_r2p_datablock (const unsigned char *msg, size_t msglen)
     622             : {
     623           0 :   print_r2p_header ("RDR_to_PC_DataBlock", msg, msglen);
     624           0 :   if (msglen < 10)
     625           0 :     return;
     626           0 :   if (msg[9])
     627           0 :     DEBUGOUT_2 ("  bChainParameter ...: 0x%02x%s\n", msg[9],
     628             :                 msg[9] == 1? " (continued)":
     629             :                 msg[9] == 2? " (continues+ends)":
     630             :                 msg[9] == 3? " (continues+continued)":
     631             :                 msg[9] == 16? " (XferBlock-expected)":"");
     632           0 :   print_pr_data (msg, msglen, 10);
     633             : }
     634             : 
     635             : 
     636             : static void
     637           0 : print_r2p_slotstatus (const unsigned char *msg, size_t msglen)
     638             : {
     639           0 :   print_r2p_header ("RDR_to_PC_SlotStatus", msg, msglen);
     640           0 :   if (msglen < 10)
     641           0 :     return;
     642           0 :   DEBUGOUT_2 ("  bClockStatus ......: 0x%02x%s\n", msg[9],
     643             :               msg[9] == 0? " (running)":
     644             :               msg[9] == 1? " (stopped-L)":
     645             :               msg[9] == 2? " (stopped-H)":
     646             :               msg[9] == 3? " (stopped)":"");
     647           0 :   print_pr_data (msg, msglen, 10);
     648             : }
     649             : 
     650             : 
     651             : static void
     652           0 : print_r2p_parameters (const unsigned char *msg, size_t msglen)
     653             : {
     654           0 :   print_r2p_header ("RDR_to_PC_Parameters", msg, msglen);
     655           0 :   if (msglen < 10)
     656           0 :     return;
     657             : 
     658           0 :   DEBUGOUT_1 ("  protocol ..........: T=%d\n", msg[9]);
     659           0 :   if (msglen == 17 && msg[9] == 1)
     660             :     {
     661             :       /* Protocol T=1.  */
     662           0 :       DEBUGOUT_1 ("  bmFindexDindex ....: %02X\n", msg[10]);
     663           0 :       DEBUGOUT_1 ("  bmTCCKST1 .........: %02X\n", msg[11]);
     664           0 :       DEBUGOUT_1 ("  bGuardTimeT1 ......: %02X\n", msg[12]);
     665           0 :       DEBUGOUT_1 ("  bmWaitingIntegersT1: %02X\n", msg[13]);
     666           0 :       DEBUGOUT_1 ("  bClockStop ........: %02X\n", msg[14]);
     667           0 :       DEBUGOUT_1 ("  bIFSC .............: %d\n", msg[15]);
     668           0 :       DEBUGOUT_1 ("  bNadValue .........: %d\n", msg[16]);
     669             :     }
     670             :   else
     671           0 :     print_pr_data (msg, msglen, 10);
     672             : }
     673             : 
     674             : 
     675             : static void
     676           0 : print_r2p_escape (const unsigned char *msg, size_t msglen)
     677             : {
     678           0 :   print_r2p_header ("RDR_to_PC_Escape", msg, msglen);
     679           0 :   if (msglen < 10)
     680           0 :     return;
     681           0 :   DEBUGOUT_1 ("  buffer[9] .........: %02X\n", msg[9]);
     682           0 :   print_pr_data (msg, msglen, 10);
     683             : }
     684             : 
     685             : 
     686             : static void
     687           0 : print_r2p_datarate (const unsigned char *msg, size_t msglen)
     688             : {
     689           0 :   print_r2p_header ("RDR_to_PC_DataRate", msg, msglen);
     690           0 :   if (msglen < 10)
     691           0 :     return;
     692           0 :   if (msglen >= 18)
     693             :     {
     694           0 :       DEBUGOUT_1 ("  dwClockFrequency ..: %u\n", convert_le_u32 (msg+10));
     695           0 :       DEBUGOUT_1 ("  dwDataRate ..... ..: %u\n", convert_le_u32 (msg+14));
     696           0 :       print_pr_data (msg, msglen, 18);
     697             :     }
     698             :   else
     699           0 :     print_pr_data (msg, msglen, 10);
     700             : }
     701             : 
     702             : 
     703             : static void
     704           0 : print_r2p_unknown (const unsigned char *msg, size_t msglen)
     705             : {
     706           0 :   print_r2p_header ("Unknown RDR_to_PC command", msg, msglen);
     707           0 :   if (msglen < 10)
     708           0 :     return;
     709           0 :   DEBUGOUT_1 ("  bMessageType ......: %02X\n", msg[0]);
     710           0 :   DEBUGOUT_1 ("  buffer[9] .........: %02X\n", msg[9]);
     711           0 :   print_pr_data (msg, msglen, 10);
     712             : }
     713             : 
     714             : 
     715             : /* Given a handle used for special transport prepare it for use.  In
     716             :    particular setup all information in way that resembles what
     717             :    parse_cccid_descriptor does. */
     718             : static void
     719           0 : prepare_special_transport (ccid_driver_t handle)
     720             : {
     721           0 :   assert (!handle->id_vendor);
     722             : 
     723           0 :   handle->nonnull_nad = 0;
     724           0 :   handle->auto_ifsd = 0;
     725           0 :   handle->max_ifsd = 32;
     726           0 :   handle->max_ccid_msglen = CCID_MAX_BUF;
     727           0 :   handle->has_pinpad = 0;
     728           0 :   handle->apdu_level = 0;
     729           0 :   switch (handle->id_product)
     730             :     {
     731             :     case TRANSPORT_CM4040:
     732           0 :       DEBUGOUT ("setting up transport for CardMan 4040\n");
     733           0 :       handle->apdu_level = 1;
     734           0 :       break;
     735             : 
     736           0 :     default: assert (!"transport not defined");
     737             :     }
     738           0 : }
     739             : 
     740             : /* Parse a CCID descriptor, optionally print all available features
     741             :    and test whether this reader is usable by this driver.  Returns 0
     742             :    if it is usable.
     743             : 
     744             :    Note, that this code is based on the one in lsusb.c of the
     745             :    usb-utils package, I wrote on 2003-09-01. -wk. */
     746             : static int
     747           0 : parse_ccid_descriptor (ccid_driver_t handle,
     748             :                        const unsigned char *buf, size_t buflen)
     749             : {
     750             :   unsigned int i;
     751             :   unsigned int us;
     752           0 :   int have_t1 = 0, have_tpdu=0;
     753             : 
     754             : 
     755           0 :   handle->nonnull_nad = 0;
     756           0 :   handle->auto_ifsd = 0;
     757           0 :   handle->max_ifsd = 32;
     758           0 :   handle->has_pinpad = 0;
     759           0 :   handle->apdu_level = 0;
     760           0 :   handle->auto_voltage = 0;
     761           0 :   handle->auto_param = 0;
     762           0 :   handle->auto_pps = 0;
     763           0 :   DEBUGOUT_3 ("idVendor: %04X  idProduct: %04X  bcdDevice: %04X\n",
     764             :               handle->id_vendor, handle->id_product, handle->bcd_device);
     765           0 :   if (buflen < 54 || buf[0] < 54)
     766             :     {
     767           0 :       DEBUGOUT ("CCID device descriptor is too short\n");
     768           0 :       return -1;
     769             :     }
     770             : 
     771           0 :   DEBUGOUT   ("ChipCard Interface Descriptor:\n");
     772           0 :   DEBUGOUT_1 ("  bLength             %5u\n", buf[0]);
     773           0 :   DEBUGOUT_1 ("  bDescriptorType     %5u\n", buf[1]);
     774           0 :   DEBUGOUT_2 ("  bcdCCID             %2x.%02x", buf[3], buf[2]);
     775           0 :     if (buf[3] != 1 || buf[2] != 0)
     776           0 :       DEBUGOUT_CONT("  (Warning: Only accurate for version 1.0)");
     777           0 :   DEBUGOUT_LF ();
     778             : 
     779           0 :   DEBUGOUT_1 ("  nMaxSlotIndex       %5u\n", buf[4]);
     780           0 :   DEBUGOUT_2 ("  bVoltageSupport     %5u  %s\n",
     781             :               buf[5], (buf[5] == 1? "5.0V" : buf[5] == 2? "3.0V"
     782             :                        : buf[5] == 3? "1.8V":"?"));
     783             : 
     784           0 :   us = convert_le_u32 (buf+6);
     785           0 :   DEBUGOUT_1 ("  dwProtocols         %5u ", us);
     786           0 :   if ((us & 1))
     787           0 :     DEBUGOUT_CONT (" T=0");
     788           0 :   if ((us & 2))
     789             :     {
     790           0 :       DEBUGOUT_CONT (" T=1");
     791           0 :       have_t1 = 1;
     792             :     }
     793           0 :   if ((us & ~3))
     794           0 :     DEBUGOUT_CONT (" (Invalid values detected)");
     795           0 :   DEBUGOUT_LF ();
     796             : 
     797           0 :   us = convert_le_u32(buf+10);
     798           0 :   DEBUGOUT_1 ("  dwDefaultClock      %5u\n", us);
     799           0 :   us = convert_le_u32(buf+14);
     800           0 :   DEBUGOUT_1 ("  dwMaxiumumClock     %5u\n", us);
     801           0 :   DEBUGOUT_1 ("  bNumClockSupported  %5u\n", buf[18]);
     802           0 :   us = convert_le_u32(buf+19);
     803           0 :   DEBUGOUT_1 ("  dwDataRate        %7u bps\n", us);
     804           0 :   us = convert_le_u32(buf+23);
     805           0 :   DEBUGOUT_1 ("  dwMaxDataRate     %7u bps\n", us);
     806           0 :   DEBUGOUT_1 ("  bNumDataRatesSupp.  %5u\n", buf[27]);
     807             : 
     808           0 :   us = convert_le_u32(buf+28);
     809           0 :   DEBUGOUT_1 ("  dwMaxIFSD           %5u\n", us);
     810           0 :   handle->max_ifsd = us;
     811             : 
     812           0 :   us = convert_le_u32(buf+32);
     813           0 :   DEBUGOUT_1 ("  dwSyncProtocols  %08X ", us);
     814           0 :   if ((us&1))
     815           0 :     DEBUGOUT_CONT ( " 2-wire");
     816           0 :   if ((us&2))
     817           0 :     DEBUGOUT_CONT ( " 3-wire");
     818           0 :   if ((us&4))
     819           0 :     DEBUGOUT_CONT ( " I2C");
     820           0 :   DEBUGOUT_LF ();
     821             : 
     822           0 :   us = convert_le_u32(buf+36);
     823           0 :   DEBUGOUT_1 ("  dwMechanical     %08X ", us);
     824           0 :   if ((us & 1))
     825           0 :     DEBUGOUT_CONT (" accept");
     826           0 :   if ((us & 2))
     827           0 :     DEBUGOUT_CONT (" eject");
     828           0 :   if ((us & 4))
     829           0 :     DEBUGOUT_CONT (" capture");
     830           0 :   if ((us & 8))
     831           0 :     DEBUGOUT_CONT (" lock");
     832           0 :   DEBUGOUT_LF ();
     833             : 
     834           0 :   us = convert_le_u32(buf+40);
     835           0 :   DEBUGOUT_1 ("  dwFeatures       %08X\n", us);
     836           0 :   if ((us & 0x0002))
     837             :     {
     838           0 :       DEBUGOUT ("    Auto configuration based on ATR (assumes auto voltage)\n");
     839           0 :       handle->auto_voltage = 1;
     840             :     }
     841           0 :   if ((us & 0x0004))
     842           0 :     DEBUGOUT ("    Auto activation on insert\n");
     843           0 :   if ((us & 0x0008))
     844             :     {
     845           0 :       DEBUGOUT ("    Auto voltage selection\n");
     846           0 :       handle->auto_voltage = 1;
     847             :     }
     848           0 :   if ((us & 0x0010))
     849           0 :     DEBUGOUT ("    Auto clock change\n");
     850           0 :   if ((us & 0x0020))
     851           0 :     DEBUGOUT ("    Auto baud rate change\n");
     852           0 :   if ((us & 0x0040))
     853             :     {
     854           0 :       DEBUGOUT ("    Auto parameter negotiation made by CCID\n");
     855           0 :       handle->auto_param = 1;
     856             :     }
     857           0 :   else if ((us & 0x0080))
     858             :     {
     859           0 :       DEBUGOUT ("    Auto PPS made by CCID\n");
     860           0 :       handle->auto_pps = 1;
     861             :     }
     862           0 :   if ((us & (0x0040 | 0x0080)) == (0x0040 | 0x0080))
     863           0 :     DEBUGOUT ("    WARNING: conflicting negotiation features\n");
     864             : 
     865           0 :   if ((us & 0x0100))
     866           0 :     DEBUGOUT ("    CCID can set ICC in clock stop mode\n");
     867           0 :   if ((us & 0x0200))
     868             :     {
     869           0 :       DEBUGOUT ("    NAD value other than 0x00 accepted\n");
     870           0 :       handle->nonnull_nad = 1;
     871             :     }
     872           0 :   if ((us & 0x0400))
     873             :     {
     874           0 :       DEBUGOUT ("    Auto IFSD exchange\n");
     875           0 :       handle->auto_ifsd = 1;
     876             :     }
     877             : 
     878           0 :   if ((us & 0x00010000))
     879             :     {
     880           0 :       DEBUGOUT ("    TPDU level exchange\n");
     881           0 :       have_tpdu = 1;
     882             :     }
     883           0 :   else if ((us & 0x00020000))
     884             :     {
     885           0 :       DEBUGOUT ("    Short APDU level exchange\n");
     886           0 :       handle->apdu_level = 1;
     887             :     }
     888           0 :   else if ((us & 0x00040000))
     889             :     {
     890           0 :       DEBUGOUT ("    Short and extended APDU level exchange\n");
     891           0 :       handle->apdu_level = 2;
     892             :     }
     893           0 :   else if ((us & 0x00070000))
     894           0 :     DEBUGOUT ("    WARNING: conflicting exchange levels\n");
     895             : 
     896           0 :   us = convert_le_u32(buf+44);
     897           0 :   DEBUGOUT_1 ("  dwMaxCCIDMsgLen     %5u\n", us);
     898           0 :   handle->max_ccid_msglen = us;
     899             : 
     900           0 :   DEBUGOUT (  "  bClassGetResponse    ");
     901           0 :   if (buf[48] == 0xff)
     902           0 :     DEBUGOUT_CONT ("echo\n");
     903             :   else
     904           0 :     DEBUGOUT_CONT_1 ("  %02X\n", buf[48]);
     905             : 
     906           0 :   DEBUGOUT (  "  bClassEnvelope       ");
     907           0 :   if (buf[49] == 0xff)
     908           0 :     DEBUGOUT_CONT ("echo\n");
     909             :   else
     910           0 :     DEBUGOUT_CONT_1 ("  %02X\n", buf[48]);
     911             : 
     912           0 :   DEBUGOUT (  "  wlcdLayout           ");
     913           0 :   if (!buf[50] && !buf[51])
     914           0 :     DEBUGOUT_CONT ("none\n");
     915             :   else
     916           0 :     DEBUGOUT_CONT_2 ("%u cols %u lines\n", buf[50], buf[51]);
     917             : 
     918           0 :   DEBUGOUT_1 ("  bPINSupport         %5u ", buf[52]);
     919           0 :   if ((buf[52] & 1))
     920             :     {
     921           0 :       DEBUGOUT_CONT ( " verification");
     922           0 :       handle->has_pinpad |= 1;
     923             :     }
     924           0 :   if ((buf[52] & 2))
     925             :     {
     926           0 :       DEBUGOUT_CONT ( " modification");
     927           0 :       handle->has_pinpad |= 2;
     928             :     }
     929           0 :   DEBUGOUT_LF ();
     930             : 
     931           0 :   DEBUGOUT_1 ("  bMaxCCIDBusySlots   %5u\n", buf[53]);
     932             : 
     933           0 :   if (buf[0] > 54)
     934             :     {
     935           0 :       DEBUGOUT ("  junk             ");
     936           0 :       for (i=54; i < buf[0]-54; i++)
     937           0 :         DEBUGOUT_CONT_1 (" %02X", buf[i]);
     938           0 :       DEBUGOUT_LF ();
     939             :     }
     940             : 
     941           0 :   if (!have_t1 || !(have_tpdu  || handle->apdu_level))
     942             :     {
     943           0 :       DEBUGOUT ("this drivers requires that the reader supports T=1, "
     944             :                 "TPDU or APDU level exchange - this is not available\n");
     945           0 :       return -1;
     946             :     }
     947             : 
     948             : 
     949             :   /* SCM drivers get stuck in their internal USB stack if they try to
     950             :      send a frame of n*wMaxPacketSize back to us.  Given that
     951             :      wMaxPacketSize is 64 for these readers we set the IFSD to a value
     952             :      lower than that:
     953             :         64 - 10 CCID header -  4 T1frame - 2 reserved = 48
     954             :      Product Ids:
     955             :          0xe001 - SCR 331
     956             :          0x5111 - SCR 331-DI
     957             :          0x5115 - SCR 335
     958             :          0xe003 - SPR 532
     959             :      The
     960             :          0x5117 - SCR 3320 USB ID-000 reader
     961             :      seems to be very slow but enabling this workaround boosts the
     962             :      performance to a a more or less acceptable level (tested by David).
     963             : 
     964             :   */
     965           0 :   if (handle->id_vendor == VENDOR_SCM
     966           0 :       && handle->max_ifsd > 48
     967           0 :       && (  (handle->id_product == SCM_SCR331   && handle->bcd_device < 0x0516)
     968           0 :           ||(handle->id_product == SCM_SCR331DI && handle->bcd_device < 0x0620)
     969           0 :           ||(handle->id_product == SCM_SCR335   && handle->bcd_device < 0x0514)
     970           0 :           ||(handle->id_product == SCM_SPR532   && handle->bcd_device < 0x0504)
     971           0 :           ||(handle->id_product == SCM_SCR3320  && handle->bcd_device < 0x0522)
     972             :           ))
     973             :     {
     974           0 :       DEBUGOUT ("enabling workaround for buggy SCM readers\n");
     975           0 :       handle->max_ifsd = 48;
     976             :     }
     977             : 
     978           0 :   if (handle->id_vendor == VENDOR_GEMPC)
     979             :     {
     980           0 :       DEBUGOUT ("enabling product quirk: disable non-null NAD\n");
     981           0 :       handle->nonnull_nad = 0;
     982             :     }
     983             : 
     984           0 :   return 0;
     985             : }
     986             : 
     987             : 
     988             : static char *
     989           0 : get_escaped_usb_string (libusb_device_handle *idev, int idx,
     990             :                         const char *prefix, const char *suffix)
     991             : {
     992             :   int rc;
     993             :   unsigned char buf[280];
     994             :   unsigned char *s;
     995             :   unsigned int langid;
     996             :   size_t i, n, len;
     997             :   char *result;
     998             : 
     999           0 :   if (!idx)
    1000           0 :     return NULL;
    1001             : 
    1002             :   /* Fixme: The next line is for the current Valgrid without support
    1003             :      for USB IOCTLs. */
    1004           0 :   memset (buf, 0, sizeof buf);
    1005             : 
    1006             :   /* First get the list of supported languages and use the first one.
    1007             :      If we do don't find it we try to use English.  Note that this is
    1008             :      all in a 2 bute Unicode encoding using little endian. */
    1009           0 :   rc = libusb_control_transfer (idev, LIBUSB_ENDPOINT_IN,
    1010             :                                 LIBUSB_REQUEST_GET_DESCRIPTOR,
    1011             :                                 (LIBUSB_DT_STRING << 8), 0,
    1012             :                                 (char*)buf, sizeof buf, 1000 /* ms timeout */);
    1013           0 :   if (rc < 4)
    1014           0 :     langid = 0x0409; /* English.  */
    1015             :   else
    1016           0 :     langid = (buf[3] << 8) | buf[2];
    1017             : 
    1018           0 :   rc = libusb_control_transfer (idev, LIBUSB_ENDPOINT_IN,
    1019             :                                 LIBUSB_REQUEST_GET_DESCRIPTOR,
    1020             :                                 (LIBUSB_DT_STRING << 8) + idx, langid,
    1021             :                                 (char*)buf, sizeof buf, 1000 /* ms timeout */);
    1022           0 :   if (rc < 2 || buf[1] != LIBUSB_DT_STRING)
    1023           0 :     return NULL; /* Error or not a string. */
    1024           0 :   len = buf[0];
    1025           0 :   if (len > rc)
    1026           0 :     return NULL; /* Larger than our buffer. */
    1027             : 
    1028           0 :   for (s=buf+2, i=2, n=0; i+1 < len; i += 2, s += 2)
    1029             :     {
    1030           0 :       if (s[1])
    1031           0 :         n++; /* High byte set. */
    1032           0 :       else if (*s <= 0x20 || *s >= 0x7f || *s == '%' || *s == ':')
    1033           0 :         n += 3 ;
    1034             :       else
    1035           0 :         n++;
    1036             :     }
    1037             : 
    1038           0 :   result = malloc (strlen (prefix) + n + strlen (suffix) + 1);
    1039           0 :   if (!result)
    1040           0 :     return NULL;
    1041             : 
    1042           0 :   strcpy (result, prefix);
    1043           0 :   n = strlen (prefix);
    1044           0 :   for (s=buf+2, i=2; i+1 < len; i += 2, s += 2)
    1045             :     {
    1046           0 :       if (s[1])
    1047           0 :         result[n++] = '\xff'; /* High byte set. */
    1048           0 :       else if (*s <= 0x20 || *s >= 0x7f || *s == '%' || *s == ':')
    1049             :         {
    1050           0 :           sprintf (result+n, "%%%02X", *s);
    1051           0 :           n += 3;
    1052             :         }
    1053             :       else
    1054           0 :         result[n++] = *s;
    1055             :     }
    1056           0 :   strcpy (result+n, suffix);
    1057             : 
    1058           0 :   return result;
    1059             : }
    1060             : 
    1061             : /* This function creates an reader id to be used to find the same
    1062             :    physical reader after a reset.  It returns an allocated and possibly
    1063             :    percent escaped string or NULL if not enough memory is available. */
    1064             : static char *
    1065           0 : make_reader_id (libusb_device_handle *idev,
    1066             :                 unsigned int vendor, unsigned int product,
    1067             :                 unsigned char serialno_index)
    1068             : {
    1069             :   char *rid;
    1070             :   char prefix[20];
    1071             : 
    1072           0 :   sprintf (prefix, "%04X:%04X:", (vendor & 0xffff), (product & 0xffff));
    1073           0 :   rid = get_escaped_usb_string (idev, serialno_index, prefix, ":0");
    1074           0 :   if (!rid)
    1075             :     {
    1076           0 :       rid = malloc (strlen (prefix) + 3 + 1);
    1077           0 :       if (!rid)
    1078           0 :         return NULL;
    1079           0 :       strcpy (rid, prefix);
    1080           0 :       strcat (rid, "X:0");
    1081             :     }
    1082           0 :   return rid;
    1083             : }
    1084             : 
    1085             : 
    1086             : /* Helper to find the endpoint from an interface descriptor.  */
    1087             : static int
    1088           0 : find_endpoint (const struct libusb_interface_descriptor *ifcdesc, int mode)
    1089             : {
    1090             :   int no;
    1091           0 :   int want_bulk_in = 0;
    1092             : 
    1093           0 :   if (mode == 1)
    1094           0 :     want_bulk_in = 0x80;
    1095           0 :   for (no=0; no < ifcdesc->bNumEndpoints; no++)
    1096             :     {
    1097           0 :       const struct libusb_endpoint_descriptor *ep = ifcdesc->endpoint + no;
    1098           0 :       if (ep->bDescriptorType != LIBUSB_DT_ENDPOINT)
    1099             :         ;
    1100           0 :       else if (mode == 2
    1101           0 :                && ((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK)
    1102             :                    == LIBUSB_TRANSFER_TYPE_INTERRUPT)
    1103           0 :                && (ep->bEndpointAddress & 0x80))
    1104           0 :         return ep->bEndpointAddress;
    1105           0 :       else if (((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK)
    1106             :                 == LIBUSB_TRANSFER_TYPE_BULK)
    1107           0 :                && (ep->bEndpointAddress & 0x80) == want_bulk_in)
    1108           0 :         return ep->bEndpointAddress;
    1109             :     }
    1110             : 
    1111           0 :   return -1;
    1112             : }
    1113             : 
    1114             : 
    1115             : /* Helper for scan_or_find_devices. This function returns true if a
    1116             :    requested device has been found or the caller should stop scanning
    1117             :    for other reasons. */
    1118             : static int
    1119           0 : scan_or_find_usb_device (int scan_mode,
    1120             :                          int *readerno, int *count, char **rid_list,
    1121             :                          const char *readerid,
    1122             :                          struct libusb_device *dev,
    1123             :                          char **r_rid,
    1124             :                          struct libusb_device_descriptor *desc,
    1125             :                          libusb_device_handle **r_idev,
    1126             :                          unsigned char **ifcdesc_extra,
    1127             :                          size_t *ifcdesc_extra_len,
    1128             :                          int *interface_number,
    1129             :                          int *ep_bulk_out, int *ep_bulk_in, int *ep_intr)
    1130             : {
    1131             :   int cfg_no;
    1132             :   int ifc_no;
    1133             :   int set_no;
    1134             :   const struct libusb_interface_descriptor *ifcdesc;
    1135             :   char *rid;
    1136             :   libusb_device_handle *idev;
    1137             :   int err;
    1138             : 
    1139           0 :   err = libusb_get_device_descriptor (dev, desc);
    1140           0 :   if (err < 0)
    1141           0 :     return err;
    1142             : 
    1143           0 :   *r_idev = NULL;
    1144             : 
    1145           0 :   for (cfg_no=0; cfg_no < desc->bNumConfigurations; cfg_no++)
    1146             :     {
    1147             :       struct libusb_config_descriptor *config;
    1148             : 
    1149           0 :       err = libusb_get_config_descriptor (dev, cfg_no, &config);
    1150           0 :       if (err < 0)
    1151             :         {
    1152           0 :           if (err == LIBUSB_ERROR_NO_MEM)
    1153           0 :             return err;
    1154           0 :           continue;
    1155             :         }
    1156             : 
    1157           0 :       for (ifc_no=0; ifc_no < config->bNumInterfaces; ifc_no++)
    1158             :         {
    1159           0 :           for (set_no=0; set_no < config->interface[ifc_no].num_altsetting;
    1160           0 :                set_no++)
    1161             :             {
    1162           0 :               ifcdesc = (config->interface[ifc_no].altsetting + set_no);
    1163             :               /* The second condition is for older SCM SPR 532 who did
    1164             :                  not know about the assigned CCID class.  The third
    1165             :                  condition does the same for a Cherry SmartTerminal
    1166             :                  ST-2000.  Instead of trying to interpret the strings
    1167             :                  we simply check the product ID. */
    1168           0 :               if (ifcdesc && ifcdesc->extra
    1169           0 :                   && ((ifcdesc->bInterfaceClass == 11
    1170           0 :                        && ifcdesc->bInterfaceSubClass == 0
    1171           0 :                        && ifcdesc->bInterfaceProtocol == 0)
    1172           0 :                       || (ifcdesc->bInterfaceClass == 255
    1173           0 :                           && desc->idVendor == VENDOR_SCM
    1174           0 :                           && desc->idProduct == SCM_SPR532)
    1175           0 :                       || (ifcdesc->bInterfaceClass == 255
    1176           0 :                           && desc->idVendor == VENDOR_CHERRY
    1177           0 :                           && desc->idProduct == CHERRY_ST2000)))
    1178             :                 {
    1179           0 :                   err = libusb_open (dev, &idev);
    1180           0 :                   if (err < 0)
    1181             :                     {
    1182           0 :                       DEBUGOUT_1 ("usb_open failed: %s\n",
    1183             :                                   libusb_error_name (err));
    1184           0 :                       continue; /* with next setting. */
    1185             :                     }
    1186             : 
    1187           0 :                   rid = make_reader_id (idev,
    1188           0 :                                         desc->idVendor,
    1189           0 :                                         desc->idProduct,
    1190           0 :                                         desc->iSerialNumber);
    1191           0 :                   if (rid)
    1192             :                     {
    1193           0 :                       if (scan_mode)
    1194             :                         {
    1195             :                           char *p;
    1196             : 
    1197             :                           /* We are collecting infos about all
    1198             :                              available CCID readers.  Store them and
    1199             :                              continue. */
    1200           0 :                           DEBUGOUT_2 ("found CCID reader %d (ID=%s)\n",
    1201             :                                       *count, rid );
    1202           0 :                           p = malloc ((*rid_list? strlen (*rid_list):0) + 1
    1203           0 :                                       + strlen (rid) + 1);
    1204           0 :                           if (p)
    1205             :                             {
    1206           0 :                               *p = 0;
    1207           0 :                               if (*rid_list)
    1208             :                                 {
    1209           0 :                                   strcat (p, *rid_list);
    1210           0 :                                   free (*rid_list);
    1211             :                                 }
    1212           0 :                               strcat (p, rid);
    1213           0 :                               strcat (p, "\n");
    1214           0 :                               *rid_list = p;
    1215             :                             }
    1216             :                           else /* Out of memory. */
    1217           0 :                             free (rid);
    1218             : 
    1219           0 :                           rid = NULL;
    1220           0 :                           ++*count;
    1221             :                         }
    1222           0 :                       else if (!*readerno
    1223           0 :                                || (*readerno < 0
    1224           0 :                                    && readerid
    1225           0 :                                    && !strcmp (readerid, rid)))
    1226             :                         {
    1227             :                           /* We found the requested reader. */
    1228           0 :                           if (ifcdesc_extra && ifcdesc_extra_len)
    1229             :                             {
    1230           0 :                               *ifcdesc_extra = malloc (ifcdesc
    1231           0 :                                                        ->extra_length);
    1232           0 :                               if (!*ifcdesc_extra)
    1233             :                                 {
    1234           0 :                                   libusb_close (idev);
    1235           0 :                                   free (rid);
    1236           0 :                                   libusb_free_config_descriptor (config);
    1237           0 :                                   return 1; /* Out of core. */
    1238             :                                 }
    1239           0 :                               memcpy (*ifcdesc_extra, ifcdesc->extra,
    1240           0 :                                       ifcdesc->extra_length);
    1241           0 :                               *ifcdesc_extra_len = ifcdesc->extra_length;
    1242             :                             }
    1243             : 
    1244           0 :                           if (interface_number)
    1245           0 :                             *interface_number = (ifcdesc->bInterfaceNumber);
    1246             : 
    1247           0 :                           if (ep_bulk_out)
    1248           0 :                             *ep_bulk_out = find_endpoint (ifcdesc, 0);
    1249           0 :                           if (ep_bulk_in)
    1250           0 :                             *ep_bulk_in = find_endpoint (ifcdesc, 1);
    1251           0 :                           if (ep_intr)
    1252           0 :                             *ep_intr = find_endpoint (ifcdesc, 2);
    1253             : 
    1254           0 :                           if (r_rid)
    1255             :                             {
    1256           0 :                               *r_rid = rid;
    1257           0 :                               rid = NULL;
    1258             :                             }
    1259             :                           else
    1260           0 :                             free (rid);
    1261             : 
    1262           0 :                           *r_idev = idev;
    1263           0 :                           libusb_free_config_descriptor (config);
    1264           0 :                           return 1; /* Found requested device. */
    1265             :                         }
    1266             :                       else
    1267             :                         {
    1268             :                           /* This is not yet the reader we want.
    1269             :                              fixme: We should avoid the extra usb_open
    1270             :                              in this case. */
    1271           0 :                           if (*readerno >= 0)
    1272           0 :                             --*readerno;
    1273             :                         }
    1274           0 :                       free (rid);
    1275             :                     }
    1276             : 
    1277           0 :                   libusb_close (idev);
    1278           0 :                   idev = NULL;
    1279           0 :                   libusb_free_config_descriptor (config);
    1280           0 :                   return 0;
    1281             :                 }
    1282             :             }
    1283             :         }
    1284             : 
    1285           0 :       libusb_free_config_descriptor (config);
    1286             :     }
    1287             : 
    1288           0 :   return 0;
    1289             : }
    1290             : 
    1291             : /* Combination function to either scan all CCID devices or to find and
    1292             :    open one specific device.
    1293             : 
    1294             :    The function returns 0 if a reader has been found or when a scan
    1295             :    returned without error.
    1296             : 
    1297             :    With READERNO = -1 and READERID is NULL, scan mode is used and
    1298             :    R_RID should be the address where to store the list of reader_ids
    1299             :    we found.  If on return this list is empty, no CCID device has been
    1300             :    found; otherwise it points to an allocated linked list of reader
    1301             :    IDs.  Note that in this mode the function always returns NULL.
    1302             : 
    1303             :    With READERNO >= 0 or READERID is not NULL find mode is used.  This
    1304             :    uses the same algorithm as the scan mode but stops and returns at
    1305             :    the entry number READERNO and return the handle for the the opened
    1306             :    USB device. If R_RID is not NULL it will receive the reader ID of
    1307             :    that device.  If R_DEV is not NULL it will the device pointer of
    1308             :    that device.  If IFCDESC_EXTRA is NOT NULL it will receive a
    1309             :    malloced copy of the interfaces "extra: data filed;
    1310             :    IFCDESC_EXTRA_LEN receive the length of this field.  If there is
    1311             :    no reader with number READERNO or that reader is not usable by our
    1312             :    implementation NULL will be returned.  The caller must close a
    1313             :    returned USB device handle and free (if not passed as NULL) the
    1314             :    returned reader ID info as well as the IFCDESC_EXTRA.  On error
    1315             :    NULL will get stored at R_RID, R_DEV, IFCDESC_EXTRA and
    1316             :    IFCDESC_EXTRA_LEN.  With READERID being -1 the function stops if
    1317             :    the READERID was found.
    1318             : 
    1319             :    If R_FD is not -1 on return the device is not using USB for
    1320             :    transport but the device associated with that file descriptor.  In
    1321             :    this case INTERFACE will receive the transport type and the other
    1322             :    USB specific return values are not used; the return value is
    1323             :    (void*)(1).
    1324             : 
    1325             :    Note that the first entry of the returned reader ID list in scan mode
    1326             :    corresponds with a READERNO of 0 in find mode.
    1327             : */
    1328             : static int
    1329           0 : scan_or_find_devices (int readerno, const char *readerid,
    1330             :                       char **r_rid,
    1331             :                       struct libusb_device_descriptor *r_desc,
    1332             :                       unsigned char **ifcdesc_extra,
    1333             :                       size_t *ifcdesc_extra_len,
    1334             :                       int *interface_number,
    1335             :                       int *ep_bulk_out, int *ep_bulk_in, int *ep_intr,
    1336             :                       libusb_device_handle **r_idev,
    1337             :                       int *r_fd)
    1338             : {
    1339           0 :   char *rid_list = NULL;
    1340           0 :   int count = 0;
    1341           0 :   libusb_device **dev_list = NULL;
    1342             :   libusb_device *dev;
    1343           0 :   libusb_device_handle *idev = NULL;
    1344           0 :   int scan_mode = (readerno == -1 && !readerid);
    1345             :   int i;
    1346             :   ssize_t n;
    1347             :   struct libusb_device_descriptor desc;
    1348             : 
    1349             :   /* Set return values to a default. */
    1350           0 :   if (r_rid)
    1351           0 :     *r_rid = NULL;
    1352           0 :   if (ifcdesc_extra)
    1353           0 :     *ifcdesc_extra = NULL;
    1354           0 :   if (ifcdesc_extra_len)
    1355           0 :     *ifcdesc_extra_len = 0;
    1356           0 :   if (interface_number)
    1357           0 :     *interface_number = 0;
    1358           0 :   if (r_idev)
    1359           0 :     *r_idev = NULL;
    1360           0 :   if (r_fd)
    1361           0 :     *r_fd = -1;
    1362             : 
    1363             :   /* See whether we want scan or find mode. */
    1364           0 :   if (scan_mode)
    1365             :     {
    1366           0 :       assert (r_rid);
    1367             :     }
    1368             : 
    1369           0 :   n = libusb_get_device_list (NULL, &dev_list);
    1370             : 
    1371           0 :   for (i = 0; i < n; i++)
    1372             :     {
    1373           0 :       dev = dev_list[i];
    1374           0 :       if (scan_or_find_usb_device (scan_mode, &readerno, &count, &rid_list,
    1375             :                                    readerid,
    1376             :                                    dev,
    1377             :                                    r_rid,
    1378             :                                    &desc,
    1379             :                                    &idev,
    1380             :                                    ifcdesc_extra,
    1381             :                                    ifcdesc_extra_len,
    1382             :                                    interface_number,
    1383             :                                    ep_bulk_out, ep_bulk_in, ep_intr))
    1384             :         {
    1385           0 :           libusb_free_device_list (dev_list, 1);
    1386             :           /* Found requested device or out of core. */
    1387           0 :           if (!idev)
    1388             :             {
    1389           0 :               free (rid_list);
    1390           0 :               return -1; /* error */
    1391             :             }
    1392           0 :           *r_idev = idev;
    1393           0 :           if (r_desc)
    1394           0 :             memcpy (r_desc, &desc, sizeof (struct libusb_device_descriptor));
    1395           0 :           return 0;
    1396             :         }
    1397             :     }
    1398             : 
    1399           0 :   libusb_free_device_list (dev_list, 1);
    1400             : 
    1401             :   /* Now check whether there are any devices with special transport types. */
    1402           0 :   for (i=0; transports[i].name; i++)
    1403             :     {
    1404             :       int fd;
    1405             :       char *rid, *p;
    1406             : 
    1407           0 :       fd = open (transports[i].name, O_RDWR);
    1408           0 :       if (fd == -1 && scan_mode && errno == EBUSY)
    1409             :         {
    1410             :           /* Ignore this error in scan mode because it indicates that
    1411             :              the device exists but is already open (most likely by us)
    1412             :              and thus in general suitable as a reader.  */
    1413             :         }
    1414           0 :       else if (fd == -1)
    1415             :         {
    1416           0 :           DEBUGOUT_2 ("failed to open '%s': %s\n",
    1417             :                      transports[i].name, strerror (errno));
    1418           0 :           continue;
    1419             :         }
    1420             : 
    1421           0 :       rid = malloc (strlen (transports[i].name) + 30 + 10);
    1422           0 :       if (!rid)
    1423             :         {
    1424           0 :           if (fd != -1)
    1425           0 :             close (fd);
    1426           0 :           free (rid_list);
    1427           0 :           return -1; /* Error. */
    1428             :         }
    1429           0 :       sprintf (rid, "0000:%04X:%s:0", transports[i].type, transports[i].name);
    1430           0 :       if (scan_mode)
    1431             :         {
    1432           0 :           DEBUGOUT_2 ("found CCID reader %d (ID=%s)\n", count, rid);
    1433           0 :           p = malloc ((rid_list? strlen (rid_list):0) + 1 + strlen (rid) + 1);
    1434           0 :           if (!p)
    1435             :             {
    1436           0 :               if (fd != -1)
    1437           0 :                 close (fd);
    1438           0 :               free (rid_list);
    1439           0 :               free (rid);
    1440           0 :               return -1; /* Error. */
    1441             :             }
    1442           0 :           *p = 0;
    1443           0 :           if (rid_list)
    1444             :             {
    1445           0 :               strcat (p, rid_list);
    1446           0 :               free (rid_list);
    1447             :             }
    1448           0 :           strcat (p, rid);
    1449           0 :           strcat (p, "\n");
    1450           0 :           rid_list = p;
    1451           0 :           ++count;
    1452             :         }
    1453           0 :       else if (!readerno ||
    1454           0 :                (readerno < 0 && readerid && !strcmp (readerid, rid)))
    1455             :         {
    1456             :           /* Found requested device. */
    1457           0 :           if (interface_number)
    1458           0 :             *interface_number = transports[i].type;
    1459           0 :           if (r_rid)
    1460           0 :             *r_rid = rid;
    1461             :           else
    1462           0 :             free (rid);
    1463           0 :           if (r_fd)
    1464           0 :             *r_fd = fd;
    1465           0 :           return 0; /* Okay, found device */
    1466             :         }
    1467             :       else /* This is not yet the reader we want. */
    1468             :         {
    1469           0 :           if (readerno >= 0)
    1470           0 :             --readerno;
    1471             :         }
    1472           0 :       free (rid);
    1473           0 :       if (fd != -1)
    1474           0 :         close (fd);
    1475             :     }
    1476             : 
    1477           0 :   if (scan_mode)
    1478             :     {
    1479           0 :       *r_rid = rid_list;
    1480           0 :       return 0;
    1481             :     }
    1482             :   else
    1483           0 :     return -1;
    1484             : }
    1485             : 
    1486             : 
    1487             : /* Set the level of debugging to LEVEL and return the old level.  -1
    1488             :    just returns the old level.  A level of 0 disables debugging, 1
    1489             :    enables debugging, 2 enables additional tracing of the T=1
    1490             :    protocol, 3 additionally enables debugging for GetSlotStatus, other
    1491             :    values are not yet defined.
    1492             : 
    1493             :    Note that libusb may provide its own debugging feature which is
    1494             :    enabled by setting the envvar USB_DEBUG.  */
    1495             : int
    1496           0 : ccid_set_debug_level (int level)
    1497             : {
    1498           0 :   int old = debug_level;
    1499           0 :   if (level != -1)
    1500           0 :     debug_level = level;
    1501           0 :   return old;
    1502             : }
    1503             : 
    1504             : 
    1505             : char *
    1506           0 : ccid_get_reader_list (void)
    1507             : {
    1508             :   char *reader_list;
    1509             : 
    1510           0 :   if (!initialized_usb)
    1511             :     {
    1512           0 :       libusb_init (NULL);
    1513           0 :       initialized_usb = 1;
    1514             :     }
    1515             : 
    1516           0 :   if (scan_or_find_devices (-1, NULL, &reader_list, NULL, NULL, NULL, NULL,
    1517             :                             NULL, NULL, NULL, NULL, NULL))
    1518           0 :     return NULL; /* Error. */
    1519           0 :   return reader_list;
    1520             : }
    1521             : 
    1522             : 
    1523             : /* Vendor specific custom initialization.  */
    1524             : static int
    1525           0 : ccid_vendor_specific_init (ccid_driver_t handle)
    1526             : {
    1527           0 :   if (handle->id_vendor == VENDOR_VEGA && handle->id_product == VEGA_ALPHA)
    1528             :     {
    1529             :       int r;
    1530             :       /*
    1531             :        * Vega alpha has a feature to show retry counter on the pinpad
    1532             :        * display.  But it assumes that the card returns the value of
    1533             :        * retry counter by VERIFY with empty data (return code of
    1534             :        * 63Cx).  Unfortunately, existing OpenPGP cards don't support
    1535             :        * VERIFY command with empty data.  This vendor specific command
    1536             :        * sequence is to disable the feature.
    1537             :        */
    1538           0 :       const unsigned char cmd[] = { '\xb5', '\x01', '\x00', '\x03', '\x00' };
    1539             : 
    1540           0 :       r = send_escape_cmd (handle, cmd, sizeof (cmd), NULL, 0, NULL);
    1541           0 :       if (r != 0 && r != CCID_DRIVER_ERR_CARD_INACTIVE
    1542           0 :           && r != CCID_DRIVER_ERR_NO_CARD)
    1543           0 :         return r;
    1544             :     }
    1545             : 
    1546           0 :   return 0;
    1547             : }
    1548             : 
    1549             : 
    1550             : /* Open the reader with the internal number READERNO and return a
    1551             :    pointer to be used as handle in HANDLE.  Returns 0 on success. */
    1552             : int
    1553           0 : ccid_open_reader (ccid_driver_t *handle, const char *readerid,
    1554             :                   const char **rdrname_p)
    1555             : {
    1556           0 :   int rc = 0;
    1557           0 :   libusb_device_handle *idev = NULL;
    1558           0 :   int dev_fd = -1;
    1559           0 :   char *rid = NULL;
    1560           0 :   unsigned char *ifcdesc_extra = NULL;
    1561             :   size_t ifcdesc_extra_len;
    1562             :   int readerno;
    1563             :   int ifc_no, ep_bulk_out, ep_bulk_in, ep_intr;
    1564             :   struct libusb_device_descriptor desc;
    1565             : 
    1566           0 :   *handle = NULL;
    1567             : 
    1568           0 :   if (!initialized_usb)
    1569             :     {
    1570           0 :       libusb_init (NULL);
    1571           0 :       initialized_usb = 1;
    1572             :     }
    1573             : 
    1574             :   /* See whether we want to use the reader ID string or a reader
    1575             :      number. A readerno of -1 indicates that the reader ID string is
    1576             :      to be used. */
    1577           0 :   if (readerid && strchr (readerid, ':'))
    1578           0 :     readerno = -1; /* We want to use the readerid.  */
    1579           0 :   else if (readerid)
    1580             :     {
    1581           0 :       readerno = atoi (readerid);
    1582           0 :       if (readerno < 0)
    1583             :         {
    1584           0 :           DEBUGOUT ("no CCID readers found\n");
    1585           0 :           rc = CCID_DRIVER_ERR_NO_READER;
    1586           0 :           goto leave;
    1587             :         }
    1588             :     }
    1589             :   else
    1590           0 :     readerno = 0;  /* Default. */
    1591             : 
    1592           0 :   if (scan_or_find_devices (readerno, readerid, &rid, &desc,
    1593             :                             &ifcdesc_extra, &ifcdesc_extra_len,
    1594             :                             &ifc_no, &ep_bulk_out, &ep_bulk_in, &ep_intr,
    1595             :                             &idev, &dev_fd) )
    1596             :     {
    1597           0 :       if (readerno == -1)
    1598           0 :         DEBUGOUT_1 ("no CCID reader with ID %s\n", readerid );
    1599             :       else
    1600           0 :         DEBUGOUT_1 ("no CCID reader with number %d\n", readerno );
    1601           0 :       rc = CCID_DRIVER_ERR_NO_READER;
    1602           0 :       goto leave;
    1603             :     }
    1604             : 
    1605             :   /* Okay, this is a CCID reader. */
    1606           0 :   *handle = calloc (1, sizeof **handle);
    1607           0 :   if (!*handle)
    1608             :     {
    1609           0 :       DEBUGOUT ("out of memory\n");
    1610           0 :       rc = CCID_DRIVER_ERR_OUT_OF_CORE;
    1611           0 :       goto leave;
    1612             :     }
    1613           0 :   (*handle)->rid = rid;
    1614           0 :   if (idev) /* Regular USB transport. */
    1615             :     {
    1616           0 :       (*handle)->idev = idev;
    1617           0 :       (*handle)->dev_fd = -1;
    1618           0 :       (*handle)->id_vendor = desc.idVendor;
    1619           0 :       (*handle)->id_product = desc.idProduct;
    1620           0 :       (*handle)->bcd_device = desc.bcdDevice;
    1621           0 :       (*handle)->ifc_no = ifc_no;
    1622           0 :       (*handle)->ep_bulk_out = ep_bulk_out;
    1623           0 :       (*handle)->ep_bulk_in = ep_bulk_in;
    1624           0 :       (*handle)->ep_intr = ep_intr;
    1625             :     }
    1626           0 :   else if (dev_fd != -1) /* Device transport. */
    1627             :     {
    1628           0 :       (*handle)->idev = NULL;
    1629           0 :       (*handle)->dev_fd = dev_fd;
    1630           0 :       (*handle)->id_vendor = 0;  /* Magic vendor for special transport. */
    1631           0 :       (*handle)->id_product = ifc_no; /* Transport type */
    1632           0 :       prepare_special_transport (*handle);
    1633             :     }
    1634             :   else
    1635             :     {
    1636           0 :       assert (!"no transport"); /* Bug. */
    1637             :     }
    1638             : 
    1639           0 :   DEBUGOUT_2 ("using CCID reader %d (ID=%s)\n",  readerno, rid );
    1640             : 
    1641           0 :   if (idev)
    1642             :     {
    1643           0 :       if (parse_ccid_descriptor (*handle, ifcdesc_extra, ifcdesc_extra_len))
    1644             :         {
    1645           0 :           DEBUGOUT ("device not supported\n");
    1646           0 :           rc = CCID_DRIVER_ERR_NO_READER;
    1647           0 :           goto leave;
    1648             :         }
    1649             : 
    1650           0 :       rc = libusb_claim_interface (idev, ifc_no);
    1651           0 :       if (rc < 0)
    1652             :         {
    1653           0 :           DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc);
    1654           0 :           rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
    1655           0 :           goto leave;
    1656             :         }
    1657             :     }
    1658             : 
    1659           0 :   rc = ccid_vendor_specific_init (*handle);
    1660             : 
    1661             :  leave:
    1662           0 :   free (ifcdesc_extra);
    1663           0 :   if (rc)
    1664             :     {
    1665           0 :       free (rid);
    1666           0 :       if (idev)
    1667           0 :         libusb_close (idev);
    1668           0 :       if (dev_fd != -1)
    1669           0 :         close (dev_fd);
    1670           0 :       free (*handle);
    1671           0 :       *handle = NULL;
    1672             :     }
    1673             :   else
    1674           0 :     if (rdrname_p)
    1675           0 :       *rdrname_p = (*handle)->rid;
    1676             : 
    1677           0 :   return rc;
    1678             : }
    1679             : 
    1680             : 
    1681             : static void
    1682           0 : do_close_reader (ccid_driver_t handle)
    1683             : {
    1684             :   int rc;
    1685             :   unsigned char msg[100];
    1686             :   size_t msglen;
    1687             :   unsigned char seqno;
    1688             : 
    1689           0 :   if (!handle->powered_off)
    1690             :     {
    1691           0 :       msg[0] = PC_to_RDR_IccPowerOff;
    1692           0 :       msg[5] = 0; /* slot */
    1693           0 :       msg[6] = seqno = handle->seqno++;
    1694           0 :       msg[7] = 0; /* RFU */
    1695           0 :       msg[8] = 0; /* RFU */
    1696           0 :       msg[9] = 0; /* RFU */
    1697           0 :       set_msg_len (msg, 0);
    1698           0 :       msglen = 10;
    1699             : 
    1700           0 :       rc = bulk_out (handle, msg, msglen, 0);
    1701           0 :       if (!rc)
    1702           0 :         bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus,
    1703             :                  seqno, 2000, 0);
    1704           0 :       handle->powered_off = 1;
    1705             :     }
    1706           0 :   if (handle->idev)
    1707             :     {
    1708           0 :       libusb_release_interface (handle->idev, handle->ifc_no);
    1709           0 :       libusb_close (handle->idev);
    1710           0 :       handle->idev = NULL;
    1711             :     }
    1712           0 :   if (handle->dev_fd != -1)
    1713             :     {
    1714           0 :       close (handle->dev_fd);
    1715           0 :       handle->dev_fd = -1;
    1716             :     }
    1717           0 : }
    1718             : 
    1719             : 
    1720             : int
    1721           0 : ccid_set_progress_cb (ccid_driver_t handle,
    1722             :                       void (*cb)(void *, const char *, int, int, int),
    1723             :                       void *cb_arg)
    1724             : {
    1725           0 :   if (!handle || !handle->rid)
    1726           0 :     return CCID_DRIVER_ERR_INV_VALUE;
    1727             : 
    1728           0 :   handle->progress_cb = cb;
    1729           0 :   handle->progress_cb_arg = cb_arg;
    1730           0 :   return 0;
    1731             : }
    1732             : 
    1733             : 
    1734             : /* Close the reader HANDLE. */
    1735             : int
    1736           0 : ccid_close_reader (ccid_driver_t handle)
    1737             : {
    1738           0 :   if (!handle || (!handle->idev && handle->dev_fd == -1))
    1739           0 :     return 0;
    1740             : 
    1741           0 :   do_close_reader (handle);
    1742           0 :   free (handle->rid);
    1743           0 :   free (handle);
    1744           0 :   return 0;
    1745             : }
    1746             : 
    1747             : 
    1748             : /* Return False if a card is present and powered. */
    1749             : int
    1750           0 : ccid_check_card_presence (ccid_driver_t handle)
    1751             : {
    1752             :   (void)handle;  /* Not yet implemented.  */
    1753           0 :   return -1;
    1754             : }
    1755             : 
    1756             : 
    1757             : /* Write NBYTES of BUF to file descriptor FD. */
    1758             : static int
    1759           0 : writen (int fd, const void *buf, size_t nbytes)
    1760             : {
    1761           0 :   size_t nleft = nbytes;
    1762             :   int nwritten;
    1763             : 
    1764           0 :   while (nleft > 0)
    1765             :     {
    1766           0 :       nwritten = write (fd, buf, nleft);
    1767           0 :       if (nwritten < 0)
    1768             :         {
    1769           0 :           if (errno == EINTR)
    1770           0 :             nwritten = 0;
    1771             :           else
    1772           0 :             return -1;
    1773             :         }
    1774           0 :       nleft -= nwritten;
    1775           0 :       buf = (const char*)buf + nwritten;
    1776             :     }
    1777             : 
    1778           0 :   return 0;
    1779             : }
    1780             : 
    1781             : 
    1782             : /* Write a MSG of length MSGLEN to the designated bulk out endpoint.
    1783             :    Returns 0 on success. */
    1784             : static int
    1785           0 : bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen,
    1786             :           int no_debug)
    1787             : {
    1788             :   int rc;
    1789             : 
    1790             :   /* No need to continue and clutter the log with USB write error
    1791             :      messages after we got the first ENODEV.  */
    1792           0 :   if (handle->enodev_seen)
    1793           0 :     return CCID_DRIVER_ERR_NO_READER;
    1794             : 
    1795           0 :   if (debug_level && (!no_debug || debug_level >= 3))
    1796             :     {
    1797           0 :       switch (msglen? msg[0]:0)
    1798             :         {
    1799             :         case PC_to_RDR_IccPowerOn:
    1800           0 :           print_p2r_iccpoweron (msg, msglen);
    1801           0 :           break;
    1802             :         case PC_to_RDR_IccPowerOff:
    1803           0 :           print_p2r_iccpoweroff (msg, msglen);
    1804           0 :           break;
    1805             :         case PC_to_RDR_GetSlotStatus:
    1806           0 :           print_p2r_getslotstatus (msg, msglen);
    1807           0 :           break;
    1808             :         case PC_to_RDR_XfrBlock:
    1809           0 :           print_p2r_xfrblock (msg, msglen);
    1810           0 :           break;
    1811             :         case PC_to_RDR_GetParameters:
    1812           0 :           print_p2r_getparameters (msg, msglen);
    1813           0 :           break;
    1814             :         case PC_to_RDR_ResetParameters:
    1815           0 :           print_p2r_resetparameters (msg, msglen);
    1816           0 :           break;
    1817             :         case PC_to_RDR_SetParameters:
    1818           0 :           print_p2r_setparameters (msg, msglen);
    1819           0 :           break;
    1820             :         case PC_to_RDR_Escape:
    1821           0 :           print_p2r_escape (msg, msglen);
    1822           0 :           break;
    1823             :         case PC_to_RDR_IccClock:
    1824           0 :           print_p2r_iccclock (msg, msglen);
    1825           0 :           break;
    1826             :         case PC_to_RDR_T0APDU:
    1827           0 :           print_p2r_to0apdu (msg, msglen);
    1828           0 :           break;
    1829             :         case PC_to_RDR_Secure:
    1830           0 :           print_p2r_secure (msg, msglen);
    1831           0 :           break;
    1832             :         case PC_to_RDR_Mechanical:
    1833           0 :           print_p2r_mechanical (msg, msglen);
    1834           0 :           break;
    1835             :         case PC_to_RDR_Abort:
    1836           0 :           print_p2r_abort (msg, msglen);
    1837           0 :           break;
    1838             :         case PC_to_RDR_SetDataRate:
    1839           0 :           print_p2r_setdatarate (msg, msglen);
    1840           0 :           break;
    1841             :         default:
    1842           0 :           print_p2r_unknown (msg, msglen);
    1843           0 :           break;
    1844             :         }
    1845             :     }
    1846             : 
    1847           0 :   if (handle->idev)
    1848             :     {
    1849             :       int transferred;
    1850             : 
    1851           0 :       rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_out,
    1852             :                                  (char*)msg, msglen, &transferred,
    1853             :                                  5000 /* ms timeout */);
    1854           0 :       if (rc == 0 && transferred == msglen)
    1855           0 :         return 0;
    1856             : 
    1857           0 :       if (rc < 0)
    1858             :         {
    1859           0 :           DEBUGOUT_1 ("usb_bulk_write error: %s\n", libusb_error_name (rc));
    1860           0 :           if (rc == LIBUSB_ERROR_NO_DEVICE)
    1861             :             {
    1862           0 :               handle->enodev_seen = 1;
    1863           0 :               return CCID_DRIVER_ERR_NO_READER;
    1864             :             }
    1865             :         }
    1866             :     }
    1867             :   else
    1868             :     {
    1869           0 :       rc = writen (handle->dev_fd, msg, msglen);
    1870           0 :       if (!rc)
    1871           0 :         return 0;
    1872           0 :       DEBUGOUT_2 ("writen to %d failed: %s\n",
    1873             :                   handle->dev_fd, strerror (errno));
    1874             : 
    1875             :     }
    1876           0 :   return CCID_DRIVER_ERR_CARD_IO_ERROR;
    1877             : }
    1878             : 
    1879             : 
    1880             : /* Read a maximum of LENGTH bytes from the bulk in endpoint into
    1881             :    BUFFER and return the actual read number if bytes in NREAD. SEQNO
    1882             :    is the sequence number used to send the request and EXPECTED_TYPE
    1883             :    the type of message we expect. Does checks on the ccid
    1884             :    header. TIMEOUT is the timeout value in ms. NO_DEBUG may be set to
    1885             :    avoid debug messages in case of no error; this can be overriden
    1886             :    with a glibal debug level of at least 3. Returns 0 on success. */
    1887             : static int
    1888           0 : bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
    1889             :          size_t *nread, int expected_type, int seqno, int timeout,
    1890             :          int no_debug)
    1891             : {
    1892             :   int rc;
    1893             :   int msglen;
    1894           0 :   int eagain_retries = 0;
    1895             : 
    1896             :   /* Fixme: The next line for the current Valgrind without support
    1897             :      for USB IOCTLs. */
    1898           0 :   memset (buffer, 0, length);
    1899             :  retry:
    1900           0 :   if (handle->idev)
    1901             :     {
    1902           0 :       rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_in,
    1903             :                                  (char*)buffer, length, &msglen, timeout);
    1904           0 :       if (rc < 0)
    1905             :         {
    1906           0 :           DEBUGOUT_1 ("usb_bulk_read error: %s\n", libusb_error_name (rc));
    1907           0 :           if (rc == LIBUSB_ERROR_NO_DEVICE)
    1908             :             {
    1909           0 :               handle->enodev_seen = 1;
    1910           0 :               return CCID_DRIVER_ERR_NO_READER;
    1911             :             }
    1912             : 
    1913           0 :           return CCID_DRIVER_ERR_CARD_IO_ERROR;
    1914             :         }
    1915           0 :       if (msglen < 0)
    1916           0 :         return CCID_DRIVER_ERR_INV_VALUE;  /* Faulty libusb.  */
    1917           0 :       *nread = msglen;
    1918             :     }
    1919             :   else
    1920             :     {
    1921           0 :       rc = read (handle->dev_fd, buffer, length);
    1922           0 :       if (rc < 0)
    1923             :         {
    1924           0 :           rc = errno;
    1925           0 :           DEBUGOUT_2 ("read from %d failed: %s\n",
    1926             :                       handle->dev_fd, strerror (rc));
    1927           0 :           if (rc == EAGAIN && eagain_retries++ < 5)
    1928             :             {
    1929           0 :               my_sleep (1);
    1930           0 :               goto retry;
    1931             :             }
    1932           0 :           return CCID_DRIVER_ERR_CARD_IO_ERROR;
    1933             :         }
    1934           0 :       *nread = msglen = rc;
    1935             :     }
    1936           0 :   eagain_retries = 0;
    1937             : 
    1938           0 :   if (msglen < 10)
    1939             :     {
    1940           0 :       DEBUGOUT_1 ("bulk-in msg too short (%u)\n", (unsigned int)msglen);
    1941           0 :       abort_cmd (handle, seqno);
    1942           0 :       return CCID_DRIVER_ERR_INV_VALUE;
    1943             :     }
    1944           0 :   if (buffer[5] != 0)
    1945             :     {
    1946           0 :       DEBUGOUT_1 ("unexpected bulk-in slot (%d)\n", buffer[5]);
    1947           0 :       return CCID_DRIVER_ERR_INV_VALUE;
    1948             :     }
    1949           0 :   if (buffer[6] != seqno)
    1950             :     {
    1951           0 :       DEBUGOUT_2 ("bulk-in seqno does not match (%d/%d)\n",
    1952             :                   seqno, buffer[6]);
    1953             :       /* Retry until we are synced again.  */
    1954           0 :       goto retry;
    1955             :     }
    1956             : 
    1957             :   /* We need to handle the time extension request before we check that
    1958             :      we got the expected message type.  This is in particular required
    1959             :      for the Cherry keyboard which sends a time extension request for
    1960             :      each key hit.  */
    1961           0 :   if ( !(buffer[7] & 0x03) && (buffer[7] & 0xC0) == 0x80)
    1962             :     {
    1963             :       /* Card present and active, time extension requested. */
    1964           0 :       DEBUGOUT_2 ("time extension requested (%02X,%02X)\n",
    1965             :                   buffer[7], buffer[8]);
    1966           0 :       goto retry;
    1967             :     }
    1968             : 
    1969           0 :   if (buffer[0] != expected_type)
    1970             :     {
    1971           0 :       DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]);
    1972           0 :       abort_cmd (handle, seqno);
    1973           0 :       return CCID_DRIVER_ERR_INV_VALUE;
    1974             :     }
    1975             : 
    1976           0 :   if (debug_level && (!no_debug || debug_level >= 3))
    1977             :     {
    1978           0 :       switch (buffer[0])
    1979             :         {
    1980             :         case RDR_to_PC_DataBlock:
    1981           0 :           print_r2p_datablock (buffer, msglen);
    1982           0 :           break;
    1983             :         case RDR_to_PC_SlotStatus:
    1984           0 :           print_r2p_slotstatus (buffer, msglen);
    1985           0 :           break;
    1986             :         case RDR_to_PC_Parameters:
    1987           0 :           print_r2p_parameters (buffer, msglen);
    1988           0 :           break;
    1989             :         case RDR_to_PC_Escape:
    1990           0 :           print_r2p_escape (buffer, msglen);
    1991           0 :           break;
    1992             :         case RDR_to_PC_DataRate:
    1993           0 :           print_r2p_datarate (buffer, msglen);
    1994           0 :           break;
    1995             :         default:
    1996           0 :           print_r2p_unknown (buffer, msglen);
    1997           0 :           break;
    1998             :         }
    1999             :     }
    2000           0 :   if (CCID_COMMAND_FAILED (buffer))
    2001           0 :     print_command_failed (buffer);
    2002             : 
    2003             :   /* Check whether a card is at all available.  Note: If you add new
    2004             :      error codes here, check whether they need to be ignored in
    2005             :      send_escape_cmd. */
    2006           0 :   switch ((buffer[7] & 0x03))
    2007             :     {
    2008           0 :     case 0: /* no error */ break;
    2009           0 :     case 1: return CCID_DRIVER_ERR_CARD_INACTIVE;
    2010           0 :     case 2: return CCID_DRIVER_ERR_NO_CARD;
    2011           0 :     case 3: /* RFU */ break;
    2012             :     }
    2013           0 :   return 0;
    2014             : }
    2015             : 
    2016             : 
    2017             : 
    2018             : /* Send an abort sequence and wait until everything settled.  */
    2019             : static int
    2020           0 : abort_cmd (ccid_driver_t handle, int seqno)
    2021             : {
    2022             :   int rc;
    2023             :   char dummybuf[8];
    2024             :   unsigned char msg[100];
    2025             :   int msglen;
    2026             : 
    2027           0 :   if (!handle->idev)
    2028             :     {
    2029             :       /* I don't know how to send an abort to non-USB devices.  */
    2030           0 :       rc = CCID_DRIVER_ERR_NOT_SUPPORTED;
    2031             :     }
    2032             : 
    2033           0 :   seqno &= 0xff;
    2034           0 :   DEBUGOUT_1 ("sending abort sequence for seqno %d\n", seqno);
    2035             :   /* Send the abort command to the control pipe.  Note that we don't
    2036             :      need to keep track of sent abort commands because there should
    2037             :      never be another thread using the same slot concurrently.  */
    2038           0 :   rc = libusb_control_transfer (handle->idev,
    2039             :                                 0x21,/* bmRequestType: host-to-device,
    2040             :                                         class specific, to interface.  */
    2041             :                                 1,   /* ABORT */
    2042             :                                 (seqno << 8 | 0 /* slot */),
    2043           0 :                                 handle->ifc_no,
    2044             :                                 dummybuf, 0,
    2045             :                                 1000 /* ms timeout */);
    2046           0 :   if (rc < 0)
    2047             :     {
    2048           0 :       DEBUGOUT_1 ("usb_control_msg error: %s\n", libusb_error_name (rc));
    2049           0 :       return CCID_DRIVER_ERR_CARD_IO_ERROR;
    2050             :     }
    2051             : 
    2052             :   /* Now send the abort command to the bulk out pipe using the same
    2053             :      SEQNO and SLOT.  Do this in a loop to so that all seqno are
    2054             :      tried.  */
    2055           0 :   seqno--;  /* Adjust for next increment.  */
    2056             :   do
    2057             :     {
    2058             :       int transferred;
    2059             : 
    2060           0 :       seqno++;
    2061           0 :       msg[0] = PC_to_RDR_Abort;
    2062           0 :       msg[5] = 0; /* slot */
    2063           0 :       msg[6] = seqno;
    2064           0 :       msg[7] = 0; /* RFU */
    2065           0 :       msg[8] = 0; /* RFU */
    2066           0 :       msg[9] = 0; /* RFU */
    2067           0 :       msglen = 10;
    2068           0 :       set_msg_len (msg, 0);
    2069             : 
    2070           0 :       rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_out,
    2071             :                                  (char*)msg, msglen, &transferred,
    2072             :                                  5000 /* ms timeout */);
    2073           0 :       if (rc == 0 && transferred == msglen)
    2074           0 :         rc = 0;
    2075           0 :       else if (rc < 0)
    2076           0 :         DEBUGOUT_1 ("usb_bulk_write error in abort_cmd: %s\n",
    2077             :                     libusb_error_name (rc));
    2078             : 
    2079           0 :       if (rc)
    2080           0 :         return rc;
    2081             : 
    2082           0 :       rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_in,
    2083             :                                  (char*)msg, sizeof msg, &msglen,
    2084             :                                  5000 /*ms timeout*/);
    2085           0 :       if (rc < 0)
    2086             :         {
    2087           0 :           DEBUGOUT_1 ("usb_bulk_read error in abort_cmd: %s\n",
    2088             :                       libusb_error_name (rc));
    2089           0 :           return CCID_DRIVER_ERR_CARD_IO_ERROR;
    2090             :         }
    2091             : 
    2092           0 :       if (msglen < 10)
    2093             :         {
    2094           0 :           DEBUGOUT_1 ("bulk-in msg in abort_cmd too short (%u)\n",
    2095             :                       (unsigned int)msglen);
    2096           0 :           return CCID_DRIVER_ERR_INV_VALUE;
    2097             :         }
    2098           0 :       if (msg[5] != 0)
    2099             :         {
    2100           0 :           DEBUGOUT_1 ("unexpected bulk-in slot (%d) in abort_cmd\n", msg[5]);
    2101           0 :           return CCID_DRIVER_ERR_INV_VALUE;
    2102             :         }
    2103             : 
    2104           0 :       DEBUGOUT_3 ("status: %02X  error: %02X  octet[9]: %02X\n",
    2105             :                   msg[7], msg[8], msg[9]);
    2106           0 :       if (CCID_COMMAND_FAILED (msg))
    2107           0 :         print_command_failed (msg);
    2108             :     }
    2109           0 :   while (msg[0] != RDR_to_PC_SlotStatus && msg[5] != 0 && msg[6] != seqno);
    2110             : 
    2111           0 :   handle->seqno = ((seqno + 1) & 0xff);
    2112           0 :   DEBUGOUT ("sending abort sequence succeeded\n");
    2113             : 
    2114           0 :   return 0;
    2115             : }
    2116             : 
    2117             : 
    2118             : /* Note that this function won't return the error codes NO_CARD or
    2119             :    CARD_INACTIVE.  IF RESULT is not NULL, the result from the
    2120             :    operation will get returned in RESULT and its length in RESULTLEN.
    2121             :    If the response is larger than RESULTMAX, an error is returned and
    2122             :    the required buffer length returned in RESULTLEN.  */
    2123             : static int
    2124           0 : send_escape_cmd (ccid_driver_t handle,
    2125             :                  const unsigned char *data, size_t datalen,
    2126             :                  unsigned char *result, size_t resultmax, size_t *resultlen)
    2127             : {
    2128             :   int rc;
    2129             :   unsigned char msg[100];
    2130             :   size_t msglen;
    2131             :   unsigned char seqno;
    2132             : 
    2133           0 :   if (resultlen)
    2134           0 :     *resultlen = 0;
    2135             : 
    2136           0 :   if (datalen > sizeof msg - 10)
    2137           0 :     return CCID_DRIVER_ERR_INV_VALUE; /* Escape data too large.  */
    2138             : 
    2139           0 :   msg[0] = PC_to_RDR_Escape;
    2140           0 :   msg[5] = 0; /* slot */
    2141           0 :   msg[6] = seqno = handle->seqno++;
    2142           0 :   msg[7] = 0; /* RFU */
    2143           0 :   msg[8] = 0; /* RFU */
    2144           0 :   msg[9] = 0; /* RFU */
    2145           0 :   memcpy (msg+10, data, datalen);
    2146           0 :   msglen = 10 + datalen;
    2147           0 :   set_msg_len (msg, datalen);
    2148             : 
    2149           0 :   rc = bulk_out (handle, msg, msglen, 0);
    2150           0 :   if (rc)
    2151           0 :     return rc;
    2152           0 :   rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Escape,
    2153             :                 seqno, 5000, 0);
    2154           0 :   if (result)
    2155           0 :     switch (rc)
    2156             :       {
    2157             :         /* We need to ignore certain errorcode here. */
    2158             :       case 0:
    2159             :       case CCID_DRIVER_ERR_CARD_INACTIVE:
    2160             :       case CCID_DRIVER_ERR_NO_CARD:
    2161             :         {
    2162           0 :           if (msglen > resultmax)
    2163           0 :             rc = CCID_DRIVER_ERR_INV_VALUE; /* Response too large. */
    2164             :           else
    2165             :             {
    2166           0 :               memcpy (result, msg, msglen);
    2167           0 :               *resultlen = msglen;
    2168           0 :               rc = 0;
    2169             :             }
    2170             :         }
    2171           0 :         break;
    2172             :       default:
    2173           0 :         break;
    2174             :       }
    2175             : 
    2176           0 :   return rc;
    2177             : }
    2178             : 
    2179             : 
    2180             : int
    2181           0 : ccid_transceive_escape (ccid_driver_t handle,
    2182             :                         const unsigned char *data, size_t datalen,
    2183             :                         unsigned char *resp, size_t maxresplen, size_t *nresp)
    2184             : {
    2185           0 :   return send_escape_cmd (handle, data, datalen, resp, maxresplen, nresp);
    2186             : }
    2187             : 
    2188             : 
    2189             : 
    2190             : /* experimental */
    2191             : int
    2192           0 : ccid_poll (ccid_driver_t handle)
    2193             : {
    2194             :   int rc;
    2195             :   unsigned char msg[10];
    2196             :   int msglen;
    2197             :   int i, j;
    2198             : 
    2199           0 :   if (handle->idev)
    2200             :     {
    2201           0 :       rc = libusb_bulk_transfer (handle->idev, handle->ep_intr,
    2202             :                                  (char*)msg, sizeof msg, &msglen,
    2203             :                                  0 /* ms timeout */ );
    2204           0 :       if (rc == LIBUSB_ERROR_TIMEOUT)
    2205           0 :         return 0;
    2206             :     }
    2207             :   else
    2208           0 :     return 0;
    2209             : 
    2210           0 :   if (rc < 0)
    2211             :     {
    2212           0 :       DEBUGOUT_1 ("usb_intr_read error: %s\n", libusb_error_name (rc));
    2213           0 :       return CCID_DRIVER_ERR_CARD_IO_ERROR;
    2214             :     }
    2215             : 
    2216           0 :   if (msglen < 1)
    2217             :     {
    2218           0 :       DEBUGOUT ("intr-in msg too short\n");
    2219           0 :       return CCID_DRIVER_ERR_INV_VALUE;
    2220             :     }
    2221             : 
    2222           0 :   if (msg[0] == RDR_to_PC_NotifySlotChange)
    2223             :     {
    2224           0 :       DEBUGOUT ("notify slot change:");
    2225           0 :       for (i=1; i < msglen; i++)
    2226           0 :         for (j=0; j < 4; j++)
    2227           0 :           DEBUGOUT_CONT_3 (" %d:%c%c",
    2228             :                            (i-1)*4+j,
    2229             :                            (msg[i] & (1<<(j*2)))? 'p':'-',
    2230             :                            (msg[i] & (2<<(j*2)))? '*':' ');
    2231           0 :       DEBUGOUT_LF ();
    2232             :     }
    2233           0 :   else if (msg[0] == RDR_to_PC_HardwareError)
    2234             :     {
    2235           0 :       DEBUGOUT ("hardware error occurred\n");
    2236             :     }
    2237             :   else
    2238             :     {
    2239           0 :       DEBUGOUT_1 ("unknown intr-in msg of type %02X\n", msg[0]);
    2240             :     }
    2241             : 
    2242           0 :   return 0;
    2243             : }
    2244             : 
    2245             : 
    2246             : /* Note that this function won't return the error codes NO_CARD or
    2247             :    CARD_INACTIVE */
    2248             : int
    2249           0 : ccid_slot_status (ccid_driver_t handle, int *statusbits)
    2250             : {
    2251             :   int rc;
    2252             :   unsigned char msg[100];
    2253             :   size_t msglen;
    2254             :   unsigned char seqno;
    2255           0 :   int retries = 0;
    2256             : 
    2257             :  retry:
    2258           0 :   msg[0] = PC_to_RDR_GetSlotStatus;
    2259           0 :   msg[5] = 0; /* slot */
    2260           0 :   msg[6] = seqno = handle->seqno++;
    2261           0 :   msg[7] = 0; /* RFU */
    2262           0 :   msg[8] = 0; /* RFU */
    2263           0 :   msg[9] = 0; /* RFU */
    2264           0 :   set_msg_len (msg, 0);
    2265             : 
    2266           0 :   rc = bulk_out (handle, msg, 10, 1);
    2267           0 :   if (rc)
    2268           0 :     return rc;
    2269             :   /* Note that we set the NO_DEBUG flag here, so that the logs won't
    2270             :      get cluttered up by a ticker function checking for the slot
    2271             :      status and debugging enabled. */
    2272           0 :   rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus,
    2273             :                 seqno, retries? 1000 : 200, 1);
    2274           0 :   if (rc == CCID_DRIVER_ERR_CARD_IO_ERROR && retries < 3)
    2275             :     {
    2276           0 :       if (!retries)
    2277             :         {
    2278           0 :           DEBUGOUT ("USB: CALLING USB_CLEAR_HALT\n");
    2279           0 :           libusb_clear_halt (handle->idev, handle->ep_bulk_in);
    2280           0 :           libusb_clear_halt (handle->idev, handle->ep_bulk_out);
    2281             :         }
    2282             :       else
    2283           0 :           DEBUGOUT ("USB: RETRYING bulk_in AGAIN\n");
    2284           0 :       retries++;
    2285           0 :       goto retry;
    2286             :     }
    2287           0 :   if (rc && rc != CCID_DRIVER_ERR_NO_CARD
    2288           0 :       && rc != CCID_DRIVER_ERR_CARD_INACTIVE)
    2289           0 :     return rc;
    2290           0 :   *statusbits = (msg[7] & 3);
    2291             : 
    2292           0 :   return 0;
    2293             : }
    2294             : 
    2295             : 
    2296             : /* Parse ATR string (of ATRLEN) and update parameters at PARAM.
    2297             :    Calling this routine, it should prepare default values at PARAM
    2298             :    beforehand.  This routine assumes that card is accessed by T=1
    2299             :    protocol.  It doesn't analyze historical bytes at all.
    2300             : 
    2301             :    Returns < 0 value on error:
    2302             :      -1 for parse error or integrity check error
    2303             :      -2 for card doesn't support T=1 protocol
    2304             :      -3 for parameters are nod explicitly defined by ATR
    2305             :      -4 for this driver doesn't support CRC
    2306             : 
    2307             :    Returns >= 0 on success:
    2308             :       0 for card is negotiable mode
    2309             :       1 for card is specific mode (and not negotiable)
    2310             :  */
    2311             : static int
    2312           0 : update_param_by_atr (unsigned char *param, unsigned char *atr, size_t atrlen)
    2313             : {
    2314           0 :   int i = -1;
    2315             :   int t, y, chk;
    2316           0 :   int historical_bytes_num, negotiable = 1;
    2317             : 
    2318             : #define NEXTBYTE() do { i++; if (atrlen <= i) return -1; } while (0)
    2319             : 
    2320           0 :   NEXTBYTE ();
    2321             : 
    2322           0 :   if (atr[i] == 0x3F)
    2323           0 :     param[1] |= 0x02;           /* Convention is inverse.  */
    2324           0 :   NEXTBYTE ();
    2325             : 
    2326           0 :   y = (atr[i] >> 4);
    2327           0 :   historical_bytes_num = atr[i] & 0x0f;
    2328           0 :   NEXTBYTE ();
    2329             : 
    2330           0 :   if ((y & 1))
    2331             :     {
    2332           0 :       param[0] = atr[i];        /* TA1 - Fi & Di */
    2333           0 :       NEXTBYTE ();
    2334             :     }
    2335             : 
    2336           0 :   if ((y & 2))
    2337           0 :     NEXTBYTE ();                /* TB1 - ignore */
    2338             : 
    2339           0 :   if ((y & 4))
    2340             :     {
    2341           0 :       param[2] = atr[i];        /* TC1 - Guard Time */
    2342           0 :       NEXTBYTE ();
    2343             :     }
    2344             : 
    2345           0 :   if ((y & 8))
    2346             :     {
    2347           0 :       y = (atr[i] >> 4);        /* TD1 */
    2348           0 :       t = atr[i] & 0x0f;
    2349           0 :       NEXTBYTE ();
    2350             : 
    2351           0 :       if ((y & 1))
    2352             :         {                       /* TA2 - PPS mode */
    2353           0 :           if ((atr[i] & 0x0f) != 1)
    2354           0 :             return -2;          /* Wrong card protocol (!= 1).  */
    2355             : 
    2356           0 :           if ((atr[i] & 0x10) != 0x10)
    2357           0 :             return -3; /* Transmission parameters are implicitly defined. */
    2358             : 
    2359           0 :           negotiable = 0;       /* TA2 means specific mode.  */
    2360           0 :           NEXTBYTE ();
    2361             :         }
    2362             : 
    2363           0 :       if ((y & 2))
    2364           0 :         NEXTBYTE ();            /* TB2 - ignore */
    2365             : 
    2366           0 :       if ((y & 4))
    2367           0 :         NEXTBYTE ();            /* TC2 - ignore */
    2368             : 
    2369           0 :       if ((y & 8))
    2370             :         {
    2371           0 :           y = (atr[i] >> 4);    /* TD2 */
    2372           0 :           t = atr[i] & 0x0f;
    2373           0 :           NEXTBYTE ();
    2374             :         }
    2375             :       else
    2376           0 :         y = 0;
    2377             : 
    2378           0 :       while (y)
    2379             :         {
    2380           0 :           if ((y & 1))
    2381             :             {                   /* TAx */
    2382           0 :               if (t == 1)
    2383           0 :                 param[5] = atr[i]; /* IFSC */
    2384           0 :               else if (t == 15)
    2385             :                 /* XXX: check voltage? */
    2386           0 :                 param[4] = (atr[i] >> 6); /* ClockStop */
    2387             : 
    2388           0 :               NEXTBYTE ();
    2389             :             }
    2390             : 
    2391           0 :           if ((y & 2))
    2392             :             {
    2393           0 :               if (t == 1)
    2394           0 :                 param[3] = atr[i]; /* TBx - BWI & CWI */
    2395           0 :               NEXTBYTE ();
    2396             :             }
    2397             : 
    2398           0 :           if ((y & 4))
    2399             :             {
    2400           0 :               if (t == 1)
    2401           0 :                 param[1] |= (atr[i] & 0x01); /* TCx - LRC/CRC */
    2402           0 :               NEXTBYTE ();
    2403             : 
    2404           0 :               if (param[1] & 0x01)
    2405           0 :                 return -4;      /* CRC not supported yet.  */
    2406             :             }
    2407             : 
    2408           0 :           if ((y & 8))
    2409             :             {
    2410           0 :               y = (atr[i] >> 4); /* TDx */
    2411           0 :               t = atr[i] & 0x0f;
    2412           0 :               NEXTBYTE ();
    2413             :             }
    2414             :           else
    2415           0 :             y = 0;
    2416             :         }
    2417             :     }
    2418             : 
    2419           0 :   i += historical_bytes_num - 1;
    2420           0 :   NEXTBYTE ();
    2421           0 :   if (atrlen != i+1)
    2422           0 :     return -1;
    2423             : 
    2424             : #undef NEXTBYTE
    2425             : 
    2426           0 :   chk = 0;
    2427             :   do
    2428             :     {
    2429           0 :       chk ^= atr[i];
    2430           0 :       i--;
    2431             :     }
    2432           0 :   while (i > 0);
    2433             : 
    2434           0 :   if (chk != 0)
    2435           0 :     return -1;
    2436             : 
    2437           0 :   return negotiable;
    2438             : }
    2439             : 
    2440             : 
    2441             : /* Return the ATR of the card.  This is not a cached value and thus an
    2442             :    actual reset is done.  */
    2443             : int
    2444           0 : ccid_get_atr (ccid_driver_t handle,
    2445             :               unsigned char *atr, size_t maxatrlen, size_t *atrlen)
    2446             : {
    2447             :   int rc;
    2448             :   int statusbits;
    2449             :   unsigned char msg[100];
    2450             :   unsigned char *tpdu;
    2451             :   size_t msglen, tpdulen;
    2452             :   unsigned char seqno;
    2453           0 :   int use_crc = 0;
    2454             :   unsigned int edc;
    2455           0 :   int tried_iso = 0;
    2456             :   int got_param;
    2457           0 :   unsigned char param[7] = { /* For Protocol T=1 */
    2458             :     0x11, /* bmFindexDindex */
    2459             :     0x10, /* bmTCCKST1 */
    2460             :     0x00, /* bGuardTimeT1 */
    2461             :     0x4d, /* bmWaitingIntegersT1 */
    2462             :     0x00, /* bClockStop */
    2463             :     0x20, /* bIFSC */
    2464             :     0x00  /* bNadValue */
    2465             :   };
    2466             : 
    2467             :   /* First check whether a card is available.  */
    2468           0 :   rc = ccid_slot_status (handle, &statusbits);
    2469           0 :   if (rc)
    2470           0 :     return rc;
    2471           0 :   if (statusbits == 2)
    2472           0 :     return CCID_DRIVER_ERR_NO_CARD;
    2473             : 
    2474             :   /* For an inactive and also for an active card, issue the PowerOn
    2475             :      command to get the ATR.  */
    2476             :  again:
    2477           0 :   msg[0] = PC_to_RDR_IccPowerOn;
    2478           0 :   msg[5] = 0; /* slot */
    2479           0 :   msg[6] = seqno = handle->seqno++;
    2480             :   /* power select (0=auto, 1=5V, 2=3V, 3=1.8V) */
    2481           0 :   msg[7] = handle->auto_voltage ? 0 : 1;
    2482           0 :   msg[8] = 0; /* RFU */
    2483           0 :   msg[9] = 0; /* RFU */
    2484           0 :   set_msg_len (msg, 0);
    2485           0 :   msglen = 10;
    2486             : 
    2487           0 :   rc = bulk_out (handle, msg, msglen, 0);
    2488           0 :   if (rc)
    2489           0 :     return rc;
    2490           0 :   rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_DataBlock,
    2491             :                 seqno, 5000, 0);
    2492           0 :   if (rc)
    2493           0 :     return rc;
    2494           0 :   if (!tried_iso && CCID_COMMAND_FAILED (msg) && CCID_ERROR_CODE (msg) == 0xbb
    2495           0 :       && ((handle->id_vendor == VENDOR_CHERRY
    2496           0 :            && handle->id_product == 0x0005)
    2497           0 :           || (handle->id_vendor == VENDOR_GEMPC
    2498           0 :               && handle->id_product == 0x4433)
    2499             :           ))
    2500             :     {
    2501           0 :       tried_iso = 1;
    2502             :       /* Try switching to ISO mode. */
    2503           0 :       if (!send_escape_cmd (handle, (const unsigned char*)"\xF1\x01", 2,
    2504             :                             NULL, 0, NULL))
    2505           0 :         goto again;
    2506             :     }
    2507           0 :   else if (CCID_COMMAND_FAILED (msg))
    2508           0 :     return CCID_DRIVER_ERR_CARD_IO_ERROR;
    2509             : 
    2510             : 
    2511           0 :   handle->powered_off = 0;
    2512             : 
    2513           0 :   if (atr)
    2514             :     {
    2515           0 :       size_t n = msglen - 10;
    2516             : 
    2517           0 :       if (n > maxatrlen)
    2518           0 :         n = maxatrlen;
    2519           0 :       memcpy (atr, msg+10, n);
    2520           0 :       *atrlen = n;
    2521             :     }
    2522             : 
    2523           0 :   param[6] = handle->nonnull_nad? ((1 << 4) | 0): 0;
    2524           0 :   rc = update_param_by_atr (param, msg+10, msglen - 10);
    2525           0 :   if (rc < 0)
    2526             :     {
    2527           0 :       DEBUGOUT_1 ("update_param_by_atr failed: %d\n", rc);
    2528           0 :       return CCID_DRIVER_ERR_CARD_IO_ERROR;
    2529             :     }
    2530             : 
    2531           0 :   got_param = 0;
    2532             : 
    2533           0 :   if (handle->auto_param)
    2534             :     {
    2535           0 :       msg[0] = PC_to_RDR_GetParameters;
    2536           0 :       msg[5] = 0; /* slot */
    2537           0 :       msg[6] = seqno = handle->seqno++;
    2538           0 :       msg[7] = 0; /* RFU */
    2539           0 :       msg[8] = 0; /* RFU */
    2540           0 :       msg[9] = 0; /* RFU */
    2541           0 :       set_msg_len (msg, 0);
    2542           0 :       msglen = 10;
    2543           0 :       rc = bulk_out (handle, msg, msglen, 0);
    2544           0 :       if (!rc)
    2545           0 :         rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Parameters,
    2546             :                       seqno, 2000, 0);
    2547           0 :       if (rc)
    2548           0 :         DEBUGOUT ("GetParameters failed\n");
    2549           0 :       else if (msglen == 17 && msg[9] == 1)
    2550           0 :         got_param = 1;
    2551             :     }
    2552           0 :   else if (handle->auto_pps)
    2553             :     ;
    2554           0 :   else if (rc == 1)             /* It's negotiable, send PPS.  */
    2555             :     {
    2556           0 :       msg[0] = PC_to_RDR_XfrBlock;
    2557           0 :       msg[5] = 0; /* slot */
    2558           0 :       msg[6] = seqno = handle->seqno++;
    2559           0 :       msg[7] = 0;
    2560           0 :       msg[8] = 0;
    2561           0 :       msg[9] = 0;
    2562           0 :       msg[10] = 0xff;           /* PPSS */
    2563           0 :       msg[11] = 0x11;           /* PPS0: PPS1, Protocol T=1 */
    2564           0 :       msg[12] = param[0];       /* PPS1: Fi / Di */
    2565           0 :       msg[13] = 0xff ^ 0x11 ^ param[0]; /* PCK */
    2566           0 :       set_msg_len (msg, 4);
    2567           0 :       msglen = 10 + 4;
    2568             : 
    2569           0 :       rc = bulk_out (handle, msg, msglen, 0);
    2570           0 :       if (rc)
    2571           0 :         return rc;
    2572             : 
    2573           0 :       rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_DataBlock,
    2574             :                     seqno, 5000, 0);
    2575           0 :       if (rc)
    2576           0 :         return rc;
    2577             : 
    2578           0 :       if (msglen != 10 + 4)
    2579             :         {
    2580           0 :           DEBUGOUT_1 ("Setting PPS failed: %zu\n", msglen);
    2581           0 :           return CCID_DRIVER_ERR_CARD_IO_ERROR;
    2582             :         }
    2583             : 
    2584           0 :       if (msg[10] != 0xff || msg[11] != 0x11 || msg[12] != param[0])
    2585             :         {
    2586           0 :           DEBUGOUT_1 ("Setting PPS failed: 0x%02x\n", param[0]);
    2587           0 :           return CCID_DRIVER_ERR_CARD_IO_ERROR;
    2588             :         }
    2589             :     }
    2590             : 
    2591             :   /* Setup parameters to select T=1. */
    2592           0 :   msg[0] = PC_to_RDR_SetParameters;
    2593           0 :   msg[5] = 0; /* slot */
    2594           0 :   msg[6] = seqno = handle->seqno++;
    2595           0 :   msg[7] = 1; /* Select T=1. */
    2596           0 :   msg[8] = 0; /* RFU */
    2597           0 :   msg[9] = 0; /* RFU */
    2598             : 
    2599           0 :   if (!got_param)
    2600           0 :     memcpy (&msg[10], param, 7);
    2601           0 :   set_msg_len (msg, 7);
    2602           0 :   msglen = 10 + 7;
    2603             : 
    2604           0 :   rc = bulk_out (handle, msg, msglen, 0);
    2605           0 :   if (rc)
    2606           0 :     return rc;
    2607           0 :   rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Parameters,
    2608             :                 seqno, 5000, 0);
    2609           0 :   if (rc)
    2610           0 :     DEBUGOUT ("SetParameters failed (ignored)\n");
    2611             : 
    2612           0 :   if (!rc && msglen > 15 && msg[15] >= 16 && msg[15] <= 254 )
    2613           0 :     handle->ifsc = msg[15];
    2614             :   else
    2615           0 :     handle->ifsc = 128; /* Something went wrong, assume 128 bytes.  */
    2616             : 
    2617           0 :   if (handle->nonnull_nad && msglen > 16 && msg[16] == 0)
    2618             :     {
    2619           0 :       DEBUGOUT ("Use Null-NAD, clearing handle->nonnull_nad.\n");
    2620           0 :       handle->nonnull_nad = 0;
    2621             :     }
    2622             : 
    2623           0 :   handle->t1_ns = 0;
    2624           0 :   handle->t1_nr = 0;
    2625             : 
    2626             :   /* Send an S-Block with our maximum IFSD to the CCID.  */
    2627           0 :   if (!handle->apdu_level && !handle->auto_ifsd)
    2628             :     {
    2629           0 :       tpdu = msg+10;
    2630             :       /* NAD: DAD=1, SAD=0 */
    2631           0 :       tpdu[0] = handle->nonnull_nad? ((1 << 4) | 0): 0;
    2632           0 :       tpdu[1] = (0xc0 | 0 | 1); /* S-block request: change IFSD */
    2633           0 :       tpdu[2] = 1;
    2634           0 :       tpdu[3] = handle->max_ifsd? handle->max_ifsd : 32;
    2635           0 :       tpdulen = 4;
    2636           0 :       edc = compute_edc (tpdu, tpdulen, use_crc);
    2637           0 :       if (use_crc)
    2638           0 :         tpdu[tpdulen++] = (edc >> 8);
    2639           0 :       tpdu[tpdulen++] = edc;
    2640             : 
    2641           0 :       msg[0] = PC_to_RDR_XfrBlock;
    2642           0 :       msg[5] = 0; /* slot */
    2643           0 :       msg[6] = seqno = handle->seqno++;
    2644           0 :       msg[7] = 0;
    2645           0 :       msg[8] = 0; /* RFU */
    2646           0 :       msg[9] = 0; /* RFU */
    2647           0 :       set_msg_len (msg, tpdulen);
    2648           0 :       msglen = 10 + tpdulen;
    2649             : 
    2650           0 :       if (debug_level > 1)
    2651           0 :         DEBUGOUT_3 ("T=1: put %c-block seq=%d%s\n",
    2652             :                       ((msg[11] & 0xc0) == 0x80)? 'R' :
    2653             :                                 (msg[11] & 0x80)? 'S' : 'I',
    2654             :                       ((msg[11] & 0x80)? !!(msg[11]& 0x10)
    2655             :                                        : !!(msg[11] & 0x40)),
    2656             :                     (!(msg[11] & 0x80) && (msg[11] & 0x20)? " [more]":""));
    2657             : 
    2658           0 :       rc = bulk_out (handle, msg, msglen, 0);
    2659           0 :       if (rc)
    2660           0 :         return rc;
    2661             : 
    2662             : 
    2663           0 :       rc = bulk_in (handle, msg, sizeof msg, &msglen,
    2664             :                     RDR_to_PC_DataBlock, seqno, 5000, 0);
    2665           0 :       if (rc)
    2666           0 :         return rc;
    2667             : 
    2668           0 :       tpdu = msg + 10;
    2669           0 :       tpdulen = msglen - 10;
    2670             : 
    2671           0 :       if (tpdulen < 4)
    2672           0 :         return CCID_DRIVER_ERR_ABORTED;
    2673             : 
    2674           0 :       if (debug_level > 1)
    2675           0 :         DEBUGOUT_4 ("T=1: got %c-block seq=%d err=%d%s\n",
    2676             :                     ((msg[11] & 0xc0) == 0x80)? 'R' :
    2677             :                               (msg[11] & 0x80)? 'S' : 'I',
    2678             :                     ((msg[11] & 0x80)? !!(msg[11]& 0x10)
    2679             :                                      : !!(msg[11] & 0x40)),
    2680             :                     ((msg[11] & 0xc0) == 0x80)? (msg[11] & 0x0f) : 0,
    2681             :                     (!(msg[11] & 0x80) && (msg[11] & 0x20)? " [more]":""));
    2682             : 
    2683           0 :       if ((tpdu[1] & 0xe0) != 0xe0 || tpdu[2] != 1)
    2684             :         {
    2685           0 :           DEBUGOUT ("invalid response for S-block (Change-IFSD)\n");
    2686           0 :           return -1;
    2687             :         }
    2688           0 :       DEBUGOUT_1 ("IFSD has been set to %d\n", tpdu[3]);
    2689             :     }
    2690             : 
    2691           0 :   return 0;
    2692             : }
    2693             : 
    2694             : 
    2695             : 
    2696             : 
    2697             : static unsigned int
    2698           0 : compute_edc (const unsigned char *data, size_t datalen, int use_crc)
    2699             : {
    2700           0 :   if (use_crc)
    2701             :     {
    2702           0 :       return 0x42; /* Not yet implemented. */
    2703             :     }
    2704             :   else
    2705             :     {
    2706           0 :       unsigned char crc = 0;
    2707             : 
    2708           0 :       for (; datalen; datalen--)
    2709           0 :         crc ^= *data++;
    2710           0 :       return crc;
    2711             :     }
    2712             : }
    2713             : 
    2714             : 
    2715             : /* Return true if APDU is an extended length one.  */
    2716             : static int
    2717           0 : is_exlen_apdu (const unsigned char *apdu, size_t apdulen)
    2718             : {
    2719           0 :   if (apdulen < 7 || apdu[4])
    2720           0 :     return 0;  /* Too short or no Z byte.  */
    2721           0 :   return 1;
    2722             : }
    2723             : 
    2724             : 
    2725             : /* Helper for ccid_transceive used for APDU level exchanges.  */
    2726             : static int
    2727           0 : ccid_transceive_apdu_level (ccid_driver_t handle,
    2728             :                             const unsigned char *apdu_buf, size_t apdu_len,
    2729             :                             unsigned char *resp, size_t maxresplen,
    2730             :                             size_t *nresp)
    2731             : {
    2732             :   int rc;
    2733             :   unsigned char msg[CCID_MAX_BUF];
    2734             :   const unsigned char *apdu_p;
    2735             :   size_t apdu_part_len;
    2736             :   size_t msglen;
    2737             :   unsigned char seqno;
    2738           0 :   int bwi = 4;
    2739           0 :   unsigned char chain = 0;
    2740             : 
    2741           0 :   if (apdu_len == 0 || apdu_len > sizeof (msg) - 10)
    2742           0 :     return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */
    2743             : 
    2744           0 :   apdu_p = apdu_buf;
    2745             :   while (1)
    2746             :     {
    2747           0 :       apdu_part_len = apdu_len;
    2748           0 :       if (apdu_part_len > handle->max_ccid_msglen - 10)
    2749             :         {
    2750           0 :           apdu_part_len = handle->max_ccid_msglen - 10;
    2751           0 :           chain |= 0x01;
    2752             :         }
    2753             : 
    2754           0 :       msg[0] = PC_to_RDR_XfrBlock;
    2755           0 :       msg[5] = 0; /* slot */
    2756           0 :       msg[6] = seqno = handle->seqno++;
    2757           0 :       msg[7] = bwi;
    2758           0 :       msg[8] = chain;
    2759           0 :       msg[9] = 0;
    2760           0 :       memcpy (msg+10, apdu_p, apdu_part_len);
    2761           0 :       set_msg_len (msg, apdu_part_len);
    2762           0 :       msglen = 10 + apdu_part_len;
    2763             : 
    2764           0 :       rc = bulk_out (handle, msg, msglen, 0);
    2765           0 :       if (rc)
    2766           0 :         return rc;
    2767             : 
    2768           0 :       apdu_p += apdu_part_len;
    2769           0 :       apdu_len -= apdu_part_len;
    2770             : 
    2771           0 :       rc = bulk_in (handle, msg, sizeof msg, &msglen,
    2772             :                     RDR_to_PC_DataBlock, seqno, CCID_CMD_TIMEOUT, 0);
    2773           0 :       if (rc)
    2774           0 :         return rc;
    2775             : 
    2776           0 :       if (!(chain & 0x01))
    2777           0 :         break;
    2778             : 
    2779           0 :       chain = 0x02;
    2780           0 :     }
    2781             : 
    2782           0 :   apdu_len = 0;
    2783             :   while (1)
    2784             :     {
    2785           0 :       apdu_part_len = msglen - 10;
    2786           0 :       if (resp && apdu_len + apdu_part_len <= maxresplen)
    2787           0 :         memcpy (resp + apdu_len, msg+10, apdu_part_len);
    2788           0 :       apdu_len += apdu_part_len;
    2789             : 
    2790           0 :       if (!(msg[9] & 0x01))
    2791           0 :         break;
    2792             : 
    2793           0 :       msg[0] = PC_to_RDR_XfrBlock;
    2794           0 :       msg[5] = 0; /* slot */
    2795           0 :       msg[6] = seqno = handle->seqno++;
    2796           0 :       msg[7] = bwi;
    2797           0 :       msg[8] = 0x10;                /* Request next data block */
    2798           0 :       msg[9] = 0;
    2799           0 :       set_msg_len (msg, 0);
    2800           0 :       msglen = 10;
    2801             : 
    2802           0 :       rc = bulk_out (handle, msg, msglen, 0);
    2803           0 :       if (rc)
    2804           0 :         return rc;
    2805             : 
    2806           0 :       rc = bulk_in (handle, msg, sizeof msg, &msglen,
    2807             :                     RDR_to_PC_DataBlock, seqno, CCID_CMD_TIMEOUT, 0);
    2808           0 :       if (rc)
    2809           0 :         return rc;
    2810           0 :     }
    2811             : 
    2812           0 :   if (resp)
    2813             :     {
    2814           0 :       if (apdu_len > maxresplen)
    2815             :         {
    2816           0 :           DEBUGOUT_2 ("provided buffer too short for received data "
    2817             :                       "(%u/%u)\n",
    2818             :                       (unsigned int)apdu_len, (unsigned int)maxresplen);
    2819           0 :           return CCID_DRIVER_ERR_INV_VALUE;
    2820             :         }
    2821             : 
    2822           0 :       *nresp = apdu_len;
    2823             :     }
    2824             : 
    2825           0 :   return 0;
    2826             : }
    2827             : 
    2828             : 
    2829             : 
    2830             : /*
    2831             :   Protocol T=1 overview
    2832             : 
    2833             :   Block Structure:
    2834             :            Prologue Field:
    2835             :    1 byte     Node Address (NAD)
    2836             :    1 byte     Protocol Control Byte (PCB)
    2837             :    1 byte     Length (LEN)
    2838             :            Information Field:
    2839             :    0-254 byte APDU or Control Information (INF)
    2840             :            Epilogue Field:
    2841             :    1 byte     Error Detection Code (EDC)
    2842             : 
    2843             :   NAD:
    2844             :    bit 7     unused
    2845             :    bit 4..6  Destination Node Address (DAD)
    2846             :    bit 3     unused
    2847             :    bit 2..0  Source Node Address (SAD)
    2848             : 
    2849             :    If node adresses are not used, SAD and DAD should be set to 0 on
    2850             :    the first block sent to the card.  If they are used they should
    2851             :    have different values (0 for one is okay); that first block sets up
    2852             :    the addresses of the nodes.
    2853             : 
    2854             :   PCB:
    2855             :    Information Block (I-Block):
    2856             :       bit 7    0
    2857             :       bit 6    Sequence number (yep, that is modulo 2)
    2858             :       bit 5    Chaining flag
    2859             :       bit 4..0 reserved
    2860             :    Received-Ready Block (R-Block):
    2861             :       bit 7    1
    2862             :       bit 6    0
    2863             :       bit 5    0
    2864             :       bit 4    Sequence number
    2865             :       bit 3..0  0 = no error
    2866             :                 1 = EDC or parity error
    2867             :                 2 = other error
    2868             :                 other values are reserved
    2869             :    Supervisory Block (S-Block):
    2870             :       bit 7    1
    2871             :       bit 6    1
    2872             :       bit 5    clear=request,set=response
    2873             :       bit 4..0  0 = resyncronisation request
    2874             :                 1 = information field size request
    2875             :                 2 = abort request
    2876             :                 3 = extension of BWT request
    2877             :                 4 = VPP error
    2878             :                 other values are reserved
    2879             : 
    2880             : */
    2881             : 
    2882             : int
    2883           0 : ccid_transceive (ccid_driver_t handle,
    2884             :                  const unsigned char *apdu_buf, size_t apdu_buflen,
    2885             :                  unsigned char *resp, size_t maxresplen, size_t *nresp)
    2886             : {
    2887             :   int rc;
    2888             :   /* The size of the buffer used to be 10+259.  For the via_escape
    2889             :      hack we need one extra byte, thus 11+259.  */
    2890             :   unsigned char send_buffer[11+259], recv_buffer[11+259];
    2891             :   const unsigned char *apdu;
    2892             :   size_t apdulen;
    2893             :   unsigned char *msg, *tpdu, *p;
    2894             :   size_t msglen, tpdulen, last_tpdulen, n;
    2895             :   unsigned char seqno;
    2896             :   unsigned int edc;
    2897           0 :   int use_crc = 0;
    2898             :   int hdrlen, pcboff;
    2899             :   size_t dummy_nresp;
    2900           0 :   int via_escape = 0;
    2901           0 :   int next_chunk = 1;
    2902           0 :   int sending = 1;
    2903           0 :   int retries = 0;
    2904           0 :   int resyncing = 0;
    2905             :   int nad_byte;
    2906             : 
    2907           0 :   if (!nresp)
    2908           0 :     nresp = &dummy_nresp;
    2909           0 :   *nresp = 0;
    2910             : 
    2911             :   /* Smarter readers allow sending APDUs directly; divert here. */
    2912           0 :   if (handle->apdu_level)
    2913             :     {
    2914             :       /* We employ a hack for Omnikey readers which are able to send
    2915             :          TPDUs using an escape sequence.  There is no documentation
    2916             :          but the Windows driver does it this way.  Tested using a
    2917             :          CM6121.  This method works also for the Cherry XX44
    2918             :          keyboards; however there are problems with the
    2919             :          ccid_tranceive_secure which leads to a loss of sync on the
    2920             :          CCID level.  If Cherry wants to make their keyboard work
    2921             :          again, they should hand over some docs. */
    2922           0 :       if ((handle->id_vendor == VENDOR_OMNIKEY
    2923           0 :            || (!handle->idev && handle->id_product == TRANSPORT_CM4040))
    2924           0 :           && handle->apdu_level < 2
    2925           0 :           && is_exlen_apdu (apdu_buf, apdu_buflen))
    2926           0 :         via_escape = 1;
    2927             :       else
    2928           0 :         return ccid_transceive_apdu_level (handle, apdu_buf, apdu_buflen,
    2929             :                                            resp, maxresplen, nresp);
    2930             :     }
    2931             : 
    2932             :   /* The other readers we support require sending TPDUs.  */
    2933             : 
    2934           0 :   tpdulen = 0; /* Avoid compiler warning about no initialization. */
    2935           0 :   msg = send_buffer;
    2936           0 :   hdrlen = via_escape? 11 : 10;
    2937             : 
    2938             :   /* NAD: DAD=1, SAD=0 */
    2939           0 :   nad_byte = handle->nonnull_nad? ((1 << 4) | 0): 0;
    2940           0 :   if (via_escape)
    2941           0 :     nad_byte = 0;
    2942             : 
    2943           0 :   last_tpdulen = 0;  /* Avoid gcc warning (controlled by RESYNCING). */
    2944             :   for (;;)
    2945             :     {
    2946           0 :       if (next_chunk)
    2947             :         {
    2948           0 :           next_chunk = 0;
    2949             : 
    2950           0 :           apdu = apdu_buf;
    2951           0 :           apdulen = apdu_buflen;
    2952           0 :           assert (apdulen);
    2953             : 
    2954             :           /* Construct an I-Block. */
    2955           0 :           tpdu = msg + hdrlen;
    2956           0 :           tpdu[0] = nad_byte;
    2957           0 :           tpdu[1] = ((handle->t1_ns & 1) << 6); /* I-block */
    2958           0 :           if (apdulen > handle->ifsc )
    2959             :             {
    2960           0 :               apdulen = handle->ifsc;
    2961           0 :               apdu_buf += handle->ifsc;
    2962           0 :               apdu_buflen -= handle->ifsc;
    2963           0 :               tpdu[1] |= (1 << 5); /* Set more bit. */
    2964             :             }
    2965           0 :           tpdu[2] = apdulen;
    2966           0 :           memcpy (tpdu+3, apdu, apdulen);
    2967           0 :           tpdulen = 3 + apdulen;
    2968           0 :           edc = compute_edc (tpdu, tpdulen, use_crc);
    2969           0 :           if (use_crc)
    2970           0 :             tpdu[tpdulen++] = (edc >> 8);
    2971           0 :           tpdu[tpdulen++] = edc;
    2972             :         }
    2973             : 
    2974           0 :       if (via_escape)
    2975             :         {
    2976           0 :           msg[0] = PC_to_RDR_Escape;
    2977           0 :           msg[5] = 0; /* slot */
    2978           0 :           msg[6] = seqno = handle->seqno++;
    2979           0 :           msg[7] = 0; /* RFU */
    2980           0 :           msg[8] = 0; /* RFU */
    2981           0 :           msg[9] = 0; /* RFU */
    2982           0 :           msg[10] = 0x1a; /* Omnikey command to send a TPDU.  */
    2983           0 :           set_msg_len (msg, 1 + tpdulen);
    2984             :         }
    2985             :       else
    2986             :         {
    2987           0 :           msg[0] = PC_to_RDR_XfrBlock;
    2988           0 :           msg[5] = 0; /* slot */
    2989           0 :           msg[6] = seqno = handle->seqno++;
    2990           0 :           msg[7] = 4; /* bBWI */
    2991           0 :           msg[8] = 0; /* RFU */
    2992           0 :           msg[9] = 0; /* RFU */
    2993           0 :           set_msg_len (msg, tpdulen);
    2994             :         }
    2995           0 :       msglen = hdrlen + tpdulen;
    2996           0 :       if (!resyncing)
    2997           0 :         last_tpdulen = tpdulen;
    2998           0 :       pcboff = hdrlen+1;
    2999             : 
    3000           0 :       if (debug_level > 1)
    3001           0 :         DEBUGOUT_3 ("T=1: put %c-block seq=%d%s\n",
    3002             :                     ((msg[pcboff] & 0xc0) == 0x80)? 'R' :
    3003             :                     (msg[pcboff] & 0x80)? 'S' : 'I',
    3004             :                     ((msg[pcboff] & 0x80)? !!(msg[pcboff]& 0x10)
    3005             :                      : !!(msg[pcboff] & 0x40)),
    3006             :                     (!(msg[pcboff] & 0x80) && (msg[pcboff] & 0x20)?
    3007             :                      " [more]":""));
    3008             : 
    3009           0 :       rc = bulk_out (handle, msg, msglen, 0);
    3010           0 :       if (rc)
    3011           0 :         return rc;
    3012             : 
    3013           0 :       msg = recv_buffer;
    3014           0 :       rc = bulk_in (handle, msg, sizeof recv_buffer, &msglen,
    3015             :                     via_escape? RDR_to_PC_Escape : RDR_to_PC_DataBlock,
    3016             :                     seqno, CCID_CMD_TIMEOUT, 0);
    3017           0 :       if (rc)
    3018           0 :         return rc;
    3019             : 
    3020           0 :       tpdu = msg + hdrlen;
    3021           0 :       tpdulen = msglen - hdrlen;
    3022           0 :       resyncing = 0;
    3023             : 
    3024           0 :       if (tpdulen < 4)
    3025             :         {
    3026           0 :           libusb_clear_halt (handle->idev, handle->ep_bulk_in);
    3027           0 :           return CCID_DRIVER_ERR_ABORTED;
    3028             :         }
    3029             : 
    3030           0 :       if (debug_level > 1)
    3031           0 :         DEBUGOUT_4 ("T=1: got %c-block seq=%d err=%d%s\n",
    3032             :                     ((msg[pcboff] & 0xc0) == 0x80)? 'R' :
    3033             :                               (msg[pcboff] & 0x80)? 'S' : 'I',
    3034             :                     ((msg[pcboff] & 0x80)? !!(msg[pcboff]& 0x10)
    3035             :                      : !!(msg[pcboff] & 0x40)),
    3036             :                     ((msg[pcboff] & 0xc0) == 0x80)? (msg[pcboff] & 0x0f) : 0,
    3037             :                     (!(msg[pcboff] & 0x80) && (msg[pcboff] & 0x20)?
    3038             :                      " [more]":""));
    3039             : 
    3040           0 :       if (!(tpdu[1] & 0x80))
    3041             :         { /* This is an I-block. */
    3042           0 :           retries = 0;
    3043           0 :           if (sending)
    3044             :             { /* last block sent was successful. */
    3045           0 :               handle->t1_ns ^= 1;
    3046           0 :               sending = 0;
    3047             :             }
    3048             : 
    3049           0 :           if (!!(tpdu[1] & 0x40) != handle->t1_nr)
    3050             :             { /* Response does not match our sequence number. */
    3051           0 :               msg = send_buffer;
    3052           0 :               tpdu = msg + hdrlen;
    3053           0 :               tpdu[0] = nad_byte;
    3054           0 :               tpdu[1] = (0x80 | (handle->t1_nr & 1) << 4 | 2); /* R-block */
    3055           0 :               tpdu[2] = 0;
    3056           0 :               tpdulen = 3;
    3057           0 :               edc = compute_edc (tpdu, tpdulen, use_crc);
    3058           0 :               if (use_crc)
    3059           0 :                 tpdu[tpdulen++] = (edc >> 8);
    3060           0 :               tpdu[tpdulen++] = edc;
    3061             : 
    3062           0 :               continue;
    3063             :             }
    3064             : 
    3065           0 :           handle->t1_nr ^= 1;
    3066             : 
    3067           0 :           p = tpdu + 3; /* Skip the prologue field. */
    3068           0 :           n = tpdulen - 3 - 1; /* Strip the epilogue field. */
    3069             :           /* fixme: verify the checksum. */
    3070           0 :           if (resp)
    3071             :             {
    3072           0 :               if (n > maxresplen)
    3073             :                 {
    3074           0 :                   DEBUGOUT_2 ("provided buffer too short for received data "
    3075             :                               "(%u/%u)\n",
    3076             :                               (unsigned int)n, (unsigned int)maxresplen);
    3077           0 :                   return CCID_DRIVER_ERR_INV_VALUE;
    3078             :                 }
    3079             : 
    3080           0 :               memcpy (resp, p, n);
    3081           0 :               resp += n;
    3082           0 :               *nresp += n;
    3083           0 :               maxresplen -= n;
    3084             :             }
    3085             : 
    3086           0 :           if (!(tpdu[1] & 0x20))
    3087           0 :             return 0; /* No chaining requested - ready. */
    3088             : 
    3089           0 :           msg = send_buffer;
    3090           0 :           tpdu = msg + hdrlen;
    3091           0 :           tpdu[0] = nad_byte;
    3092           0 :           tpdu[1] = (0x80 | (handle->t1_nr & 1) << 4); /* R-block */
    3093           0 :           tpdu[2] = 0;
    3094           0 :           tpdulen = 3;
    3095           0 :           edc = compute_edc (tpdu, tpdulen, use_crc);
    3096           0 :           if (use_crc)
    3097           0 :             tpdu[tpdulen++] = (edc >> 8);
    3098           0 :           tpdu[tpdulen++] = edc;
    3099             :         }
    3100           0 :       else if ((tpdu[1] & 0xc0) == 0x80)
    3101             :         { /* This is a R-block. */
    3102           0 :           if ( (tpdu[1] & 0x0f))
    3103             :             {
    3104           0 :               retries++;
    3105           0 :               if (via_escape && retries == 1 && (msg[pcboff] & 0x0f))
    3106             :                 {
    3107             :                   /* Error probably due to switching to TPDU.  Send a
    3108             :                      resync request.  We use the recv_buffer so that
    3109             :                      we don't corrupt the send_buffer.  */
    3110           0 :                   msg = recv_buffer;
    3111           0 :                   tpdu = msg + hdrlen;
    3112           0 :                   tpdu[0] = nad_byte;
    3113           0 :                   tpdu[1] = 0xc0; /* S-block resync request. */
    3114           0 :                   tpdu[2] = 0;
    3115           0 :                   tpdulen = 3;
    3116           0 :                   edc = compute_edc (tpdu, tpdulen, use_crc);
    3117           0 :                   if (use_crc)
    3118           0 :                     tpdu[tpdulen++] = (edc >> 8);
    3119           0 :                   tpdu[tpdulen++] = edc;
    3120           0 :                   resyncing = 1;
    3121           0 :                   DEBUGOUT ("T=1: requesting resync\n");
    3122             :                 }
    3123           0 :               else if (retries > 3)
    3124             :                 {
    3125           0 :                   DEBUGOUT ("T=1: 3 failed retries\n");
    3126           0 :                   return CCID_DRIVER_ERR_CARD_IO_ERROR;
    3127             :                 }
    3128             :               else
    3129             :                 {
    3130             :                   /* Error: repeat last block */
    3131           0 :                   msg = send_buffer;
    3132           0 :                   tpdulen = last_tpdulen;
    3133             :                 }
    3134             :             }
    3135           0 :           else if (sending && !!(tpdu[1] & 0x10) == handle->t1_ns)
    3136             :             { /* Response does not match our sequence number. */
    3137           0 :               DEBUGOUT ("R-block with wrong seqno received on more bit\n");
    3138           0 :               return CCID_DRIVER_ERR_CARD_IO_ERROR;
    3139             :             }
    3140           0 :           else if (sending)
    3141             :             { /* Send next chunk. */
    3142           0 :               retries = 0;
    3143           0 :               msg = send_buffer;
    3144           0 :               next_chunk = 1;
    3145           0 :               handle->t1_ns ^= 1;
    3146             :             }
    3147             :           else
    3148             :             {
    3149           0 :               DEBUGOUT ("unexpected ACK R-block received\n");
    3150           0 :               return CCID_DRIVER_ERR_CARD_IO_ERROR;
    3151             :             }
    3152             :         }
    3153             :       else
    3154             :         { /* This is a S-block. */
    3155           0 :           retries = 0;
    3156           0 :           DEBUGOUT_2 ("T=1: S-block %s received cmd=%d\n",
    3157             :                       (tpdu[1] & 0x20)? "response": "request",
    3158             :                       (tpdu[1] & 0x1f));
    3159           0 :           if ( !(tpdu[1] & 0x20) && (tpdu[1] & 0x1f) == 1 && tpdu[2] == 1)
    3160           0 :             {
    3161             :               /* Information field size request.  */
    3162           0 :               unsigned char ifsc = tpdu[3];
    3163             : 
    3164           0 :               if (ifsc < 16 || ifsc > 254)
    3165           0 :                 return CCID_DRIVER_ERR_CARD_IO_ERROR;
    3166             : 
    3167           0 :               msg = send_buffer;
    3168           0 :               tpdu = msg + hdrlen;
    3169           0 :               tpdu[0] = nad_byte;
    3170           0 :               tpdu[1] = (0xc0 | 0x20 | 1); /* S-block response */
    3171           0 :               tpdu[2] = 1;
    3172           0 :               tpdu[3] = ifsc;
    3173           0 :               tpdulen = 4;
    3174           0 :               edc = compute_edc (tpdu, tpdulen, use_crc);
    3175           0 :               if (use_crc)
    3176           0 :                 tpdu[tpdulen++] = (edc >> 8);
    3177           0 :               tpdu[tpdulen++] = edc;
    3178           0 :               DEBUGOUT_1 ("T=1: requesting an ifsc=%d\n", ifsc);
    3179             :             }
    3180           0 :           else if ( !(tpdu[1] & 0x20) && (tpdu[1] & 0x1f) == 3 && tpdu[2])
    3181           0 :             {
    3182             :               /* Wait time extension request. */
    3183           0 :               unsigned char bwi = tpdu[3];
    3184           0 :               msg = send_buffer;
    3185           0 :               tpdu = msg + hdrlen;
    3186           0 :               tpdu[0] = nad_byte;
    3187           0 :               tpdu[1] = (0xc0 | 0x20 | 3); /* S-block response */
    3188           0 :               tpdu[2] = 1;
    3189           0 :               tpdu[3] = bwi;
    3190           0 :               tpdulen = 4;
    3191           0 :               edc = compute_edc (tpdu, tpdulen, use_crc);
    3192           0 :               if (use_crc)
    3193           0 :                 tpdu[tpdulen++] = (edc >> 8);
    3194           0 :               tpdu[tpdulen++] = edc;
    3195           0 :               DEBUGOUT_1 ("T=1: waittime extension of bwi=%d\n", bwi);
    3196           0 :               print_progress (handle);
    3197             :             }
    3198           0 :           else if ( (tpdu[1] & 0x20) && (tpdu[1] & 0x1f) == 0 && !tpdu[2])
    3199             :             {
    3200           0 :               DEBUGOUT ("T=1: resync ack from reader\n");
    3201             :               /* Repeat previous block.  */
    3202           0 :               msg = send_buffer;
    3203           0 :               tpdulen = last_tpdulen;
    3204             :             }
    3205             :           else
    3206           0 :             return CCID_DRIVER_ERR_CARD_IO_ERROR;
    3207             :         }
    3208           0 :     } /* end T=1 protocol loop. */
    3209             : 
    3210             :   return 0;
    3211             : }
    3212             : 
    3213             : 
    3214             : /* Send the CCID Secure command to the reader.  APDU_BUF should
    3215             :    contain the APDU template.  PIN_MODE defines how the pin gets
    3216             :    formatted:
    3217             : 
    3218             :      1 := The PIN is ASCII encoded and of variable length.  The
    3219             :           length of the PIN entered will be put into Lc by the reader.
    3220             :           The APDU should me made up of 4 bytes without Lc.
    3221             : 
    3222             :    PINLEN_MIN and PINLEN_MAX define the limits for the pin length. 0
    3223             :    may be used t enable reasonable defaults.
    3224             : 
    3225             :    When called with RESP and NRESP set to NULL, the function will
    3226             :    merely check whether the reader supports the secure command for the
    3227             :    given APDU and PIN_MODE. */
    3228             : int
    3229           0 : ccid_transceive_secure (ccid_driver_t handle,
    3230             :                         const unsigned char *apdu_buf, size_t apdu_buflen,
    3231             :                         pininfo_t *pininfo,
    3232             :                         unsigned char *resp, size_t maxresplen, size_t *nresp)
    3233             : {
    3234             :   int rc;
    3235             :   unsigned char send_buffer[10+259], recv_buffer[10+259];
    3236             :   unsigned char *msg, *tpdu, *p;
    3237             :   size_t msglen, tpdulen, n;
    3238             :   unsigned char seqno;
    3239             :   size_t dummy_nresp;
    3240             :   int testmode;
    3241           0 :   int cherry_mode = 0;
    3242           0 :   int add_zero = 0;
    3243           0 :   int enable_varlen = 0;
    3244             : 
    3245           0 :   testmode = !resp && !nresp;
    3246             : 
    3247           0 :   if (!nresp)
    3248           0 :     nresp = &dummy_nresp;
    3249           0 :   *nresp = 0;
    3250             : 
    3251           0 :   if (apdu_buflen >= 4 && apdu_buf[1] == 0x20 && (handle->has_pinpad & 1))
    3252             :     ;
    3253           0 :   else if (apdu_buflen >= 4 && apdu_buf[1] == 0x24 && (handle->has_pinpad & 2))
    3254             :     ;
    3255             :   else
    3256           0 :     return CCID_DRIVER_ERR_NO_PINPAD;
    3257             : 
    3258           0 :   if (!pininfo->minlen)
    3259           0 :     pininfo->minlen = 1;
    3260           0 :   if (!pininfo->maxlen)
    3261           0 :     pininfo->maxlen = 15;
    3262             : 
    3263             :   /* Note that the 25 is the maximum value the SPR532 allows.  */
    3264           0 :   if (pininfo->minlen < 1 || pininfo->minlen > 25
    3265           0 :       || pininfo->maxlen < 1 || pininfo->maxlen > 25
    3266           0 :       || pininfo->minlen > pininfo->maxlen)
    3267           0 :     return CCID_DRIVER_ERR_INV_VALUE;
    3268             : 
    3269             :   /* We have only tested a few readers so better don't risk anything
    3270             :      and do not allow the use with other readers. */
    3271           0 :   switch (handle->id_vendor)
    3272             :     {
    3273             :     case VENDOR_SCM:  /* Tested with SPR 532. */
    3274             :     case VENDOR_KAAN: /* Tested with KAAN Advanced (1.02). */
    3275             :     case VENDOR_FSIJ: /* Tested with Gnuk (0.21). */
    3276           0 :       pininfo->maxlen = 25;
    3277           0 :       enable_varlen = 1;
    3278           0 :       break;
    3279             :     case VENDOR_REINER:/* Tested with cyberJack go */
    3280             :     case VENDOR_VASCO: /* Tested with DIGIPASS 920 */
    3281           0 :       enable_varlen = 1;
    3282           0 :       break;
    3283             :     case VENDOR_CHERRY:
    3284           0 :       pininfo->maxlen = 15;
    3285           0 :       enable_varlen = 1;
    3286             :       /* The CHERRY XX44 keyboard echos an asterisk for each entered
    3287             :          character on the keyboard channel.  We use a special variant
    3288             :          of PC_to_RDR_Secure which directs these characters to the
    3289             :          smart card's bulk-in channel.  We also need to append a zero
    3290             :          Lc byte to the APDU.  It seems that it will be replaced with
    3291             :          the actual length instead of being appended before the APDU
    3292             :          is send to the card. */
    3293           0 :       add_zero = 1;
    3294           0 :       if (handle->id_product != CHERRY_ST2000)
    3295           0 :         cherry_mode = 1;
    3296           0 :       break;
    3297             :     default:
    3298           0 :       if ((handle->id_vendor == VENDOR_GEMPC &&
    3299           0 :            handle->id_product == GEMPC_PINPAD)
    3300           0 :           || (handle->id_vendor == VENDOR_VEGA &&
    3301           0 :               handle->id_product == VEGA_ALPHA))
    3302             :         {
    3303           0 :           enable_varlen = 0;
    3304           0 :           pininfo->minlen = 4;
    3305           0 :           pininfo->maxlen = 8;
    3306           0 :           break;
    3307             :         }
    3308           0 :      return CCID_DRIVER_ERR_NOT_SUPPORTED;
    3309             :     }
    3310             : 
    3311           0 :   if (enable_varlen)
    3312           0 :     pininfo->fixedlen = 0;
    3313             : 
    3314           0 :   if (testmode)
    3315           0 :     return 0; /* Success */
    3316             : 
    3317           0 :   if (pininfo->fixedlen < 0 || pininfo->fixedlen >= 16)
    3318           0 :     return CCID_DRIVER_ERR_NOT_SUPPORTED;
    3319             : 
    3320           0 :   msg = send_buffer;
    3321           0 :   if (handle->id_vendor == VENDOR_SCM)
    3322             :     {
    3323           0 :       DEBUGOUT ("sending escape sequence to switch to a case 1 APDU\n");
    3324           0 :       rc = send_escape_cmd (handle, (const unsigned char*)"\x80\x02\x00", 3,
    3325             :                             NULL, 0, NULL);
    3326           0 :       if (rc)
    3327           0 :         return rc;
    3328             :     }
    3329             : 
    3330           0 :   msg[0] = cherry_mode? 0x89 : PC_to_RDR_Secure;
    3331           0 :   msg[5] = 0; /* slot */
    3332           0 :   msg[6] = seqno = handle->seqno++;
    3333           0 :   msg[7] = 0; /* bBWI */
    3334           0 :   msg[8] = 0; /* RFU */
    3335           0 :   msg[9] = 0; /* RFU */
    3336           0 :   msg[10] = apdu_buf[1] == 0x20 ? 0 : 1;
    3337             :                /* Perform PIN verification or PIN modification. */
    3338           0 :   msg[11] = 0; /* Timeout in seconds. */
    3339           0 :   msg[12] = 0x82; /* bmFormatString: Byte, pos=0, left, ASCII. */
    3340           0 :   if (handle->id_vendor == VENDOR_SCM)
    3341             :     {
    3342             :       /* For the SPR532 the next 2 bytes need to be zero.  We do this
    3343             :          for all SCM products.  Kudos to Martin Paljak for this
    3344             :          hint.  */
    3345           0 :       msg[13] = msg[14] = 0;
    3346             :     }
    3347             :   else
    3348             :     {
    3349           0 :       msg[13] = pininfo->fixedlen; /* bmPINBlockString:
    3350             :                                       0 bits of pin length to insert.
    3351             :                                       PIN block size by fixedlen.  */
    3352           0 :       msg[14] = 0x00; /* bmPINLengthFormat:
    3353             :                          Units are bytes, position is 0. */
    3354             :     }
    3355             : 
    3356           0 :   msglen = 15;
    3357           0 :   if (apdu_buf[1] == 0x24)
    3358             :     {
    3359           0 :       msg[msglen++] = 0;    /* bInsertionOffsetOld */
    3360           0 :       msg[msglen++] = pininfo->fixedlen;    /* bInsertionOffsetNew */
    3361             :     }
    3362             : 
    3363             :   /* The following is a little endian word. */
    3364           0 :   msg[msglen++] = pininfo->maxlen;   /* wPINMaxExtraDigit-Maximum.  */
    3365           0 :   msg[msglen++] = pininfo->minlen;   /* wPINMaxExtraDigit-Minimum.  */
    3366             : 
    3367           0 :   if (apdu_buf[1] == 0x24)
    3368           0 :     msg[msglen++] = apdu_buf[2] == 0 ? 0x03 : 0x01;
    3369             :               /* bConfirmPIN
    3370             :                *    0x00: new PIN once
    3371             :                *    0x01: new PIN twice (confirmation)
    3372             :                *    0x02: old PIN and new PIN once
    3373             :                *    0x03: old PIN and new PIN twice (confirmation)
    3374             :                */
    3375             : 
    3376           0 :   msg[msglen] = 0x02; /* bEntryValidationCondition:
    3377             :                          Validation key pressed */
    3378           0 :   if (pininfo->minlen && pininfo->maxlen && pininfo->minlen == pininfo->maxlen)
    3379           0 :     msg[msglen] |= 0x01; /* Max size reached.  */
    3380           0 :   msglen++;
    3381             : 
    3382           0 :   if (apdu_buf[1] == 0x20)
    3383           0 :     msg[msglen++] = 0x01; /* bNumberMessage. */
    3384             :   else
    3385           0 :     msg[msglen++] = 0x03; /* bNumberMessage. */
    3386             : 
    3387           0 :   msg[msglen++] = 0x09; /* wLangId-Low:  English FIXME: use the first entry. */
    3388           0 :   msg[msglen++] = 0x04; /* wLangId-High. */
    3389             : 
    3390           0 :   if (apdu_buf[1] == 0x20)
    3391           0 :     msg[msglen++] = 0;    /* bMsgIndex. */
    3392             :   else
    3393             :     {
    3394           0 :       msg[msglen++] = 0;    /* bMsgIndex1. */
    3395           0 :       msg[msglen++] = 1;    /* bMsgIndex2. */
    3396           0 :       msg[msglen++] = 2;    /* bMsgIndex3. */
    3397             :     }
    3398             : 
    3399             :   /* Calculate Lc.  */
    3400           0 :   n = pininfo->fixedlen;
    3401           0 :   if (apdu_buf[1] == 0x24)
    3402           0 :     n += pininfo->fixedlen;
    3403             : 
    3404             :   /* bTeoProlog follows: */
    3405           0 :   msg[msglen++] = handle->nonnull_nad? ((1 << 4) | 0): 0;
    3406           0 :   msg[msglen++] = ((handle->t1_ns & 1) << 6); /* I-block */
    3407           0 :   if (n)
    3408           0 :     msg[msglen++] = n + 5; /* apdulen should be filled for fixed length.  */
    3409             :   else
    3410           0 :     msg[msglen++] = 0; /* The apdulen will be filled in by the reader.  */
    3411             :   /* APDU follows:  */
    3412           0 :   msg[msglen++] = apdu_buf[0]; /* CLA */
    3413           0 :   msg[msglen++] = apdu_buf[1]; /* INS */
    3414           0 :   msg[msglen++] = apdu_buf[2]; /* P1 */
    3415           0 :   msg[msglen++] = apdu_buf[3]; /* P2 */
    3416           0 :   if (add_zero)
    3417           0 :     msg[msglen++] = 0;
    3418           0 :   else if (pininfo->fixedlen != 0)
    3419             :     {
    3420           0 :       msg[msglen++] = n;
    3421           0 :       memset (&msg[msglen], 0xff, n);
    3422           0 :       msglen += n;
    3423             :     }
    3424             :   /* An EDC is not required. */
    3425           0 :   set_msg_len (msg, msglen - 10);
    3426             : 
    3427           0 :   rc = bulk_out (handle, msg, msglen, 0);
    3428           0 :   if (rc)
    3429           0 :     return rc;
    3430             : 
    3431           0 :   msg = recv_buffer;
    3432           0 :   rc = bulk_in (handle, msg, sizeof recv_buffer, &msglen,
    3433             :                 RDR_to_PC_DataBlock, seqno, 30000, 0);
    3434           0 :   if (rc)
    3435           0 :     return rc;
    3436             : 
    3437           0 :   tpdu = msg + 10;
    3438           0 :   tpdulen = msglen - 10;
    3439             : 
    3440           0 :   if (handle->apdu_level)
    3441             :     {
    3442           0 :       if (resp)
    3443             :         {
    3444           0 :           if (tpdulen > maxresplen)
    3445             :             {
    3446           0 :               DEBUGOUT_2 ("provided buffer too short for received data "
    3447             :                           "(%u/%u)\n",
    3448             :                           (unsigned int)tpdulen, (unsigned int)maxresplen);
    3449           0 :               return CCID_DRIVER_ERR_INV_VALUE;
    3450             :             }
    3451             : 
    3452           0 :           memcpy (resp, tpdu, tpdulen);
    3453           0 :           *nresp = tpdulen;
    3454             :         }
    3455           0 :       return 0;
    3456             :     }
    3457             : 
    3458           0 :   if (tpdulen < 4)
    3459             :     {
    3460           0 :       libusb_clear_halt (handle->idev, handle->ep_bulk_in);
    3461           0 :       return CCID_DRIVER_ERR_ABORTED;
    3462             :     }
    3463           0 :   if (debug_level > 1)
    3464           0 :     DEBUGOUT_4 ("T=1: got %c-block seq=%d err=%d%s\n",
    3465             :                 ((msg[11] & 0xc0) == 0x80)? 'R' :
    3466             :                           (msg[11] & 0x80)? 'S' : 'I',
    3467             :                 ((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40)),
    3468             :                 ((msg[11] & 0xc0) == 0x80)? (msg[11] & 0x0f) : 0,
    3469             :                 (!(msg[11] & 0x80) && (msg[11] & 0x20)? " [more]":""));
    3470             : 
    3471           0 :   if (!(tpdu[1] & 0x80))
    3472             :     { /* This is an I-block. */
    3473             :       /* Last block sent was successful. */
    3474           0 :       handle->t1_ns ^= 1;
    3475             : 
    3476           0 :       if (!!(tpdu[1] & 0x40) != handle->t1_nr)
    3477             :         { /* Response does not match our sequence number. */
    3478           0 :           DEBUGOUT ("I-block with wrong seqno received\n");
    3479           0 :           return CCID_DRIVER_ERR_CARD_IO_ERROR;
    3480             :         }
    3481             : 
    3482           0 :       handle->t1_nr ^= 1;
    3483             : 
    3484           0 :       p = tpdu + 3; /* Skip the prologue field. */
    3485           0 :       n = tpdulen - 3 - 1; /* Strip the epilogue field. */
    3486             :       /* fixme: verify the checksum. */
    3487           0 :       if (resp)
    3488             :         {
    3489           0 :           if (n > maxresplen)
    3490             :             {
    3491           0 :               DEBUGOUT_2 ("provided buffer too short for received data "
    3492             :                           "(%u/%u)\n",
    3493             :                           (unsigned int)n, (unsigned int)maxresplen);
    3494           0 :               return CCID_DRIVER_ERR_INV_VALUE;
    3495             :             }
    3496             : 
    3497           0 :           memcpy (resp, p, n);
    3498           0 :           resp += n;
    3499           0 :           *nresp += n;
    3500           0 :           maxresplen -= n;
    3501             :         }
    3502             : 
    3503           0 :       if (!(tpdu[1] & 0x20))
    3504           0 :         return 0; /* No chaining requested - ready. */
    3505             : 
    3506           0 :       DEBUGOUT ("chaining requested but not supported for Secure operation\n");
    3507           0 :       return CCID_DRIVER_ERR_CARD_IO_ERROR;
    3508             :     }
    3509           0 :   else if ((tpdu[1] & 0xc0) == 0x80)
    3510             :     { /* This is a R-block. */
    3511           0 :       if ( (tpdu[1] & 0x0f))
    3512             :         { /* Error: repeat last block */
    3513           0 :           DEBUGOUT ("No retries supported for Secure operation\n");
    3514           0 :           return CCID_DRIVER_ERR_CARD_IO_ERROR;
    3515             :         }
    3516           0 :       else if (!!(tpdu[1] & 0x10) == handle->t1_ns)
    3517             :         { /* Response does not match our sequence number. */
    3518           0 :           DEBUGOUT ("R-block with wrong seqno received on more bit\n");
    3519           0 :           return CCID_DRIVER_ERR_CARD_IO_ERROR;
    3520             :         }
    3521             :       else
    3522             :         { /* Send next chunk. */
    3523           0 :           DEBUGOUT ("chaining not supported on Secure operation\n");
    3524           0 :           return CCID_DRIVER_ERR_CARD_IO_ERROR;
    3525             :         }
    3526             :     }
    3527             :   else
    3528             :     { /* This is a S-block. */
    3529           0 :       DEBUGOUT_2 ("T=1: S-block %s received cmd=%d for Secure operation\n",
    3530             :                   (tpdu[1] & 0x20)? "response": "request",
    3531             :                   (tpdu[1] & 0x1f));
    3532           0 :       return CCID_DRIVER_ERR_CARD_IO_ERROR;
    3533             :     }
    3534             : 
    3535             :   return 0;
    3536             : }
    3537             : 
    3538             : 
    3539             : 
    3540             : 
    3541             : #ifdef TEST
    3542             : 
    3543             : 
    3544             : static void
    3545             : print_error (int err)
    3546             : {
    3547             :   const char *p;
    3548             :   char buf[50];
    3549             : 
    3550             :   switch (err)
    3551             :     {
    3552             :     case 0: p = "success";
    3553             :     case CCID_DRIVER_ERR_OUT_OF_CORE: p = "out of core"; break;
    3554             :     case CCID_DRIVER_ERR_INV_VALUE: p = "invalid value"; break;
    3555             :     case CCID_DRIVER_ERR_NO_DRIVER: p = "no driver"; break;
    3556             :     case CCID_DRIVER_ERR_NOT_SUPPORTED: p = "not supported"; break;
    3557             :     case CCID_DRIVER_ERR_LOCKING_FAILED: p = "locking failed"; break;
    3558             :     case CCID_DRIVER_ERR_BUSY: p = "busy"; break;
    3559             :     case CCID_DRIVER_ERR_NO_CARD: p = "no card"; break;
    3560             :     case CCID_DRIVER_ERR_CARD_INACTIVE: p = "card inactive"; break;
    3561             :     case CCID_DRIVER_ERR_CARD_IO_ERROR: p = "card I/O error"; break;
    3562             :     case CCID_DRIVER_ERR_GENERAL_ERROR: p = "general error"; break;
    3563             :     case CCID_DRIVER_ERR_NO_READER: p = "no reader"; break;
    3564             :     case CCID_DRIVER_ERR_ABORTED: p = "aborted"; break;
    3565             :     default: sprintf (buf, "0x%05x", err); p = buf; break;
    3566             :     }
    3567             :   fprintf (stderr, "operation failed: %s\n", p);
    3568             : }
    3569             : 
    3570             : 
    3571             : static void
    3572             : print_data (const unsigned char *data, size_t length)
    3573             : {
    3574             :   if (length >= 2)
    3575             :     {
    3576             :       fprintf (stderr, "operation status: %02X%02X\n",
    3577             :                data[length-2], data[length-1]);
    3578             :       length -= 2;
    3579             :     }
    3580             :   if (length)
    3581             :     {
    3582             :         fputs ("   returned data:", stderr);
    3583             :         for (; length; length--, data++)
    3584             :           fprintf (stderr, " %02X", *data);
    3585             :         putc ('\n', stderr);
    3586             :     }
    3587             : }
    3588             : 
    3589             : static void
    3590             : print_result (int rc, const unsigned char *data, size_t length)
    3591             : {
    3592             :   if (rc)
    3593             :     print_error (rc);
    3594             :   else if (data)
    3595             :     print_data (data, length);
    3596             : }
    3597             : 
    3598             : int
    3599             : main (int argc, char **argv)
    3600             : {
    3601             :   int rc;
    3602             :   ccid_driver_t ccid;
    3603             :   int slotstat;
    3604             :   unsigned char result[512];
    3605             :   size_t resultlen;
    3606             :   int no_pinpad = 0;
    3607             :   int verify_123456 = 0;
    3608             :   int did_verify = 0;
    3609             :   int no_poll = 0;
    3610             : 
    3611             :   if (argc)
    3612             :     {
    3613             :       argc--;
    3614             :       argv++;
    3615             :     }
    3616             : 
    3617             :   while (argc)
    3618             :     {
    3619             :       if ( !strcmp (*argv, "--list"))
    3620             :         {
    3621             :           char *p;
    3622             :           p = ccid_get_reader_list ();
    3623             :           if (!p)
    3624             :             return 1;
    3625             :           fputs (p, stderr);
    3626             :           free (p);
    3627             :           return 0;
    3628             :         }
    3629             :       else if ( !strcmp (*argv, "--debug"))
    3630             :         {
    3631             :           ccid_set_debug_level (ccid_set_debug_level (-1)+1);
    3632             :           argc--; argv++;
    3633             :         }
    3634             :       else if ( !strcmp (*argv, "--no-poll"))
    3635             :         {
    3636             :           no_poll = 1;
    3637             :           argc--; argv++;
    3638             :         }
    3639             :       else if ( !strcmp (*argv, "--no-pinpad"))
    3640             :         {
    3641             :           no_pinpad = 1;
    3642             :           argc--; argv++;
    3643             :         }
    3644             :       else if ( !strcmp (*argv, "--verify-123456"))
    3645             :         {
    3646             :           verify_123456 = 1;
    3647             :           argc--; argv++;
    3648             :         }
    3649             :       else
    3650             :         break;
    3651             :     }
    3652             : 
    3653             :   rc = ccid_open_reader (&ccid, argc? *argv:NULL, NULL);
    3654             :   if (rc)
    3655             :     return 1;
    3656             : 
    3657             :   if (!no_poll)
    3658             :     ccid_poll (ccid);
    3659             :   fputs ("getting ATR ...\n", stderr);
    3660             :   rc = ccid_get_atr (ccid, NULL, 0, NULL);
    3661             :   if (rc)
    3662             :     {
    3663             :       print_error (rc);
    3664             :       return 1;
    3665             :     }
    3666             : 
    3667             :   if (!no_poll)
    3668             :     ccid_poll (ccid);
    3669             :   fputs ("getting slot status ...\n", stderr);
    3670             :   rc = ccid_slot_status (ccid, &slotstat);
    3671             :   if (rc)
    3672             :     {
    3673             :       print_error (rc);
    3674             :       return 1;
    3675             :     }
    3676             : 
    3677             :   if (!no_poll)
    3678             :     ccid_poll (ccid);
    3679             : 
    3680             :   fputs ("selecting application OpenPGP ....\n", stderr);
    3681             :   {
    3682             :     static unsigned char apdu[] = {
    3683             :       0, 0xA4, 4, 0, 6, 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01};
    3684             :     rc = ccid_transceive (ccid,
    3685             :                           apdu, sizeof apdu,
    3686             :                           result, sizeof result, &resultlen);
    3687             :     print_result (rc, result, resultlen);
    3688             :   }
    3689             : 
    3690             : 
    3691             :   if (!no_poll)
    3692             :     ccid_poll (ccid);
    3693             : 
    3694             :   fputs ("getting OpenPGP DO 0x65 ....\n", stderr);
    3695             :   {
    3696             :     static unsigned char apdu[] = { 0, 0xCA, 0, 0x65, 254 };
    3697             :     rc = ccid_transceive (ccid, apdu, sizeof apdu,
    3698             :                           result, sizeof result, &resultlen);
    3699             :     print_result (rc, result, resultlen);
    3700             :   }
    3701             : 
    3702             :   if (!no_pinpad)
    3703             :     {
    3704             :     }
    3705             : 
    3706             :   if (!no_pinpad)
    3707             :     {
    3708             :       static unsigned char apdu[] = { 0, 0x20, 0, 0x81 };
    3709             : 
    3710             : 
    3711             :       if (ccid_transceive_secure (ccid,
    3712             :                                   apdu, sizeof apdu,
    3713             :                                   1, 0, 0, 0,
    3714             :                                   NULL, 0, NULL))
    3715             :         fputs ("can't verify using a PIN-Pad reader\n", stderr);
    3716             :       else
    3717             :         {
    3718             :           fputs ("verifying CHV1 using the PINPad ....\n", stderr);
    3719             : 
    3720             :           rc = ccid_transceive_secure (ccid,
    3721             :                                        apdu, sizeof apdu,
    3722             :                                        1, 0, 0, 0,
    3723             :                                        result, sizeof result, &resultlen);
    3724             :           print_result (rc, result, resultlen);
    3725             :           did_verify = 1;
    3726             :         }
    3727             :     }
    3728             : 
    3729             :   if (verify_123456 && !did_verify)
    3730             :     {
    3731             :       fputs ("verifying that CHV1 is 123456....\n", stderr);
    3732             :       {
    3733             :         static unsigned char apdu[] = {0, 0x20, 0, 0x81,
    3734             :                                        6, '1','2','3','4','5','6'};
    3735             :         rc = ccid_transceive (ccid, apdu, sizeof apdu,
    3736             :                               result, sizeof result, &resultlen);
    3737             :         print_result (rc, result, resultlen);
    3738             :       }
    3739             :     }
    3740             : 
    3741             :   if (!rc)
    3742             :     {
    3743             :       fputs ("getting OpenPGP DO 0x5E ....\n", stderr);
    3744             :       {
    3745             :         static unsigned char apdu[] = { 0, 0xCA, 0, 0x5E, 254 };
    3746             :         rc = ccid_transceive (ccid, apdu, sizeof apdu,
    3747             :                               result, sizeof result, &resultlen);
    3748             :         print_result (rc, result, resultlen);
    3749             :       }
    3750             :     }
    3751             : 
    3752             :   ccid_close_reader (ccid);
    3753             : 
    3754             :   return 0;
    3755             : }
    3756             : 
    3757             : /*
    3758             :  * Local Variables:
    3759             :  *  compile-command: "gcc -DTEST -Wall -I/usr/local/include -lusb -g ccid-driver.c"
    3760             :  * End:
    3761             :  */
    3762             : #endif /*TEST*/
    3763             : #endif /*HAVE_LIBUSB*/

Generated by: LCOV version 1.11