LCOV - code coverage report
Current view: top level - scd - apdu.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1356 0.0 %
Date: 2016-09-12 13:01:59 Functions: 0 67 0.0 %

          Line data    Source code
       1             : /* apdu.c - ISO 7816 APDU functions and low level I/O
       2             :  * Copyright (C) 2003, 2004, 2008, 2009, 2010,
       3             :  *               2011 Free Software Foundation, Inc.
       4             :  *
       5             :  * This file is part of GnuPG.
       6             :  *
       7             :  * GnuPG is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU General Public License as published by
       9             :  * the Free Software Foundation; either version 3 of the License, or
      10             :  * (at your option) any later version.
      11             :  *
      12             :  * GnuPG is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License
      18             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : /* NOTE: This module is also used by other software, thus the use of
      22             :    the macro USE_NPTH is mandatory.  For GnuPG this macro is
      23             :    guaranteed to be defined true. */
      24             : 
      25             : #include <config.h>
      26             : #include <errno.h>
      27             : #include <stdio.h>
      28             : #include <stdlib.h>
      29             : #include <string.h>
      30             : #include <assert.h>
      31             : #include <signal.h>
      32             : #ifdef USE_NPTH
      33             : # include <unistd.h>
      34             : # include <fcntl.h>
      35             : # include <npth.h>
      36             : #endif
      37             : 
      38             : 
      39             : /* If requested include the definitions for the remote APDU protocol
      40             :    code. */
      41             : #ifdef USE_G10CODE_RAPDU
      42             : #include "rapdu.h"
      43             : #endif /*USE_G10CODE_RAPDU*/
      44             : 
      45             : #if defined(GNUPG_SCD_MAIN_HEADER)
      46             : #include GNUPG_SCD_MAIN_HEADER
      47             : #elif GNUPG_MAJOR_VERSION == 1
      48             : /* This is used with GnuPG version < 1.9.  The code has been source
      49             :    copied from the current GnuPG >= 1.9  and is maintained over
      50             :    there. */
      51             : #include "options.h"
      52             : #include "errors.h"
      53             : #include "memory.h"
      54             : #include "util.h"
      55             : #include "i18n.h"
      56             : #include "dynload.h"
      57             : #include "cardglue.h"
      58             : #else /* GNUPG_MAJOR_VERSION != 1 */
      59             : #include "scdaemon.h"
      60             : #include "exechelp.h"
      61             : #endif /* GNUPG_MAJOR_VERSION != 1 */
      62             : #include "host2net.h"
      63             : 
      64             : #include "iso7816.h"
      65             : #include "apdu.h"
      66             : #define CCID_DRIVER_INCLUDE_USB_IDS 1
      67             : #include "ccid-driver.h"
      68             : 
      69             : /* Due to conflicting use of threading libraries we usually can't link
      70             :    against libpcsclite if we are using Pth.  Instead we use a wrapper
      71             :    program.  Note that with nPth there is no need for a wrapper. */
      72             : #ifdef USE_PTH  /* Right, plain old Pth.  */
      73             : #if !defined(HAVE_W32_SYSTEM) && !defined(__CYGWIN__)
      74             : #define NEED_PCSC_WRAPPER 1
      75             : #endif
      76             : #endif
      77             : 
      78             : 
      79             : #define MAX_READER 4 /* Number of readers we support concurrently. */
      80             : 
      81             : 
      82             : #if defined(_WIN32) || defined(__CYGWIN__)
      83             : #define DLSTDCALL __stdcall
      84             : #else
      85             : #define DLSTDCALL
      86             : #endif
      87             : 
      88             : #if defined(__APPLE__) || defined(_WIN32) || defined(__CYGWIN__)
      89             : typedef unsigned int pcsc_dword_t;
      90             : #else
      91             : typedef unsigned long pcsc_dword_t;
      92             : #endif
      93             : 
      94             : /* A structure to collect information pertaining to one reader
      95             :    slot. */
      96             : struct reader_table_s {
      97             :   int used;            /* True if slot is used. */
      98             :   unsigned short port; /* Port number:  0 = unused, 1 - dev/tty */
      99             : 
     100             :   /* Function pointers intialized to the various backends.  */
     101             :   int (*connect_card)(int);
     102             :   int (*disconnect_card)(int);
     103             :   int (*close_reader)(int);
     104             :   int (*reset_reader)(int);
     105             :   int (*get_status_reader)(int, unsigned int *);
     106             :   int (*send_apdu_reader)(int,unsigned char *,size_t,
     107             :                           unsigned char *, size_t *, pininfo_t *);
     108             :   int (*check_pinpad)(int, int, pininfo_t *);
     109             :   void (*dump_status_reader)(int);
     110             :   int (*set_progress_cb)(int, gcry_handler_progress_t, void*);
     111             :   int (*pinpad_verify)(int, int, int, int, int, pininfo_t *);
     112             :   int (*pinpad_modify)(int, int, int, int, int, pininfo_t *);
     113             : 
     114             :   struct {
     115             :     ccid_driver_t handle;
     116             :   } ccid;
     117             :   struct {
     118             :     long context;
     119             :     long card;
     120             :     pcsc_dword_t protocol;
     121             :     pcsc_dword_t verify_ioctl;
     122             :     pcsc_dword_t modify_ioctl;
     123             :     int pinmin;
     124             :     int pinmax;
     125             : #ifdef NEED_PCSC_WRAPPER
     126             :     int req_fd;
     127             :     int rsp_fd;
     128             :     pid_t pid;
     129             : #endif /*NEED_PCSC_WRAPPER*/
     130             :   } pcsc;
     131             : #ifdef USE_G10CODE_RAPDU
     132             :   struct {
     133             :     rapdu_t handle;
     134             :   } rapdu;
     135             : #endif /*USE_G10CODE_RAPDU*/
     136             :   char *rdrname;     /* Name of the connected reader or NULL if unknown. */
     137             :   int any_status;    /* True if we have seen any status.  */
     138             :   int last_status;
     139             :   int status;
     140             :   int is_t0;         /* True if we know that we are running T=0. */
     141             :   int is_spr532;     /* True if we know that the reader is a SPR532.  */
     142             :   int pinpad_varlen_supported;  /* True if we know that the reader
     143             :                                    supports variable length pinpad
     144             :                                    input.  */
     145             :   unsigned char atr[33];
     146             :   size_t atrlen;           /* A zero length indicates that the ATR has
     147             :                               not yet been read; i.e. the card is not
     148             :                               ready for use. */
     149             :   unsigned int change_counter;
     150             : #ifdef USE_NPTH
     151             :   int lock_initialized;
     152             :   npth_mutex_t lock;
     153             : #endif
     154             : };
     155             : typedef struct reader_table_s *reader_table_t;
     156             : 
     157             : /* A global table to keep track of active readers. */
     158             : static struct reader_table_s reader_table[MAX_READER];
     159             : 
     160             : 
     161             : /* ct API function pointer. */
     162             : static char (* DLSTDCALL CT_init) (unsigned short ctn, unsigned short Pn);
     163             : static char (* DLSTDCALL CT_data) (unsigned short ctn, unsigned char *dad,
     164             :                                    unsigned char *sad, unsigned short lc,
     165             :                                    unsigned char *cmd, unsigned short *lr,
     166             :                                    unsigned char *rsp);
     167             : static char (* DLSTDCALL CT_close) (unsigned short ctn);
     168             : 
     169             : /* PC/SC constants and function pointer. */
     170             : #define PCSC_SCOPE_USER      0
     171             : #define PCSC_SCOPE_TERMINAL  1
     172             : #define PCSC_SCOPE_SYSTEM    2
     173             : #define PCSC_SCOPE_GLOBAL    3
     174             : 
     175             : #define PCSC_PROTOCOL_T0     1
     176             : #define PCSC_PROTOCOL_T1     2
     177             : #ifdef HAVE_W32_SYSTEM
     178             : # define PCSC_PROTOCOL_RAW   0x00010000  /* The active protocol.  */
     179             : #else
     180             : # define PCSC_PROTOCOL_RAW   4
     181             : #endif
     182             : 
     183             : #define PCSC_SHARE_EXCLUSIVE 1
     184             : #define PCSC_SHARE_SHARED    2
     185             : #define PCSC_SHARE_DIRECT    3
     186             : 
     187             : #define PCSC_LEAVE_CARD      0
     188             : #define PCSC_RESET_CARD      1
     189             : #define PCSC_UNPOWER_CARD    2
     190             : #define PCSC_EJECT_CARD      3
     191             : 
     192             : #ifdef HAVE_W32_SYSTEM
     193             : # define PCSC_UNKNOWN    0x0000  /* The driver is not aware of the status.  */
     194             : # define PCSC_ABSENT     0x0001  /* Card is absent.  */
     195             : # define PCSC_PRESENT    0x0002  /* Card is present.  */
     196             : # define PCSC_SWALLOWED  0x0003  /* Card is present and electrical connected. */
     197             : # define PCSC_POWERED    0x0004  /* Card is powered.  */
     198             : # define PCSC_NEGOTIABLE 0x0005  /* Card is awaiting PTS.  */
     199             : # define PCSC_SPECIFIC   0x0006  /* Card is ready for use.  */
     200             : #else
     201             : # define PCSC_UNKNOWN    0x0001
     202             : # define PCSC_ABSENT     0x0002  /* Card is absent.  */
     203             : # define PCSC_PRESENT    0x0004  /* Card is present.  */
     204             : # define PCSC_SWALLOWED  0x0008  /* Card is present and electrical connected. */
     205             : # define PCSC_POWERED    0x0010  /* Card is powered.  */
     206             : # define PCSC_NEGOTIABLE 0x0020  /* Card is awaiting PTS.  */
     207             : # define PCSC_SPECIFIC   0x0040  /* Card is ready for use.  */
     208             : #endif
     209             : 
     210             : #define PCSC_STATE_UNAWARE     0x0000  /* Want status.  */
     211             : #define PCSC_STATE_IGNORE      0x0001  /* Ignore this reader.  */
     212             : #define PCSC_STATE_CHANGED     0x0002  /* State has changed.  */
     213             : #define PCSC_STATE_UNKNOWN     0x0004  /* Reader unknown.  */
     214             : #define PCSC_STATE_UNAVAILABLE 0x0008  /* Status unavailable.  */
     215             : #define PCSC_STATE_EMPTY       0x0010  /* Card removed.  */
     216             : #define PCSC_STATE_PRESENT     0x0020  /* Card inserted.  */
     217             : #define PCSC_STATE_ATRMATCH    0x0040  /* ATR matches card. */
     218             : #define PCSC_STATE_EXCLUSIVE   0x0080  /* Exclusive Mode.  */
     219             : #define PCSC_STATE_INUSE       0x0100  /* Shared mode.  */
     220             : #define PCSC_STATE_MUTE        0x0200  /* Unresponsive card.  */
     221             : #ifdef HAVE_W32_SYSTEM
     222             : # define PCSC_STATE_UNPOWERED  0x0400  /* Card not powerred up.  */
     223             : #endif
     224             : 
     225             : /* Some PC/SC error codes.  */
     226             : #define PCSC_E_CANCELLED               0x80100002
     227             : #define PCSC_E_CANT_DISPOSE            0x8010000E
     228             : #define PCSC_E_INSUFFICIENT_BUFFER     0x80100008
     229             : #define PCSC_E_INVALID_ATR             0x80100015
     230             : #define PCSC_E_INVALID_HANDLE          0x80100003
     231             : #define PCSC_E_INVALID_PARAMETER       0x80100004
     232             : #define PCSC_E_INVALID_TARGET          0x80100005
     233             : #define PCSC_E_INVALID_VALUE           0x80100011
     234             : #define PCSC_E_NO_MEMORY               0x80100006
     235             : #define PCSC_E_UNKNOWN_READER          0x80100009
     236             : #define PCSC_E_TIMEOUT                 0x8010000A
     237             : #define PCSC_E_SHARING_VIOLATION       0x8010000B
     238             : #define PCSC_E_NO_SMARTCARD            0x8010000C
     239             : #define PCSC_E_UNKNOWN_CARD            0x8010000D
     240             : #define PCSC_E_PROTO_MISMATCH          0x8010000F
     241             : #define PCSC_E_NOT_READY               0x80100010
     242             : #define PCSC_E_SYSTEM_CANCELLED        0x80100012
     243             : #define PCSC_E_NOT_TRANSACTED          0x80100016
     244             : #define PCSC_E_READER_UNAVAILABLE      0x80100017
     245             : #define PCSC_E_NO_SERVICE              0x8010001D
     246             : #define PCSC_E_SERVICE_STOPPED         0x8010001E
     247             : #define PCSC_W_REMOVED_CARD            0x80100069
     248             : 
     249             : /* Fix pcsc-lite ABI incompatibilty.  */
     250             : #ifndef SCARD_CTL_CODE
     251             : #ifdef _WIN32
     252             : #include <winioctl.h>
     253             : #define SCARD_CTL_CODE(code) CTL_CODE(FILE_DEVICE_SMARTCARD, (code), \
     254             :                                       METHOD_BUFFERED, FILE_ANY_ACCESS)
     255             : #else
     256             : #define SCARD_CTL_CODE(code) (0x42000000 + (code))
     257             : #endif
     258             : #endif
     259             : 
     260             : #define CM_IOCTL_GET_FEATURE_REQUEST     SCARD_CTL_CODE(3400)
     261             : #define CM_IOCTL_VENDOR_IFD_EXCHANGE     SCARD_CTL_CODE(1)
     262             : #define FEATURE_VERIFY_PIN_DIRECT        0x06
     263             : #define FEATURE_MODIFY_PIN_DIRECT        0x07
     264             : #define FEATURE_GET_TLV_PROPERTIES       0x12
     265             : 
     266             : #define PCSCv2_PART10_PROPERTY_bEntryValidationCondition 2
     267             : #define PCSCv2_PART10_PROPERTY_bTimeOut2                 3
     268             : #define PCSCv2_PART10_PROPERTY_bMinPINSize               6
     269             : #define PCSCv2_PART10_PROPERTY_bMaxPINSize               7
     270             : #define PCSCv2_PART10_PROPERTY_wIdVendor                11
     271             : #define PCSCv2_PART10_PROPERTY_wIdProduct               12
     272             : 
     273             : 
     274             : /* The PC/SC error is defined as a long as per specs.  Due to left
     275             :    shifts bit 31 will get sign extended.  We use this mask to fix
     276             :    it. */
     277             : #define PCSC_ERR_MASK(a)  ((a) & 0xffffffff)
     278             : 
     279             : 
     280             : struct pcsc_io_request_s
     281             : {
     282             :   unsigned long protocol;
     283             :   unsigned long pci_len;
     284             : };
     285             : 
     286             : typedef struct pcsc_io_request_s *pcsc_io_request_t;
     287             : 
     288             : #ifdef __APPLE__
     289             : #pragma pack(1)
     290             : #endif
     291             : 
     292             : struct pcsc_readerstate_s
     293             : {
     294             :   const char *reader;
     295             :   void *user_data;
     296             :   pcsc_dword_t current_state;
     297             :   pcsc_dword_t event_state;
     298             :   pcsc_dword_t atrlen;
     299             :   unsigned char atr[33];
     300             : };
     301             : 
     302             : #ifdef __APPLE__
     303             : #pragma pack()
     304             : #endif
     305             : 
     306             : typedef struct pcsc_readerstate_s *pcsc_readerstate_t;
     307             : 
     308             : long (* DLSTDCALL pcsc_establish_context) (pcsc_dword_t scope,
     309             :                                            const void *reserved1,
     310             :                                            const void *reserved2,
     311             :                                            long *r_context);
     312             : long (* DLSTDCALL pcsc_release_context) (long context);
     313             : long (* DLSTDCALL pcsc_list_readers) (long context,
     314             :                                       const char *groups,
     315             :                                       char *readers, pcsc_dword_t*readerslen);
     316             : long (* DLSTDCALL pcsc_get_status_change) (long context,
     317             :                                            pcsc_dword_t timeout,
     318             :                                            pcsc_readerstate_t readerstates,
     319             :                                            pcsc_dword_t nreaderstates);
     320             : long (* DLSTDCALL pcsc_connect) (long context,
     321             :                                  const char *reader,
     322             :                                  pcsc_dword_t share_mode,
     323             :                                  pcsc_dword_t preferred_protocols,
     324             :                                  long *r_card,
     325             :                                  pcsc_dword_t *r_active_protocol);
     326             : long (* DLSTDCALL pcsc_reconnect) (long card,
     327             :                                    pcsc_dword_t share_mode,
     328             :                                    pcsc_dword_t preferred_protocols,
     329             :                                    pcsc_dword_t initialization,
     330             :                                    pcsc_dword_t *r_active_protocol);
     331             : long (* DLSTDCALL pcsc_disconnect) (long card,
     332             :                                     pcsc_dword_t disposition);
     333             : long (* DLSTDCALL pcsc_status) (long card,
     334             :                                 char *reader, pcsc_dword_t *readerlen,
     335             :                                 pcsc_dword_t *r_state,
     336             :                                 pcsc_dword_t *r_protocol,
     337             :                                 unsigned char *atr, pcsc_dword_t *atrlen);
     338             : long (* DLSTDCALL pcsc_begin_transaction) (long card);
     339             : long (* DLSTDCALL pcsc_end_transaction) (long card,
     340             :                                          pcsc_dword_t disposition);
     341             : long (* DLSTDCALL pcsc_transmit) (long card,
     342             :                                   const pcsc_io_request_t send_pci,
     343             :                                   const unsigned char *send_buffer,
     344             :                                   pcsc_dword_t send_len,
     345             :                                   pcsc_io_request_t recv_pci,
     346             :                                   unsigned char *recv_buffer,
     347             :                                   pcsc_dword_t *recv_len);
     348             : long (* DLSTDCALL pcsc_set_timeout) (long context,
     349             :                                      pcsc_dword_t timeout);
     350             : long (* DLSTDCALL pcsc_control) (long card,
     351             :                                  pcsc_dword_t control_code,
     352             :                                  const void *send_buffer,
     353             :                                  pcsc_dword_t send_len,
     354             :                                  void *recv_buffer,
     355             :                                  pcsc_dword_t recv_len,
     356             :                                  pcsc_dword_t *bytes_returned);
     357             : 
     358             : 
     359             : /*  Prototypes.  */
     360             : static int pcsc_vendor_specific_init (int slot);
     361             : static int pcsc_get_status (int slot, unsigned int *status);
     362             : static int reset_pcsc_reader (int slot);
     363             : static int apdu_get_status_internal (int slot, int hang, int no_atr_reset,
     364             :                                      unsigned int *status,
     365             :                                      unsigned int *changed);
     366             : static int check_pcsc_pinpad (int slot, int command, pininfo_t *pininfo);
     367             : static int pcsc_pinpad_verify (int slot, int class, int ins, int p0, int p1,
     368             :                                pininfo_t *pininfo);
     369             : static int pcsc_pinpad_modify (int slot, int class, int ins, int p0, int p1,
     370             :                                pininfo_t *pininfo);
     371             : 
     372             : 
     373             : 
     374             : /*
     375             :       Helper
     376             :  */
     377             : 
     378             : static int
     379           0 : lock_slot (int slot)
     380             : {
     381             : #ifdef USE_NPTH
     382             :   int err;
     383             : 
     384           0 :   err = npth_mutex_lock (&reader_table[slot].lock);
     385           0 :   if (err)
     386             :     {
     387           0 :       log_error ("failed to acquire apdu lock: %s\n", strerror (err));
     388           0 :       return SW_HOST_LOCKING_FAILED;
     389             :     }
     390             : #endif /*USE_NPTH*/
     391           0 :   return 0;
     392             : }
     393             : 
     394             : static int
     395           0 : trylock_slot (int slot)
     396             : {
     397             : #ifdef USE_NPTH
     398             :   int err;
     399             : 
     400           0 :   err = npth_mutex_trylock (&reader_table[slot].lock);
     401           0 :   if (err == EBUSY)
     402           0 :     return SW_HOST_BUSY;
     403           0 :   else if (err)
     404             :     {
     405           0 :       log_error ("failed to acquire apdu lock: %s\n", strerror (err));
     406           0 :       return SW_HOST_LOCKING_FAILED;
     407             :     }
     408             : #endif /*USE_NPTH*/
     409           0 :   return 0;
     410             : }
     411             : 
     412             : static void
     413           0 : unlock_slot (int slot)
     414             : {
     415             : #ifdef USE_NPTH
     416             :   int err;
     417             : 
     418           0 :   err = npth_mutex_unlock (&reader_table[slot].lock);
     419           0 :   if (err)
     420           0 :     log_error ("failed to release apdu lock: %s\n", strerror (errno));
     421             : #endif /*USE_NPTH*/
     422           0 : }
     423             : 
     424             : 
     425             : /* Find an unused reader slot for PORTSTR and put it into the reader
     426             :    table.  Return -1 on error or the index into the reader table.
     427             :    Acquire slot's lock on successful return.  Caller needs to unlock it.  */
     428             : static int
     429           0 : new_reader_slot (void)
     430             : {
     431           0 :   int i, reader = -1;
     432             :   int err;
     433             : 
     434           0 :   for (i=0; i < MAX_READER; i++)
     435             :     {
     436           0 :       if (!reader_table[i].used && reader == -1)
     437           0 :         reader = i;
     438             :     }
     439           0 :   if (reader == -1)
     440             :     {
     441           0 :       log_error ("new_reader_slot: out of slots\n");
     442           0 :       return -1;
     443             :     }
     444             : #ifdef USE_NPTH
     445           0 :   if (!reader_table[reader].lock_initialized)
     446             :     {
     447           0 :       err = npth_mutex_init (&reader_table[reader].lock, NULL);
     448           0 :       if (err)
     449             :         {
     450           0 :           log_error ("error initializing mutex: %s\n", strerror (err));
     451           0 :           return -1;
     452             :         }
     453           0 :       reader_table[reader].lock_initialized = 1;
     454             :     }
     455             : #endif /*USE_NPTH*/
     456           0 :   if (lock_slot (reader))
     457             :     {
     458           0 :       log_error ("error locking mutex: %s\n", strerror (errno));
     459           0 :       return -1;
     460             :     }
     461           0 :   reader_table[reader].connect_card = NULL;
     462           0 :   reader_table[reader].disconnect_card = NULL;
     463           0 :   reader_table[reader].close_reader = NULL;
     464           0 :   reader_table[reader].reset_reader = NULL;
     465           0 :   reader_table[reader].get_status_reader = NULL;
     466           0 :   reader_table[reader].send_apdu_reader = NULL;
     467           0 :   reader_table[reader].check_pinpad = check_pcsc_pinpad;
     468           0 :   reader_table[reader].dump_status_reader = NULL;
     469           0 :   reader_table[reader].set_progress_cb = NULL;
     470           0 :   reader_table[reader].pinpad_verify = pcsc_pinpad_verify;
     471           0 :   reader_table[reader].pinpad_modify = pcsc_pinpad_modify;
     472             : 
     473           0 :   reader_table[reader].used = 1;
     474           0 :   reader_table[reader].any_status = 0;
     475           0 :   reader_table[reader].last_status = 0;
     476           0 :   reader_table[reader].is_t0 = 1;
     477           0 :   reader_table[reader].is_spr532 = 0;
     478           0 :   reader_table[reader].pinpad_varlen_supported = 0;
     479             : #ifdef NEED_PCSC_WRAPPER
     480             :   reader_table[reader].pcsc.req_fd = -1;
     481             :   reader_table[reader].pcsc.rsp_fd = -1;
     482             :   reader_table[reader].pcsc.pid = (pid_t)(-1);
     483             : #endif
     484           0 :   reader_table[reader].pcsc.verify_ioctl = 0;
     485           0 :   reader_table[reader].pcsc.modify_ioctl = 0;
     486           0 :   reader_table[reader].pcsc.pinmin = -1;
     487           0 :   reader_table[reader].pcsc.pinmax = -1;
     488             : 
     489           0 :   return reader;
     490             : }
     491             : 
     492             : 
     493             : static void
     494           0 : dump_reader_status (int slot)
     495             : {
     496           0 :   if (!opt.verbose)
     497           0 :     return;
     498             : 
     499           0 :   if (reader_table[slot].dump_status_reader)
     500           0 :     reader_table[slot].dump_status_reader (slot);
     501             : 
     502           0 :   if (reader_table[slot].status != -1
     503           0 :       && reader_table[slot].atrlen)
     504             :     {
     505           0 :       log_info ("slot %d: ATR=", slot);
     506           0 :       log_printhex ("", reader_table[slot].atr, reader_table[slot].atrlen);
     507             :     }
     508             : }
     509             : 
     510             : 
     511             : 
     512             : static const char *
     513           0 : host_sw_string (long err)
     514             : {
     515           0 :   switch (err)
     516             :     {
     517           0 :     case 0: return "okay";
     518           0 :     case SW_HOST_OUT_OF_CORE: return "out of core";
     519           0 :     case SW_HOST_INV_VALUE: return "invalid value";
     520           0 :     case SW_HOST_NO_DRIVER: return "no driver";
     521           0 :     case SW_HOST_NOT_SUPPORTED: return "not supported";
     522           0 :     case SW_HOST_LOCKING_FAILED: return "locking failed";
     523           0 :     case SW_HOST_BUSY: return "busy";
     524           0 :     case SW_HOST_NO_CARD: return "no card";
     525           0 :     case SW_HOST_CARD_INACTIVE: return "card inactive";
     526           0 :     case SW_HOST_CARD_IO_ERROR: return "card I/O error";
     527           0 :     case SW_HOST_GENERAL_ERROR: return "general error";
     528           0 :     case SW_HOST_NO_READER: return "no reader";
     529           0 :     case SW_HOST_ABORTED: return "aborted";
     530           0 :     case SW_HOST_NO_PINPAD: return "no pinpad";
     531           0 :     case SW_HOST_ALREADY_CONNECTED: return "already connected";
     532           0 :     default: return "unknown host status error";
     533             :     }
     534             : }
     535             : 
     536             : 
     537             : const char *
     538           0 : apdu_strerror (int rc)
     539             : {
     540           0 :   switch (rc)
     541             :     {
     542           0 :     case SW_EOF_REACHED    : return "eof reached";
     543           0 :     case SW_EEPROM_FAILURE : return "eeprom failure";
     544           0 :     case SW_WRONG_LENGTH   : return "wrong length";
     545           0 :     case SW_CHV_WRONG      : return "CHV wrong";
     546           0 :     case SW_CHV_BLOCKED    : return "CHV blocked";
     547           0 :     case SW_REF_DATA_INV   : return "referenced data invalidated";
     548           0 :     case SW_USE_CONDITIONS : return "use conditions not satisfied";
     549           0 :     case SW_BAD_PARAMETER  : return "bad parameter";
     550           0 :     case SW_NOT_SUPPORTED  : return "not supported";
     551           0 :     case SW_FILE_NOT_FOUND : return "file not found";
     552           0 :     case SW_RECORD_NOT_FOUND:return "record not found";
     553           0 :     case SW_REF_NOT_FOUND  : return "reference not found";
     554           0 :     case SW_NOT_ENOUGH_MEMORY: return "not enough memory space in the file";
     555           0 :     case SW_INCONSISTENT_LC: return "Lc inconsistent with TLV structure.";
     556           0 :     case SW_INCORRECT_P0_P1: return "incorrect parameters P0,P1";
     557           0 :     case SW_BAD_LC         : return "Lc inconsistent with P0,P1";
     558           0 :     case SW_BAD_P0_P1      : return "bad P0,P1";
     559           0 :     case SW_INS_NOT_SUP    : return "instruction not supported";
     560           0 :     case SW_CLA_NOT_SUP    : return "class not supported";
     561           0 :     case SW_SUCCESS        : return "success";
     562             :     default:
     563           0 :       if ((rc & ~0x00ff) == SW_MORE_DATA)
     564           0 :         return "more data available";
     565           0 :       if ( (rc & 0x10000) )
     566           0 :         return host_sw_string (rc);
     567           0 :       return "unknown status error";
     568             :     }
     569             : }
     570             : 
     571             : 
     572             : 
     573             : /*
     574             :        ct API Interface
     575             :  */
     576             : 
     577             : static const char *
     578           0 : ct_error_string (long err)
     579             : {
     580           0 :   switch (err)
     581             :     {
     582           0 :     case 0: return "okay";
     583           0 :     case -1: return "invalid data";
     584           0 :     case -8: return "ct error";
     585           0 :     case -10: return "transmission error";
     586           0 :     case -11: return "memory allocation error";
     587           0 :     case -128: return "HTSI error";
     588           0 :     default: return "unknown CT-API error";
     589             :     }
     590             : }
     591             : 
     592             : 
     593             : static void
     594           0 : ct_dump_reader_status (int slot)
     595             : {
     596           0 :   log_info ("reader slot %d: %s\n", slot,
     597           0 :             reader_table[slot].status == 1? "Processor ICC present" :
     598           0 :             reader_table[slot].status == 0? "Memory ICC present" :
     599             :             "ICC not present" );
     600           0 : }
     601             : 
     602             : 
     603             : /* Wait for the card in SLOT and activate it.  Return a status word
     604             :    error or 0 on success. */
     605             : static int
     606           0 : ct_activate_card (int slot)
     607             : {
     608             :   int rc;
     609             :   unsigned char dad[1], sad[1], cmd[11], buf[256];
     610             :   unsigned short buflen;
     611             : 
     612             :   /* Check whether card has been inserted. */
     613           0 :   dad[0] = 1;     /* Destination address: CT. */
     614           0 :   sad[0] = 2;     /* Source address: Host. */
     615             : 
     616           0 :   cmd[0] = 0x20;  /* Class byte. */
     617           0 :   cmd[1] = 0x13;  /* Request status. */
     618           0 :   cmd[2] = 0x00;  /* From kernel. */
     619           0 :   cmd[3] = 0x80;  /* Return card's DO. */
     620           0 :   cmd[4] = 0x00;
     621             : 
     622           0 :   buflen = DIM(buf);
     623             : 
     624           0 :   rc = CT_data (slot, dad, sad, 5, cmd, &buflen, buf);
     625           0 :   if (rc || buflen < 2 || buf[buflen-2] != 0x90)
     626             :     {
     627           0 :       log_error ("ct_activate_card: can't get status of reader %d: %s\n",
     628             :                  slot, ct_error_string (rc));
     629           0 :       return SW_HOST_CARD_IO_ERROR;
     630             :     }
     631             : 
     632             :   /* Connected, now activate the card. */
     633           0 :   dad[0] = 1;    /* Destination address: CT. */
     634           0 :   sad[0] = 2;    /* Source address: Host. */
     635             : 
     636           0 :   cmd[0] = 0x20;  /* Class byte. */
     637           0 :   cmd[1] = 0x12;  /* Request ICC. */
     638           0 :   cmd[2] = 0x01;  /* From first interface. */
     639           0 :   cmd[3] = 0x01;  /* Return card's ATR. */
     640           0 :   cmd[4] = 0x00;
     641             : 
     642           0 :   buflen = DIM(buf);
     643             : 
     644           0 :   rc = CT_data (slot, dad, sad, 5, cmd, &buflen, buf);
     645           0 :   if (rc || buflen < 2 || buf[buflen-2] != 0x90)
     646             :     {
     647           0 :       log_error ("ct_activate_card(%d): activation failed: %s\n",
     648             :                  slot, ct_error_string (rc));
     649           0 :       if (!rc)
     650           0 :         log_printhex ("  received data:", buf, buflen);
     651           0 :       return SW_HOST_CARD_IO_ERROR;
     652             :     }
     653             : 
     654             :   /* Store the type and the ATR. */
     655           0 :   if (buflen - 2 > DIM (reader_table[0].atr))
     656             :     {
     657           0 :       log_error ("ct_activate_card(%d): ATR too long\n", slot);
     658           0 :       return SW_HOST_CARD_IO_ERROR;
     659             :     }
     660             : 
     661           0 :   reader_table[slot].status = buf[buflen - 1];
     662           0 :   memcpy (reader_table[slot].atr, buf, buflen - 2);
     663           0 :   reader_table[slot].atrlen = buflen - 2;
     664           0 :   return 0;
     665             : }
     666             : 
     667             : 
     668             : static int
     669           0 : close_ct_reader (int slot)
     670             : {
     671           0 :   CT_close (slot);
     672           0 :   reader_table[slot].used = 0;
     673           0 :   return 0;
     674             : }
     675             : 
     676             : static int
     677           0 : reset_ct_reader (int slot)
     678             : {
     679             :   /* FIXME: Check is this is sufficient do do a reset. */
     680           0 :   return ct_activate_card (slot);
     681             : }
     682             : 
     683             : 
     684             : static int
     685           0 : ct_get_status (int slot, unsigned int *status)
     686             : {
     687             :   (void)slot;
     688             :   /* The status we returned is wrong but we don't care because ctAPI
     689             :      is not anymore required.  */
     690           0 :   *status = APDU_CARD_USABLE|APDU_CARD_PRESENT|APDU_CARD_ACTIVE;
     691           0 :   return 0;
     692             : }
     693             : 
     694             : /* Actually send the APDU of length APDULEN to SLOT and return a
     695             :    maximum of *BUFLEN data in BUFFER, the actual retruned size will be
     696             :    set to BUFLEN.  Returns: CT API error code. */
     697             : static int
     698           0 : ct_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
     699             :               unsigned char *buffer, size_t *buflen, pininfo_t *pininfo)
     700             : {
     701             :   int rc;
     702             :   unsigned char dad[1], sad[1];
     703             :   unsigned short ctbuflen;
     704             : 
     705             :   (void)pininfo;
     706             : 
     707             :   /* If we don't have an ATR, we need to reset the reader first. */
     708           0 :   if (!reader_table[slot].atrlen
     709           0 :       && (rc = reset_ct_reader (slot)))
     710           0 :     return rc;
     711             : 
     712           0 :   dad[0] = 0;     /* Destination address: Card. */
     713           0 :   sad[0] = 2;     /* Source address: Host. */
     714           0 :   ctbuflen = *buflen;
     715           0 :   if (DBG_CARD_IO)
     716           0 :     log_printhex ("  CT_data:", apdu, apdulen);
     717           0 :   rc = CT_data (slot, dad, sad, apdulen, apdu, &ctbuflen, buffer);
     718           0 :   *buflen = ctbuflen;
     719             : 
     720           0 :   return rc? SW_HOST_CARD_IO_ERROR: 0;
     721             : }
     722             : 
     723             : 
     724             : 
     725             : /* Open a reader and return an internal handle for it.  PORT is a
     726             :    non-negative value with the port number of the reader. USB readers
     727             :    do have port numbers starting at 32769. */
     728             : static int
     729           0 : open_ct_reader (int port)
     730             : {
     731             :   int rc, reader;
     732             : 
     733           0 :   if (port < 0 || port > 0xffff)
     734             :     {
     735           0 :       log_error ("open_ct_reader: invalid port %d requested\n", port);
     736           0 :       return -1;
     737             :     }
     738           0 :   reader = new_reader_slot ();
     739           0 :   if (reader == -1)
     740           0 :     return reader;
     741           0 :   reader_table[reader].port = port;
     742             : 
     743           0 :   rc = CT_init (reader, (unsigned short)port);
     744           0 :   if (rc)
     745             :     {
     746           0 :       log_error ("apdu_open_ct_reader failed on port %d: %s\n",
     747             :                  port, ct_error_string (rc));
     748           0 :       reader_table[reader].used = 0;
     749           0 :       unlock_slot (reader);
     750           0 :       return -1;
     751             :     }
     752             : 
     753             :   /* Only try to activate the card. */
     754           0 :   rc = ct_activate_card (reader);
     755           0 :   if (rc)
     756             :     {
     757           0 :       reader_table[reader].atrlen = 0;
     758           0 :       rc = 0;
     759             :     }
     760             : 
     761           0 :   reader_table[reader].close_reader = close_ct_reader;
     762           0 :   reader_table[reader].reset_reader = reset_ct_reader;
     763           0 :   reader_table[reader].get_status_reader = ct_get_status;
     764           0 :   reader_table[reader].send_apdu_reader = ct_send_apdu;
     765           0 :   reader_table[reader].check_pinpad = NULL;
     766           0 :   reader_table[reader].dump_status_reader = ct_dump_reader_status;
     767           0 :   reader_table[reader].pinpad_verify = NULL;
     768           0 :   reader_table[reader].pinpad_modify = NULL;
     769             : 
     770           0 :   dump_reader_status (reader);
     771           0 :   unlock_slot (reader);
     772           0 :   return reader;
     773             : }
     774             : 
     775             : 
     776             : /*
     777             :        PC/SC Interface
     778             :  */
     779             : 
     780             : #ifdef NEED_PCSC_WRAPPER
     781             : static int
     782             : writen (int fd, const void *buf, size_t nbytes)
     783             : {
     784             :   size_t nleft = nbytes;
     785             :   int nwritten;
     786             : 
     787             : /*   log_printhex (" writen:", buf, nbytes); */
     788             : 
     789             :   while (nleft > 0)
     790             :     {
     791             : #ifdef USE_NPTH
     792             :       nwritten = npth_write (fd, buf, nleft);
     793             : #else
     794             :       nwritten = write (fd, buf, nleft);
     795             : #endif
     796             :       if (nwritten < 0 && errno == EINTR)
     797             :         continue;
     798             :       if (nwritten < 0)
     799             :         return -1;
     800             :       nleft -= nwritten;
     801             :       buf = (const char*)buf + nwritten;
     802             :     }
     803             :   return 0;
     804             : }
     805             : 
     806             : /* Read up to BUFLEN bytes from FD and return the number of bytes
     807             :    actually read in NREAD.  Returns -1 on error or 0 on success. */
     808             : static int
     809             : readn (int fd, void *buf, size_t buflen, size_t *nread)
     810             : {
     811             :   size_t nleft = buflen;
     812             :   int n;
     813             : /*   void *orig_buf = buf; */
     814             : 
     815             :   while (nleft > 0)
     816             :     {
     817             : #ifdef USE_NPTH
     818             : # ifdef HAVE_W32_SYSTEM
     819             : #  error Cannot use npth_read here because it expects a system HANDLE.
     820             : # endif
     821             :       n = npth_read (fd, buf, nleft);
     822             : #else
     823             :       n = read (fd, buf, nleft);
     824             : #endif
     825             :       if (n < 0 && errno == EINTR)
     826             :         continue;
     827             :       if (n < 0)
     828             :         return -1; /* read error. */
     829             :       if (!n)
     830             :         break; /* EOF */
     831             :       nleft -= n;
     832             :       buf = (char*)buf + n;
     833             :     }
     834             :   if (nread)
     835             :     *nread = buflen - nleft;
     836             : 
     837             : /*   log_printhex ("  readn:", orig_buf, *nread); */
     838             : 
     839             :   return 0;
     840             : }
     841             : #endif /*NEED_PCSC_WRAPPER*/
     842             : 
     843             : static const char *
     844           0 : pcsc_error_string (long err)
     845             : {
     846             :   const char *s;
     847             : 
     848           0 :   if (!err)
     849           0 :     return "okay";
     850           0 :   if ((err & 0x80100000) != 0x80100000)
     851           0 :     return "invalid PC/SC error code";
     852           0 :   err &= 0xffff;
     853           0 :   switch (err)
     854             :     {
     855           0 :     case 0x0002: s = "cancelled"; break;
     856           0 :     case 0x000e: s = "can't dispose"; break;
     857           0 :     case 0x0008: s = "insufficient buffer"; break;
     858           0 :     case 0x0015: s = "invalid ATR"; break;
     859           0 :     case 0x0003: s = "invalid handle"; break;
     860           0 :     case 0x0004: s = "invalid parameter"; break;
     861           0 :     case 0x0005: s = "invalid target"; break;
     862           0 :     case 0x0011: s = "invalid value"; break;
     863           0 :     case 0x0006: s = "no memory"; break;
     864           0 :     case 0x0013: s = "comm error"; break;
     865           0 :     case 0x0001: s = "internal error"; break;
     866           0 :     case 0x0014: s = "unknown error"; break;
     867           0 :     case 0x0007: s = "waited too long"; break;
     868           0 :     case 0x0009: s = "unknown reader"; break;
     869           0 :     case 0x000a: s = "timeout"; break;
     870           0 :     case 0x000b: s = "sharing violation"; break;
     871           0 :     case 0x000c: s = "no smartcard"; break;
     872           0 :     case 0x000d: s = "unknown card"; break;
     873           0 :     case 0x000f: s = "proto mismatch"; break;
     874           0 :     case 0x0010: s = "not ready"; break;
     875           0 :     case 0x0012: s = "system cancelled"; break;
     876           0 :     case 0x0016: s = "not transacted"; break;
     877           0 :     case 0x0017: s = "reader unavailable"; break;
     878           0 :     case 0x0065: s = "unsupported card"; break;
     879           0 :     case 0x0066: s = "unresponsive card"; break;
     880           0 :     case 0x0067: s = "unpowered card"; break;
     881           0 :     case 0x0068: s = "reset card"; break;
     882           0 :     case 0x0069: s = "removed card"; break;
     883           0 :     case 0x006a: s = "inserted card"; break;
     884           0 :     case 0x001f: s = "unsupported feature"; break;
     885           0 :     case 0x0019: s = "PCI too small"; break;
     886           0 :     case 0x001a: s = "reader unsupported"; break;
     887           0 :     case 0x001b: s = "duplicate reader"; break;
     888           0 :     case 0x001c: s = "card unsupported"; break;
     889           0 :     case 0x001d: s = "no service"; break;
     890           0 :     case 0x001e: s = "service stopped"; break;
     891           0 :     default:     s = "unknown PC/SC error code"; break;
     892             :     }
     893           0 :   return s;
     894             : }
     895             : 
     896             : /* Map PC/SC error codes to our special host status words.  */
     897             : static int
     898           0 : pcsc_error_to_sw (long ec)
     899             : {
     900             :   int rc;
     901             : 
     902           0 :   switch ( PCSC_ERR_MASK (ec) )
     903             :     {
     904           0 :     case 0:  rc = 0; break;
     905             : 
     906           0 :     case PCSC_E_CANCELLED:           rc = SW_HOST_ABORTED; break;
     907           0 :     case PCSC_E_NO_MEMORY:           rc = SW_HOST_OUT_OF_CORE; break;
     908           0 :     case PCSC_E_TIMEOUT:             rc = SW_HOST_CARD_IO_ERROR; break;
     909             :     case PCSC_E_NO_SERVICE:
     910             :     case PCSC_E_SERVICE_STOPPED:
     911           0 :     case PCSC_E_UNKNOWN_READER:      rc = SW_HOST_NO_READER; break;
     912           0 :     case PCSC_E_SHARING_VIOLATION:   rc = SW_HOST_LOCKING_FAILED; break;
     913           0 :     case PCSC_E_NO_SMARTCARD:        rc = SW_HOST_NO_CARD; break;
     914           0 :     case PCSC_W_REMOVED_CARD:        rc = SW_HOST_NO_CARD; break;
     915             : 
     916             :     case PCSC_E_INVALID_TARGET:
     917             :     case PCSC_E_INVALID_VALUE:
     918             :     case PCSC_E_INVALID_HANDLE:
     919             :     case PCSC_E_INVALID_PARAMETER:
     920           0 :     case PCSC_E_INSUFFICIENT_BUFFER: rc = SW_HOST_INV_VALUE; break;
     921             : 
     922           0 :     default:  rc = SW_HOST_GENERAL_ERROR; break;
     923             :     }
     924             : 
     925           0 :   return rc;
     926             : }
     927             : 
     928             : static void
     929           0 : dump_pcsc_reader_status (int slot)
     930             : {
     931           0 :   if (reader_table[slot].pcsc.card)
     932             :     {
     933           0 :       log_info ("reader slot %d: active protocol:", slot);
     934           0 :       if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_T0))
     935           0 :         log_printf (" T0");
     936           0 :       else if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_T1))
     937           0 :         log_printf (" T1");
     938           0 :       else if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_RAW))
     939           0 :         log_printf (" raw");
     940           0 :       log_printf ("\n");
     941             :     }
     942             :   else
     943           0 :     log_info ("reader slot %d: not connected\n", slot);
     944           0 : }
     945             : 
     946             : 
     947             : #ifndef NEED_PCSC_WRAPPER
     948             : static int
     949           0 : pcsc_get_status_direct (int slot, unsigned int *status)
     950             : {
     951             :   long err;
     952             :   struct pcsc_readerstate_s rdrstates[1];
     953             : 
     954           0 :   memset (rdrstates, 0, sizeof *rdrstates);
     955           0 :   rdrstates[0].reader = reader_table[slot].rdrname;
     956           0 :   rdrstates[0].current_state = PCSC_STATE_UNAWARE;
     957           0 :   err = pcsc_get_status_change (reader_table[slot].pcsc.context,
     958             :                                 0,
     959             :                                 rdrstates, 1);
     960           0 :   if (err == PCSC_E_TIMEOUT)
     961           0 :     err = 0; /* Timeout is no error error here. */
     962           0 :   if (err)
     963             :     {
     964           0 :       log_error ("pcsc_get_status_change failed: %s (0x%lx)\n",
     965             :                  pcsc_error_string (err), err);
     966           0 :       return pcsc_error_to_sw (err);
     967             :     }
     968             : 
     969             :   /*   log_debug  */
     970             :   /*     ("pcsc_get_status_change: %s%s%s%s%s%s%s%s%s%s\n", */
     971             :   /*      (rdrstates[0].event_state & PCSC_STATE_IGNORE)? " ignore":"", */
     972             :   /*      (rdrstates[0].event_state & PCSC_STATE_CHANGED)? " changed":"", */
     973             :   /*      (rdrstates[0].event_state & PCSC_STATE_UNKNOWN)? " unknown":"", */
     974             :   /*      (rdrstates[0].event_state & PCSC_STATE_UNAVAILABLE)?" unavail":"", */
     975             :   /*      (rdrstates[0].event_state & PCSC_STATE_EMPTY)? " empty":"", */
     976             :   /*      (rdrstates[0].event_state & PCSC_STATE_PRESENT)? " present":"", */
     977             :   /*      (rdrstates[0].event_state & PCSC_STATE_ATRMATCH)? " atr":"", */
     978             :   /*      (rdrstates[0].event_state & PCSC_STATE_EXCLUSIVE)? " excl":"", */
     979             :   /*      (rdrstates[0].event_state & PCSC_STATE_INUSE)? " unuse":"", */
     980             :   /*      (rdrstates[0].event_state & PCSC_STATE_MUTE)? " mute":"" ); */
     981             : 
     982           0 :   *status = 0;
     983           0 :   if ( (rdrstates[0].event_state & PCSC_STATE_PRESENT) )
     984             :     {
     985           0 :       *status |= APDU_CARD_PRESENT;
     986           0 :       if ( !(rdrstates[0].event_state & PCSC_STATE_MUTE) )
     987           0 :         *status |= APDU_CARD_ACTIVE;
     988             :     }
     989             : #ifndef HAVE_W32_SYSTEM
     990             :   /* We indicate a useful card if it is not in use by another
     991             :      application.  This is because we only use exclusive access
     992             :      mode.  */
     993           0 :   if ( (*status & (APDU_CARD_PRESENT|APDU_CARD_ACTIVE))
     994             :        == (APDU_CARD_PRESENT|APDU_CARD_ACTIVE)
     995           0 :        && !(rdrstates[0].event_state & PCSC_STATE_INUSE) )
     996           0 :     *status |= APDU_CARD_USABLE;
     997             : #else
     998             :   /* Some winscard drivers may set EXCLUSIVE and INUSE at the same
     999             :      time when we are the only user (SCM SCR335) under Windows.  */
    1000             :   if ((*status & (APDU_CARD_PRESENT|APDU_CARD_ACTIVE))
    1001             :       == (APDU_CARD_PRESENT|APDU_CARD_ACTIVE))
    1002             :     *status |= APDU_CARD_USABLE;
    1003             : #endif
    1004             : 
    1005           0 :   return 0;
    1006             : }
    1007             : #endif /*!NEED_PCSC_WRAPPER*/
    1008             : 
    1009             : 
    1010             : #ifdef NEED_PCSC_WRAPPER
    1011             : static int
    1012             : pcsc_get_status_wrapped (int slot, unsigned int *status)
    1013             : {
    1014             :   long err;
    1015             :   reader_table_t slotp;
    1016             :   size_t len, full_len;
    1017             :   int i, n;
    1018             :   unsigned char msgbuf[9];
    1019             :   unsigned char buffer[16];
    1020             :   int sw = SW_HOST_CARD_IO_ERROR;
    1021             : 
    1022             :   slotp = reader_table + slot;
    1023             : 
    1024             :   if (slotp->pcsc.req_fd == -1
    1025             :       || slotp->pcsc.rsp_fd == -1
    1026             :       || slotp->pcsc.pid == (pid_t)(-1) )
    1027             :     {
    1028             :       log_error ("pcsc_get_status: pcsc-wrapper not running\n");
    1029             :       return sw;
    1030             :     }
    1031             : 
    1032             :   msgbuf[0] = 0x04; /* STATUS command. */
    1033             :   len = 0;
    1034             :   msgbuf[1] = (len >> 24);
    1035             :   msgbuf[2] = (len >> 16);
    1036             :   msgbuf[3] = (len >>  8);
    1037             :   msgbuf[4] = (len      );
    1038             :   if ( writen (slotp->pcsc.req_fd, msgbuf, 5) )
    1039             :     {
    1040             :       log_error ("error sending PC/SC STATUS request: %s\n",
    1041             :                  strerror (errno));
    1042             :       goto command_failed;
    1043             :     }
    1044             : 
    1045             :   /* Read the response. */
    1046             :   if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9)
    1047             :     {
    1048             :       log_error ("error receiving PC/SC STATUS response: %s\n",
    1049             :                  i? strerror (errno) : "premature EOF");
    1050             :       goto command_failed;
    1051             :     }
    1052             :   len = buf_to_size_t (msgbuf+1);
    1053             :   if (msgbuf[0] != 0x81 || len < 4)
    1054             :     {
    1055             :       log_error ("invalid response header from PC/SC received\n");
    1056             :       goto command_failed;
    1057             :     }
    1058             :   len -= 4; /* Already read the error code. */
    1059             :   err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
    1060             :   if (err)
    1061             :     {
    1062             :       log_error ("pcsc_status failed: %s (0x%lx)\n",
    1063             :                  pcsc_error_string (err), err);
    1064             :       /* This is a proper error code, so return immediately.  */
    1065             :       return pcsc_error_to_sw (err);
    1066             :     }
    1067             : 
    1068             :   full_len = len;
    1069             : 
    1070             :   /* The current version returns 3 words but we allow also for old
    1071             :      versions returning only 2 words. */
    1072             :   n = 12 < len ? 12 : len;
    1073             :   if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len))
    1074             :       || (len != 8 && len != 12))
    1075             :     {
    1076             :       log_error ("error receiving PC/SC STATUS response: %s\n",
    1077             :                  i? strerror (errno) : "premature EOF");
    1078             :       goto command_failed;
    1079             :     }
    1080             : 
    1081             :   slotp->is_t0 = (len == 12 && !!(buffer[11] & PCSC_PROTOCOL_T0));
    1082             : 
    1083             : 
    1084             :   full_len -= len;
    1085             :   /* Newer versions of the wrapper might send more status bytes.
    1086             :      Read them. */
    1087             :   while (full_len)
    1088             :     {
    1089             :       unsigned char dummybuf[128];
    1090             : 
    1091             :       n = full_len < DIM (dummybuf) ? full_len : DIM (dummybuf);
    1092             :       if ((i=readn (slotp->pcsc.rsp_fd, dummybuf, n, &len)) || len != n)
    1093             :         {
    1094             :           log_error ("error receiving PC/SC TRANSMIT response: %s\n",
    1095             :                      i? strerror (errno) : "premature EOF");
    1096             :           goto command_failed;
    1097             :         }
    1098             :       full_len -= n;
    1099             :     }
    1100             : 
    1101             :   /* We are lucky: The wrapper already returns the data in the
    1102             :      required format. */
    1103             :   *status = buffer[3];
    1104             :   return 0;
    1105             : 
    1106             :  command_failed:
    1107             :   close (slotp->pcsc.req_fd);
    1108             :   close (slotp->pcsc.rsp_fd);
    1109             :   slotp->pcsc.req_fd = -1;
    1110             :   slotp->pcsc.rsp_fd = -1;
    1111             :   if (slotp->pcsc.pid != -1)
    1112             :     kill (slotp->pcsc.pid, SIGTERM);
    1113             :   slotp->pcsc.pid = (pid_t)(-1);
    1114             :   slotp->used = 0;
    1115             :   return sw;
    1116             : }
    1117             : #endif /*NEED_PCSC_WRAPPER*/
    1118             : 
    1119             : 
    1120             : static int
    1121           0 : pcsc_get_status (int slot, unsigned int *status)
    1122             : {
    1123             : #ifdef NEED_PCSC_WRAPPER
    1124             :   return pcsc_get_status_wrapped (slot, status);
    1125             : #else
    1126           0 :   return pcsc_get_status_direct (slot, status);
    1127             : #endif
    1128             : }
    1129             : 
    1130             : 
    1131             : #ifndef NEED_PCSC_WRAPPER
    1132             : static int
    1133           0 : pcsc_send_apdu_direct (int slot, unsigned char *apdu, size_t apdulen,
    1134             :                        unsigned char *buffer, size_t *buflen,
    1135             :                        pininfo_t *pininfo)
    1136             : {
    1137             :   long err;
    1138             :   struct pcsc_io_request_s send_pci;
    1139             :   pcsc_dword_t recv_len;
    1140             : 
    1141             :   (void)pininfo;
    1142             : 
    1143           0 :   if (!reader_table[slot].atrlen
    1144           0 :       && (err = reset_pcsc_reader (slot)))
    1145           0 :     return err;
    1146             : 
    1147           0 :   if (DBG_CARD_IO)
    1148           0 :     log_printhex ("  PCSC_data:", apdu, apdulen);
    1149             : 
    1150           0 :   if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_T1))
    1151           0 :       send_pci.protocol = PCSC_PROTOCOL_T1;
    1152             :   else
    1153           0 :       send_pci.protocol = PCSC_PROTOCOL_T0;
    1154           0 :   send_pci.pci_len = sizeof send_pci;
    1155           0 :   recv_len = *buflen;
    1156           0 :   err = pcsc_transmit (reader_table[slot].pcsc.card,
    1157             :                        &send_pci, apdu, apdulen,
    1158             :                        NULL, buffer, &recv_len);
    1159           0 :   *buflen = recv_len;
    1160           0 :   if (err)
    1161           0 :     log_error ("pcsc_transmit failed: %s (0x%lx)\n",
    1162             :                pcsc_error_string (err), err);
    1163             : 
    1164           0 :   return pcsc_error_to_sw (err);
    1165             : }
    1166             : #endif /*!NEED_PCSC_WRAPPER*/
    1167             : 
    1168             : 
    1169             : #ifdef NEED_PCSC_WRAPPER
    1170             : static int
    1171             : pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen,
    1172             :                         unsigned char *buffer, size_t *buflen,
    1173             :                         pininfo_t *pininfo)
    1174             : {
    1175             :   long err;
    1176             :   reader_table_t slotp;
    1177             :   size_t len, full_len;
    1178             :   int i, n;
    1179             :   unsigned char msgbuf[9];
    1180             :   int sw = SW_HOST_CARD_IO_ERROR;
    1181             : 
    1182             :   (void)pininfo;
    1183             : 
    1184             :   if (!reader_table[slot].atrlen
    1185             :       && (err = reset_pcsc_reader (slot)))
    1186             :     return err;
    1187             : 
    1188             :   if (DBG_CARD_IO)
    1189             :     log_printhex ("  PCSC_data:", apdu, apdulen);
    1190             : 
    1191             :   slotp = reader_table + slot;
    1192             : 
    1193             :   if (slotp->pcsc.req_fd == -1
    1194             :       || slotp->pcsc.rsp_fd == -1
    1195             :       || slotp->pcsc.pid == (pid_t)(-1) )
    1196             :     {
    1197             :       log_error ("pcsc_send_apdu: pcsc-wrapper not running\n");
    1198             :       return sw;
    1199             :     }
    1200             : 
    1201             :   msgbuf[0] = 0x03; /* TRANSMIT command. */
    1202             :   len = apdulen;
    1203             :   msgbuf[1] = (len >> 24);
    1204             :   msgbuf[2] = (len >> 16);
    1205             :   msgbuf[3] = (len >>  8);
    1206             :   msgbuf[4] = (len      );
    1207             :   if ( writen (slotp->pcsc.req_fd, msgbuf, 5)
    1208             :        || writen (slotp->pcsc.req_fd, apdu, len))
    1209             :     {
    1210             :       log_error ("error sending PC/SC TRANSMIT request: %s\n",
    1211             :                  strerror (errno));
    1212             :       goto command_failed;
    1213             :     }
    1214             : 
    1215             :   /* Read the response. */
    1216             :   if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9)
    1217             :     {
    1218             :       log_error ("error receiving PC/SC TRANSMIT response: %s\n",
    1219             :                  i? strerror (errno) : "premature EOF");
    1220             :       goto command_failed;
    1221             :     }
    1222             :   len = buf_to_size_t (msgbuf+1);
    1223             :   if (msgbuf[0] != 0x81 || len < 4)
    1224             :     {
    1225             :       log_error ("invalid response header from PC/SC received\n");
    1226             :       goto command_failed;
    1227             :     }
    1228             :   len -= 4; /* Already read the error code. */
    1229             :   err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
    1230             :   if (err)
    1231             :     {
    1232             :       log_error ("pcsc_transmit failed: %s (0x%lx)\n",
    1233             :                  pcsc_error_string (err), err);
    1234             :       return pcsc_error_to_sw (err);
    1235             :     }
    1236             : 
    1237             :    full_len = len;
    1238             : 
    1239             :    n = *buflen < len ? *buflen : len;
    1240             :    if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len)) || len != n)
    1241             :      {
    1242             :        log_error ("error receiving PC/SC TRANSMIT response: %s\n",
    1243             :                   i? strerror (errno) : "premature EOF");
    1244             :        goto command_failed;
    1245             :      }
    1246             :    *buflen = n;
    1247             : 
    1248             :    full_len -= len;
    1249             :    if (full_len)
    1250             :      {
    1251             :        log_error ("pcsc_send_apdu: provided buffer too short - truncated\n");
    1252             :        err = SW_HOST_INV_VALUE;
    1253             :      }
    1254             :    /* We need to read any rest of the response, to keep the
    1255             :       protocol running.  */
    1256             :    while (full_len)
    1257             :      {
    1258             :        unsigned char dummybuf[128];
    1259             : 
    1260             :        n = full_len < DIM (dummybuf) ? full_len : DIM (dummybuf);
    1261             :        if ((i=readn (slotp->pcsc.rsp_fd, dummybuf, n, &len)) || len != n)
    1262             :          {
    1263             :            log_error ("error receiving PC/SC TRANSMIT response: %s\n",
    1264             :                       i? strerror (errno) : "premature EOF");
    1265             :            goto command_failed;
    1266             :          }
    1267             :        full_len -= n;
    1268             :      }
    1269             : 
    1270             :    return err;
    1271             : 
    1272             :  command_failed:
    1273             :   close (slotp->pcsc.req_fd);
    1274             :   close (slotp->pcsc.rsp_fd);
    1275             :   slotp->pcsc.req_fd = -1;
    1276             :   slotp->pcsc.rsp_fd = -1;
    1277             :   if (slotp->pcsc.pid != -1)
    1278             :     kill (slotp->pcsc.pid, SIGTERM);
    1279             :   slotp->pcsc.pid = (pid_t)(-1);
    1280             :   slotp->used = 0;
    1281             :   return sw;
    1282             : }
    1283             : #endif /*NEED_PCSC_WRAPPER*/
    1284             : 
    1285             : 
    1286             : /* Send the APDU of length APDULEN to SLOT and return a maximum of
    1287             :    *BUFLEN data in BUFFER, the actual returned size will be stored at
    1288             :    BUFLEN.  Returns: A status word. */
    1289             : static int
    1290           0 : pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
    1291             :                 unsigned char *buffer, size_t *buflen,
    1292             :                 pininfo_t *pininfo)
    1293             : {
    1294             : #ifdef NEED_PCSC_WRAPPER
    1295             :   return pcsc_send_apdu_wrapped (slot, apdu, apdulen, buffer, buflen, pininfo);
    1296             : #else
    1297           0 :   return pcsc_send_apdu_direct (slot, apdu, apdulen, buffer, buflen, pininfo);
    1298             : #endif
    1299             : }
    1300             : 
    1301             : 
    1302             : #ifndef NEED_PCSC_WRAPPER
    1303             : static int
    1304           0 : control_pcsc_direct (int slot, pcsc_dword_t ioctl_code,
    1305             :                      const unsigned char *cntlbuf, size_t len,
    1306             :                      unsigned char *buffer, pcsc_dword_t *buflen)
    1307             : {
    1308             :   long err;
    1309             : 
    1310           0 :   err = pcsc_control (reader_table[slot].pcsc.card, ioctl_code,
    1311             :                       cntlbuf, len, buffer, buflen? *buflen:0, buflen);
    1312           0 :   if (err)
    1313             :     {
    1314           0 :       log_error ("pcsc_control failed: %s (0x%lx)\n",
    1315             :                  pcsc_error_string (err), err);
    1316           0 :       return pcsc_error_to_sw (err);
    1317             :     }
    1318             : 
    1319           0 :   return 0;
    1320             : }
    1321             : #endif /*!NEED_PCSC_WRAPPER*/
    1322             : 
    1323             : 
    1324             : #ifdef NEED_PCSC_WRAPPER
    1325             : static int
    1326             : control_pcsc_wrapped (int slot, pcsc_dword_t ioctl_code,
    1327             :                       const unsigned char *cntlbuf, size_t len,
    1328             :                       unsigned char *buffer, pcsc_dword_t *buflen)
    1329             : {
    1330             :   long err = PCSC_E_NOT_TRANSACTED;
    1331             :   reader_table_t slotp;
    1332             :   unsigned char msgbuf[9];
    1333             :   int i, n;
    1334             :   size_t full_len;
    1335             : 
    1336             :   slotp = reader_table + slot;
    1337             : 
    1338             :   msgbuf[0] = 0x06; /* CONTROL command. */
    1339             :   msgbuf[1] = ((len + 4) >> 24);
    1340             :   msgbuf[2] = ((len + 4) >> 16);
    1341             :   msgbuf[3] = ((len + 4) >>  8);
    1342             :   msgbuf[4] = ((len + 4)      );
    1343             :   msgbuf[5] = (ioctl_code >> 24);
    1344             :   msgbuf[6] = (ioctl_code >> 16);
    1345             :   msgbuf[7] = (ioctl_code >>  8);
    1346             :   msgbuf[8] = (ioctl_code      );
    1347             :   if ( writen (slotp->pcsc.req_fd, msgbuf, 9)
    1348             :        || writen (slotp->pcsc.req_fd, cntlbuf, len))
    1349             :     {
    1350             :       log_error ("error sending PC/SC CONTROL request: %s\n",
    1351             :                  strerror (errno));
    1352             :       goto command_failed;
    1353             :     }
    1354             : 
    1355             :   /* Read the response. */
    1356             :   if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9)
    1357             :     {
    1358             :       log_error ("error receiving PC/SC CONTROL response: %s\n",
    1359             :                  i? strerror (errno) : "premature EOF");
    1360             :       goto command_failed;
    1361             :     }
    1362             :   len = buf32_to_size_t (msgbuf+1);
    1363             :   if (msgbuf[0] != 0x81 || len < 4)
    1364             :     {
    1365             :       log_error ("invalid response header from PC/SC received\n");
    1366             :       goto command_failed;
    1367             :     }
    1368             :   len -= 4; /* Already read the error code. */
    1369             :   err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
    1370             :   if (err)
    1371             :     {
    1372             :       log_error ("pcsc_control failed: %s (0x%lx)\n",
    1373             :                  pcsc_error_string (err), err);
    1374             :       return pcsc_error_to_sw (err);
    1375             :     }
    1376             : 
    1377             :   full_len = len;
    1378             : 
    1379             :   if (buflen)
    1380             :     n = *buflen < len ? *buflen : len;
    1381             :   else
    1382             :     n = 0;
    1383             :   if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len)) || len != n)
    1384             :     {
    1385             :       log_error ("error receiving PC/SC CONTROL response: %s\n",
    1386             :                  i? strerror (errno) : "premature EOF");
    1387             :       goto command_failed;
    1388             :     }
    1389             :   if (buflen)
    1390             :     *buflen = n;
    1391             : 
    1392             :   full_len -= len;
    1393             :   if (full_len)
    1394             :     {
    1395             :       log_error ("pcsc_send_apdu: provided buffer too short - truncated\n");
    1396             :       err = PCSC_E_INVALID_VALUE;
    1397             :     }
    1398             :   /* We need to read any rest of the response, to keep the
    1399             :      protocol running.  */
    1400             :   while (full_len)
    1401             :     {
    1402             :       unsigned char dummybuf[128];
    1403             : 
    1404             :       n = full_len < DIM (dummybuf) ? full_len : DIM (dummybuf);
    1405             :       if ((i=readn (slotp->pcsc.rsp_fd, dummybuf, n, &len)) || len != n)
    1406             :         {
    1407             :           log_error ("error receiving PC/SC CONTROL response: %s\n",
    1408             :                      i? strerror (errno) : "premature EOF");
    1409             :           goto command_failed;
    1410             :         }
    1411             :       full_len -= n;
    1412             :     }
    1413             : 
    1414             :   if (!err)
    1415             :     return 0;
    1416             : 
    1417             :  command_failed:
    1418             :   close (slotp->pcsc.req_fd);
    1419             :   close (slotp->pcsc.rsp_fd);
    1420             :   slotp->pcsc.req_fd = -1;
    1421             :   slotp->pcsc.rsp_fd = -1;
    1422             :   if (slotp->pcsc.pid != -1)
    1423             :     kill (slotp->pcsc.pid, SIGTERM);
    1424             :   slotp->pcsc.pid = (pid_t)(-1);
    1425             :   slotp->used = 0;
    1426             :   return pcsc_error_to_sw (err);
    1427             : }
    1428             : #endif /*NEED_PCSC_WRAPPER*/
    1429             : 
    1430             : 
    1431             : 
    1432             : /* Do some control with the value of IOCTL_CODE to the card inserted
    1433             :    to SLOT.  Input buffer is specified by CNTLBUF of length LEN.
    1434             :    Output buffer is specified by BUFFER of length *BUFLEN, and the
    1435             :    actual output size will be stored at BUFLEN.  Returns: A status word.
    1436             :    This routine is used for PIN pad input support.  */
    1437             : static int
    1438           0 : control_pcsc (int slot, pcsc_dword_t ioctl_code,
    1439             :               const unsigned char *cntlbuf, size_t len,
    1440             :               unsigned char *buffer, pcsc_dword_t *buflen)
    1441             : {
    1442             : #ifdef NEED_PCSC_WRAPPER
    1443             :   return control_pcsc_wrapped (slot, ioctl_code, cntlbuf, len, buffer, buflen);
    1444             : #else
    1445           0 :   return control_pcsc_direct (slot, ioctl_code, cntlbuf, len, buffer, buflen);
    1446             : #endif
    1447             : }
    1448             : 
    1449             : 
    1450             : #ifndef NEED_PCSC_WRAPPER
    1451             : static int
    1452           0 : close_pcsc_reader_direct (int slot)
    1453             : {
    1454           0 :   pcsc_release_context (reader_table[slot].pcsc.context);
    1455           0 :   xfree (reader_table[slot].rdrname);
    1456           0 :   reader_table[slot].rdrname = NULL;
    1457           0 :   reader_table[slot].used = 0;
    1458           0 :   return 0;
    1459             : }
    1460             : #endif /*!NEED_PCSC_WRAPPER*/
    1461             : 
    1462             : 
    1463             : #ifdef NEED_PCSC_WRAPPER
    1464             : static int
    1465             : close_pcsc_reader_wrapped (int slot)
    1466             : {
    1467             :   long err;
    1468             :   reader_table_t slotp;
    1469             :   size_t len;
    1470             :   int i;
    1471             :   unsigned char msgbuf[9];
    1472             : 
    1473             :   slotp = reader_table + slot;
    1474             : 
    1475             :   if (slotp->pcsc.req_fd == -1
    1476             :       || slotp->pcsc.rsp_fd == -1
    1477             :       || slotp->pcsc.pid == (pid_t)(-1) )
    1478             :     {
    1479             :       log_error ("close_pcsc_reader: pcsc-wrapper not running\n");
    1480             :       return 0;
    1481             :     }
    1482             : 
    1483             :   msgbuf[0] = 0x02; /* CLOSE command. */
    1484             :   len = 0;
    1485             :   msgbuf[1] = (len >> 24);
    1486             :   msgbuf[2] = (len >> 16);
    1487             :   msgbuf[3] = (len >>  8);
    1488             :   msgbuf[4] = (len      );
    1489             :   if ( writen (slotp->pcsc.req_fd, msgbuf, 5) )
    1490             :     {
    1491             :       log_error ("error sending PC/SC CLOSE request: %s\n",
    1492             :                  strerror (errno));
    1493             :       goto command_failed;
    1494             :     }
    1495             : 
    1496             :   /* Read the response. */
    1497             :   if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9)
    1498             :     {
    1499             :       log_error ("error receiving PC/SC CLOSE response: %s\n",
    1500             :                  i? strerror (errno) : "premature EOF");
    1501             :       goto command_failed;
    1502             :     }
    1503             :   len = buf32_to_size_t (msgbuf+1);
    1504             :   if (msgbuf[0] != 0x81 || len < 4)
    1505             :     {
    1506             :       log_error ("invalid response header from PC/SC received\n");
    1507             :       goto command_failed;
    1508             :     }
    1509             :   len -= 4; /* Already read the error code. */
    1510             :   err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
    1511             :   if (err)
    1512             :     log_error ("pcsc_close failed: %s (0x%lx)\n",
    1513             :                pcsc_error_string (err), err);
    1514             : 
    1515             :   /* We will close the wrapper in any case - errors are merely
    1516             :      informational. */
    1517             : 
    1518             :  command_failed:
    1519             :   close (slotp->pcsc.req_fd);
    1520             :   close (slotp->pcsc.rsp_fd);
    1521             :   slotp->pcsc.req_fd = -1;
    1522             :   slotp->pcsc.rsp_fd = -1;
    1523             :   if (slotp->pcsc.pid != -1)
    1524             :     kill (slotp->pcsc.pid, SIGTERM);
    1525             :   slotp->pcsc.pid = (pid_t)(-1);
    1526             :   slotp->used = 0;
    1527             :   return 0;
    1528             : }
    1529             : #endif /*NEED_PCSC_WRAPPER*/
    1530             : 
    1531             : 
    1532             : static int
    1533           0 : close_pcsc_reader (int slot)
    1534             : {
    1535             : #ifdef NEED_PCSC_WRAPPER
    1536             :   return close_pcsc_reader_wrapped (slot);
    1537             : #else
    1538           0 :   return close_pcsc_reader_direct (slot);
    1539             : #endif
    1540             : }
    1541             : 
    1542             : 
    1543             : /* Connect a PC/SC card.  */
    1544             : #ifndef NEED_PCSC_WRAPPER
    1545             : static int
    1546           0 : connect_pcsc_card (int slot)
    1547             : {
    1548             :   long err;
    1549             : 
    1550           0 :   assert (slot >= 0 && slot < MAX_READER);
    1551             : 
    1552           0 :   if (reader_table[slot].pcsc.card)
    1553           0 :     return SW_HOST_ALREADY_CONNECTED;
    1554             : 
    1555           0 :   reader_table[slot].atrlen = 0;
    1556           0 :   reader_table[slot].last_status = 0;
    1557           0 :   reader_table[slot].is_t0 = 0;
    1558             : 
    1559           0 :   err = pcsc_connect (reader_table[slot].pcsc.context,
    1560           0 :                       reader_table[slot].rdrname,
    1561             :                       PCSC_SHARE_EXCLUSIVE,
    1562             :                       PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1,
    1563             :                       &reader_table[slot].pcsc.card,
    1564             :                       &reader_table[slot].pcsc.protocol);
    1565           0 :   if (err)
    1566             :     {
    1567           0 :       reader_table[slot].pcsc.card = 0;
    1568           0 :       if (err != PCSC_E_NO_SMARTCARD)
    1569           0 :         log_error ("pcsc_connect failed: %s (0x%lx)\n",
    1570             :                    pcsc_error_string (err), err);
    1571             :     }
    1572             :   else
    1573             :     {
    1574             :       char reader[250];
    1575             :       pcsc_dword_t readerlen, atrlen;
    1576             :       pcsc_dword_t card_state, card_protocol;
    1577             : 
    1578           0 :       pcsc_vendor_specific_init (slot);
    1579             : 
    1580           0 :       atrlen = DIM (reader_table[0].atr);
    1581           0 :       readerlen = sizeof reader -1 ;
    1582           0 :       err = pcsc_status (reader_table[slot].pcsc.card,
    1583             :                          reader, &readerlen,
    1584             :                          &card_state, &card_protocol,
    1585           0 :                          reader_table[slot].atr, &atrlen);
    1586           0 :       if (err)
    1587           0 :         log_error ("pcsc_status failed: %s (0x%lx) %lu\n",
    1588             :                    pcsc_error_string (err), err, (long unsigned int)readerlen);
    1589             :       else
    1590             :         {
    1591           0 :           if (atrlen > DIM (reader_table[0].atr))
    1592           0 :             log_bug ("ATR returned by pcsc_status is too large\n");
    1593           0 :           reader_table[slot].atrlen = atrlen;
    1594             :           /* If we got to here we know that a card is present
    1595             :              and usable.  Remember this.  */
    1596           0 :           reader_table[slot].last_status = (   APDU_CARD_USABLE
    1597             :                                              | APDU_CARD_PRESENT
    1598             :                                              | APDU_CARD_ACTIVE);
    1599           0 :           reader_table[slot].is_t0 = !!(card_protocol & PCSC_PROTOCOL_T0);
    1600             :         }
    1601             :     }
    1602             : 
    1603           0 :   dump_reader_status (slot);
    1604           0 :   return pcsc_error_to_sw (err);
    1605             : }
    1606             : #endif /*!NEED_PCSC_WRAPPER*/
    1607             : 
    1608             : 
    1609             : /* Disconnect a PC/SC card.  Note that this succeeds even if the card
    1610             :    is not connected.  */
    1611             : #ifndef NEED_PCSC_WRAPPER
    1612             : static int
    1613           0 : disconnect_pcsc_card (int slot)
    1614             : {
    1615             :   long err;
    1616             : 
    1617           0 :   assert (slot >= 0 && slot < MAX_READER);
    1618             : 
    1619           0 :   if (!reader_table[slot].pcsc.card)
    1620           0 :     return 0;
    1621             : 
    1622           0 :   err = pcsc_disconnect (reader_table[slot].pcsc.card, PCSC_LEAVE_CARD);
    1623           0 :   if (err)
    1624             :     {
    1625           0 :       log_error ("pcsc_disconnect failed: %s (0x%lx)\n",
    1626             :                  pcsc_error_string (err), err);
    1627           0 :       return SW_HOST_CARD_IO_ERROR;
    1628             :     }
    1629           0 :   reader_table[slot].pcsc.card = 0;
    1630           0 :   return 0;
    1631             : }
    1632             : #endif /*!NEED_PCSC_WRAPPER*/
    1633             : 
    1634             : 
    1635             : #ifndef NEED_PCSC_WRAPPER
    1636             : static int
    1637           0 : reset_pcsc_reader_direct (int slot)
    1638             : {
    1639             :   int sw;
    1640             : 
    1641           0 :   sw = disconnect_pcsc_card (slot);
    1642           0 :   if (!sw)
    1643           0 :     sw = connect_pcsc_card (slot);
    1644             : 
    1645           0 :   return sw;
    1646             : }
    1647             : #endif /*NEED_PCSC_WRAPPER*/
    1648             : 
    1649             : 
    1650             : #ifdef NEED_PCSC_WRAPPER
    1651             : static int
    1652             : reset_pcsc_reader_wrapped (int slot)
    1653             : {
    1654             :   long err;
    1655             :   reader_table_t slotp;
    1656             :   size_t len;
    1657             :   int i, n;
    1658             :   unsigned char msgbuf[9];
    1659             :   unsigned int dummy_status;
    1660             :   int sw = SW_HOST_CARD_IO_ERROR;
    1661             : 
    1662             :   slotp = reader_table + slot;
    1663             : 
    1664             :   if (slotp->pcsc.req_fd == -1
    1665             :       || slotp->pcsc.rsp_fd == -1
    1666             :       || slotp->pcsc.pid == (pid_t)(-1) )
    1667             :     {
    1668             :       log_error ("pcsc_get_status: pcsc-wrapper not running\n");
    1669             :       return sw;
    1670             :     }
    1671             : 
    1672             :   msgbuf[0] = 0x05; /* RESET command. */
    1673             :   len = 0;
    1674             :   msgbuf[1] = (len >> 24);
    1675             :   msgbuf[2] = (len >> 16);
    1676             :   msgbuf[3] = (len >>  8);
    1677             :   msgbuf[4] = (len      );
    1678             :   if ( writen (slotp->pcsc.req_fd, msgbuf, 5) )
    1679             :     {
    1680             :       log_error ("error sending PC/SC RESET request: %s\n",
    1681             :                  strerror (errno));
    1682             :       goto command_failed;
    1683             :     }
    1684             : 
    1685             :   /* Read the response. */
    1686             :   if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9)
    1687             :     {
    1688             :       log_error ("error receiving PC/SC RESET response: %s\n",
    1689             :                  i? strerror (errno) : "premature EOF");
    1690             :       goto command_failed;
    1691             :     }
    1692             :   len = buf32_to_size_t (msgbuf+1);
    1693             :   if (msgbuf[0] != 0x81 || len < 4)
    1694             :     {
    1695             :       log_error ("invalid response header from PC/SC received\n");
    1696             :       goto command_failed;
    1697             :     }
    1698             :   len -= 4; /* Already read the error code. */
    1699             :   if (len > DIM (slotp->atr))
    1700             :     {
    1701             :       log_error ("PC/SC returned a too large ATR (len=%lx)\n",
    1702             :                  (unsigned long)len);
    1703             :       sw = SW_HOST_GENERAL_ERROR;
    1704             :       goto command_failed;
    1705             :     }
    1706             :   err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
    1707             :   if (err)
    1708             :     {
    1709             :       log_error ("PC/SC RESET failed: %s (0x%lx)\n",
    1710             :                  pcsc_error_string (err), err);
    1711             :       /* If the error code is no smart card, we should not considere
    1712             :          this a major error and close the wrapper.  */
    1713             :       sw = pcsc_error_to_sw (err);
    1714             :       if (err == PCSC_E_NO_SMARTCARD)
    1715             :         return sw;
    1716             :       goto command_failed;
    1717             :     }
    1718             : 
    1719             :   /* The open function may return a zero for the ATR length to
    1720             :      indicate that no card is present.  */
    1721             :   n = len;
    1722             :   if (n)
    1723             :     {
    1724             :       if ((i=readn (slotp->pcsc.rsp_fd, slotp->atr, n, &len)) || len != n)
    1725             :         {
    1726             :           log_error ("error receiving PC/SC RESET response: %s\n",
    1727             :                      i? strerror (errno) : "premature EOF");
    1728             :           goto command_failed;
    1729             :         }
    1730             :     }
    1731             :   slotp->atrlen = len;
    1732             : 
    1733             :   /* Read the status so that IS_T0 will be set. */
    1734             :   pcsc_get_status (slot, &dummy_status);
    1735             : 
    1736             :   return 0;
    1737             : 
    1738             :  command_failed:
    1739             :   close (slotp->pcsc.req_fd);
    1740             :   close (slotp->pcsc.rsp_fd);
    1741             :   slotp->pcsc.req_fd = -1;
    1742             :   slotp->pcsc.rsp_fd = -1;
    1743             :   if (slotp->pcsc.pid != -1)
    1744             :     kill (slotp->pcsc.pid, SIGTERM);
    1745             :   slotp->pcsc.pid = (pid_t)(-1);
    1746             :   slotp->used = 0;
    1747             :   return sw;
    1748             : }
    1749             : #endif /* !NEED_PCSC_WRAPPER */
    1750             : 
    1751             : 
    1752             : /* Send an PC/SC reset command and return a status word on error or 0
    1753             :    on success. */
    1754             : static int
    1755           0 : reset_pcsc_reader (int slot)
    1756             : {
    1757             : #ifdef NEED_PCSC_WRAPPER
    1758             :   return reset_pcsc_reader_wrapped (slot);
    1759             : #else
    1760           0 :   return reset_pcsc_reader_direct (slot);
    1761             : #endif
    1762             : }
    1763             : 
    1764             : 
    1765             : /* Examine reader specific parameters and initialize.  This is mostly
    1766             :    for pinpad input.  Called at opening the connection to the reader.  */
    1767             : static int
    1768           0 : pcsc_vendor_specific_init (int slot)
    1769             : {
    1770             :   unsigned char buf[256];
    1771             :   pcsc_dword_t len;
    1772             :   int sw;
    1773           0 :   int vendor = 0;
    1774           0 :   int product = 0;
    1775           0 :   pcsc_dword_t get_tlv_ioctl = (pcsc_dword_t)-1;
    1776             :   unsigned char *p;
    1777             : 
    1778           0 :   len = sizeof (buf);
    1779           0 :   sw = control_pcsc (slot, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, buf, &len);
    1780           0 :   if (sw)
    1781             :     {
    1782           0 :       log_error ("pcsc_vendor_specific_init: GET_FEATURE_REQUEST failed: %d\n",
    1783             :                  sw);
    1784           0 :       return SW_NOT_SUPPORTED;
    1785             :     }
    1786             :   else
    1787             :     {
    1788           0 :       p = buf;
    1789           0 :       while (p < buf + len)
    1790             :         {
    1791           0 :           unsigned char code = *p++;
    1792           0 :           int l = *p++;
    1793           0 :           unsigned int v = 0;
    1794             : 
    1795           0 :           if (l == 1)
    1796           0 :             v = p[0];
    1797           0 :           else if (l == 2)
    1798           0 :             v = buf16_to_uint (p);
    1799           0 :           else if (l == 4)
    1800           0 :             v = buf32_to_uint (p);
    1801             : 
    1802           0 :           if (code == FEATURE_VERIFY_PIN_DIRECT)
    1803           0 :             reader_table[slot].pcsc.verify_ioctl = v;
    1804           0 :           else if (code == FEATURE_MODIFY_PIN_DIRECT)
    1805           0 :             reader_table[slot].pcsc.modify_ioctl = v;
    1806           0 :           else if (code == FEATURE_GET_TLV_PROPERTIES)
    1807           0 :             get_tlv_ioctl = v;
    1808             : 
    1809           0 :           if (DBG_CARD_IO)
    1810           0 :             log_debug ("feature: code=%02X, len=%d, v=%02X\n", code, l, v);
    1811             : 
    1812           0 :           p += l;
    1813             :         }
    1814             :     }
    1815             : 
    1816           0 :   if (get_tlv_ioctl == (pcsc_dword_t)-1)
    1817             :     {
    1818             :       /*
    1819             :        * For system which doesn't support GET_TLV_PROPERTIES,
    1820             :        * we put some heuristics here.
    1821             :        */
    1822           0 :       if (reader_table[slot].rdrname)
    1823             :         {
    1824           0 :           if (strstr (reader_table[slot].rdrname, "SPRx32"))
    1825             :             {
    1826           0 :               reader_table[slot].is_spr532 = 1;
    1827           0 :               reader_table[slot].pinpad_varlen_supported = 1;
    1828             :             }
    1829           0 :           else if (strstr (reader_table[slot].rdrname, "ST-2xxx"))
    1830             :             {
    1831           0 :               reader_table[slot].pcsc.pinmax = 15;
    1832           0 :               reader_table[slot].pinpad_varlen_supported = 1;
    1833             :             }
    1834           0 :           else if (strstr (reader_table[slot].rdrname, "cyberJack")
    1835           0 :                    || strstr (reader_table[slot].rdrname, "DIGIPASS")
    1836           0 :                    || strstr (reader_table[slot].rdrname, "Gnuk")
    1837           0 :                    || strstr (reader_table[slot].rdrname, "KAAN"))
    1838           0 :             reader_table[slot].pinpad_varlen_supported = 1;
    1839             :         }
    1840             : 
    1841           0 :       return 0;
    1842             :     }
    1843             : 
    1844           0 :   len = sizeof (buf);
    1845           0 :   sw = control_pcsc (slot, get_tlv_ioctl, NULL, 0, buf, &len);
    1846           0 :   if (sw)
    1847             :     {
    1848           0 :       log_error ("pcsc_vendor_specific_init: GET_TLV_IOCTL failed: %d\n", sw);
    1849           0 :       return SW_NOT_SUPPORTED;
    1850             :     }
    1851             : 
    1852           0 :   p = buf;
    1853           0 :   while (p < buf + len)
    1854             :     {
    1855           0 :       unsigned char tag = *p++;
    1856           0 :       int l = *p++;
    1857           0 :       unsigned int v = 0;
    1858             : 
    1859             :       /* Umm... here is little endian, while the encoding above is big.  */
    1860           0 :       if (l == 1)
    1861           0 :         v = p[0];
    1862           0 :       else if (l == 2)
    1863           0 :         v = (((unsigned int)p[1] << 8) | p[0]);
    1864           0 :       else if (l == 4)
    1865           0 :         v = (((unsigned int)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
    1866             : 
    1867           0 :       if (tag == PCSCv2_PART10_PROPERTY_bMinPINSize)
    1868           0 :         reader_table[slot].pcsc.pinmin = v;
    1869           0 :       else if (tag == PCSCv2_PART10_PROPERTY_bMaxPINSize)
    1870           0 :         reader_table[slot].pcsc.pinmax = v;
    1871           0 :       else if (tag == PCSCv2_PART10_PROPERTY_wIdVendor)
    1872           0 :         vendor = v;
    1873           0 :       else if (tag == PCSCv2_PART10_PROPERTY_wIdProduct)
    1874           0 :         product = v;
    1875             : 
    1876           0 :       if (DBG_CARD_IO)
    1877           0 :         log_debug ("TLV properties: tag=%02X, len=%d, v=%08X\n", tag, l, v);
    1878             : 
    1879           0 :       p += l;
    1880             :     }
    1881             : 
    1882           0 :   if (vendor == VENDOR_VEGA && product == VEGA_ALPHA)
    1883           0 :     {
    1884             :       /*
    1885             :        * Please read the comment of ccid_vendor_specific_init in
    1886             :        * ccid-driver.c.
    1887             :        */
    1888           0 :       const unsigned char cmd[] = { '\xb5', '\x01', '\x00', '\x03', '\x00' };
    1889           0 :       sw = control_pcsc (slot, CM_IOCTL_VENDOR_IFD_EXCHANGE,
    1890             :                          cmd, sizeof (cmd), NULL, 0);
    1891           0 :       if (sw)
    1892           0 :         return SW_NOT_SUPPORTED;
    1893             :     }
    1894           0 :   else if (vendor == VENDOR_SCM && product == SCM_SPR532) /* SCM SPR532 */
    1895             :     {
    1896           0 :       reader_table[slot].is_spr532 = 1;
    1897           0 :       reader_table[slot].pinpad_varlen_supported = 1;
    1898             :     }
    1899           0 :   else if (vendor == 0x046a && product == 0x003e) /* Cherry ST-2xxx */
    1900             :     {
    1901           0 :       reader_table[slot].pcsc.pinmax = 15;
    1902           0 :       reader_table[slot].pinpad_varlen_supported = 1;
    1903             :     }
    1904           0 :   else if (vendor == 0x0c4b /* Tested with Reiner cyberJack GO */
    1905           0 :            || vendor == 0x1a44 /* Tested with Vasco DIGIPASS 920 */
    1906           0 :            || vendor == 0x234b /* Tested with FSIJ Gnuk Token */
    1907           0 :            || vendor == 0x0d46 /* Tested with KAAN Advanced??? */)
    1908           0 :     reader_table[slot].pinpad_varlen_supported = 1;
    1909             : 
    1910           0 :   return 0;
    1911             : }
    1912             : 
    1913             : 
    1914             : /* Open the PC/SC reader without using the wrapper.  Returns -1 on
    1915             :    error or a slot number for the reader.  */
    1916             : #ifndef NEED_PCSC_WRAPPER
    1917             : static int
    1918           0 : open_pcsc_reader_direct (const char *portstr)
    1919             : {
    1920             :   long err;
    1921             :   int slot;
    1922           0 :   char *list = NULL;
    1923           0 :   char *rdrname = NULL;
    1924             :   pcsc_dword_t nreader;
    1925             :   char *p;
    1926             : 
    1927           0 :   slot = new_reader_slot ();
    1928           0 :   if (slot == -1)
    1929           0 :     return -1;
    1930             : 
    1931             :   /* Fixme: Allocating a context for each slot is not required.  One
    1932             :      global context should be sufficient.  */
    1933           0 :   err = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL,
    1934             :                                 &reader_table[slot].pcsc.context);
    1935           0 :   if (err)
    1936             :     {
    1937           0 :       log_error ("pcsc_establish_context failed: %s (0x%lx)\n",
    1938             :                  pcsc_error_string (err), err);
    1939           0 :       reader_table[slot].used = 0;
    1940           0 :       unlock_slot (slot);
    1941           0 :       return -1;
    1942             :     }
    1943             : 
    1944           0 :   err = pcsc_list_readers (reader_table[slot].pcsc.context,
    1945             :                            NULL, NULL, &nreader);
    1946           0 :   if (!err)
    1947             :     {
    1948           0 :       list = xtrymalloc (nreader+1); /* Better add 1 for safety reasons. */
    1949           0 :       if (!list)
    1950             :         {
    1951           0 :           log_error ("error allocating memory for reader list\n");
    1952           0 :           pcsc_release_context (reader_table[slot].pcsc.context);
    1953           0 :           reader_table[slot].used = 0;
    1954           0 :           unlock_slot (slot);
    1955           0 :           return -1 /*SW_HOST_OUT_OF_CORE*/;
    1956             :         }
    1957           0 :       err = pcsc_list_readers (reader_table[slot].pcsc.context,
    1958             :                                NULL, list, &nreader);
    1959             :     }
    1960           0 :   if (err)
    1961             :     {
    1962           0 :       log_error ("pcsc_list_readers failed: %s (0x%lx)\n",
    1963             :                  pcsc_error_string (err), err);
    1964           0 :       pcsc_release_context (reader_table[slot].pcsc.context);
    1965           0 :       reader_table[slot].used = 0;
    1966           0 :       xfree (list);
    1967           0 :       unlock_slot (slot);
    1968           0 :       return -1;
    1969             :     }
    1970             : 
    1971           0 :   p = list;
    1972           0 :   while (nreader)
    1973             :     {
    1974           0 :       if (!*p && !p[1])
    1975           0 :         break;
    1976           0 :       log_info ("detected reader '%s'\n", p);
    1977           0 :       if (nreader < (strlen (p)+1))
    1978             :         {
    1979           0 :           log_error ("invalid response from pcsc_list_readers\n");
    1980           0 :           break;
    1981             :         }
    1982           0 :       if (!rdrname && portstr && !strncmp (p, portstr, strlen (portstr)))
    1983           0 :         rdrname = p;
    1984           0 :       nreader -= strlen (p)+1;
    1985           0 :       p += strlen (p) + 1;
    1986             :     }
    1987             : 
    1988           0 :   if (!rdrname)
    1989           0 :     rdrname = list;
    1990             : 
    1991           0 :   reader_table[slot].rdrname = xtrystrdup (rdrname);
    1992           0 :   if (!reader_table[slot].rdrname)
    1993             :     {
    1994           0 :       log_error ("error allocating memory for reader name\n");
    1995           0 :       pcsc_release_context (reader_table[slot].pcsc.context);
    1996           0 :       reader_table[slot].used = 0;
    1997           0 :       unlock_slot (slot);
    1998           0 :       return -1;
    1999             :     }
    2000           0 :   xfree (list);
    2001           0 :   list = NULL;
    2002             : 
    2003           0 :   reader_table[slot].pcsc.card = 0;
    2004           0 :   reader_table[slot].atrlen = 0;
    2005           0 :   reader_table[slot].last_status = 0;
    2006             : 
    2007           0 :   reader_table[slot].connect_card = connect_pcsc_card;
    2008           0 :   reader_table[slot].disconnect_card = disconnect_pcsc_card;
    2009           0 :   reader_table[slot].close_reader = close_pcsc_reader;
    2010           0 :   reader_table[slot].reset_reader = reset_pcsc_reader;
    2011           0 :   reader_table[slot].get_status_reader = pcsc_get_status;
    2012           0 :   reader_table[slot].send_apdu_reader = pcsc_send_apdu;
    2013           0 :   reader_table[slot].dump_status_reader = dump_pcsc_reader_status;
    2014             : 
    2015           0 :   dump_reader_status (slot);
    2016           0 :   unlock_slot (slot);
    2017           0 :   return slot;
    2018             : }
    2019             : #endif /*!NEED_PCSC_WRAPPER */
    2020             : 
    2021             : 
    2022             : /* Open the PC/SC reader using the pcsc_wrapper program.  This is
    2023             :    needed to cope with different thread models and other peculiarities
    2024             :    of libpcsclite. */
    2025             : #ifdef NEED_PCSC_WRAPPER
    2026             : static int
    2027             : open_pcsc_reader_wrapped (const char *portstr)
    2028             : {
    2029             :   int slot;
    2030             :   reader_table_t slotp;
    2031             :   int fd, rp[2], wp[2];
    2032             :   int n, i;
    2033             :   pid_t pid;
    2034             :   size_t len;
    2035             :   unsigned char msgbuf[9];
    2036             :   int err;
    2037             :   unsigned int dummy_status;
    2038             : 
    2039             :   /* Note that we use the constant and not the function because this
    2040             :      code won't be be used under Windows.  */
    2041             :   const char *wrapperpgm = GNUPG_LIBEXECDIR "/gnupg-pcsc-wrapper";
    2042             : 
    2043             :   if (access (wrapperpgm, X_OK))
    2044             :     {
    2045             :       log_error ("can't run PC/SC access module '%s': %s\n",
    2046             :                  wrapperpgm, strerror (errno));
    2047             :       return -1;
    2048             :     }
    2049             : 
    2050             :   slot = new_reader_slot ();
    2051             :   if (slot == -1)
    2052             :     return -1;
    2053             :   slotp = reader_table + slot;
    2054             : 
    2055             :   /* Fire up the PC/SCc wrapper.  We don't use any fork/exec code from
    2056             :      the common directy but implement it directly so that this file
    2057             :      may still be source copied. */
    2058             : 
    2059             :   if (pipe (rp) == -1)
    2060             :     {
    2061             :       log_error ("error creating a pipe: %s\n", strerror (errno));
    2062             :       slotp->used = 0;
    2063             :       unlock_slot (slot);
    2064             :       return -1;
    2065             :     }
    2066             :   if (pipe (wp) == -1)
    2067             :     {
    2068             :       log_error ("error creating a pipe: %s\n", strerror (errno));
    2069             :       close (rp[0]);
    2070             :       close (rp[1]);
    2071             :       slotp->used = 0;
    2072             :       unlock_slot (slot);
    2073             :       return -1;
    2074             :     }
    2075             : 
    2076             :   pid = fork ();
    2077             :   if (pid == -1)
    2078             :     {
    2079             :       log_error ("error forking process: %s\n", strerror (errno));
    2080             :       close (rp[0]);
    2081             :       close (rp[1]);
    2082             :       close (wp[0]);
    2083             :       close (wp[1]);
    2084             :       slotp->used = 0;
    2085             :       unlock_slot (slot);
    2086             :       return -1;
    2087             :     }
    2088             :   slotp->pcsc.pid = pid;
    2089             : 
    2090             :   if (!pid)
    2091             :     { /*
    2092             :          === Child ===
    2093             :        */
    2094             : 
    2095             :       /* Double fork. */
    2096             :       pid = fork ();
    2097             :       if (pid == -1)
    2098             :         _exit (31);
    2099             :       if (pid)
    2100             :         _exit (0); /* Immediate exit this parent, so that the child
    2101             :                       gets cleaned up by the init process. */
    2102             : 
    2103             :       /* Connect our pipes. */
    2104             :       if (wp[0] != 0 && dup2 (wp[0], 0) == -1)
    2105             :         log_fatal ("dup2 stdin failed: %s\n", strerror (errno));
    2106             :       if (rp[1] != 1 && dup2 (rp[1], 1) == -1)
    2107             :         log_fatal ("dup2 stdout failed: %s\n", strerror (errno));
    2108             : 
    2109             :       /* Send stderr to the bit bucket. */
    2110             :       fd = open ("/dev/null", O_WRONLY);
    2111             :       if (fd == -1)
    2112             :         log_fatal ("can't open '/dev/null': %s", strerror (errno));
    2113             :       if (fd != 2 && dup2 (fd, 2) == -1)
    2114             :         log_fatal ("dup2 stderr failed: %s\n", strerror (errno));
    2115             : 
    2116             :       /* Close all other files. */
    2117             :       close_all_fds (3, NULL);
    2118             : 
    2119             :       execl (wrapperpgm,
    2120             :              "pcsc-wrapper",
    2121             :              "--",
    2122             :              "1", /* API version */
    2123             :              opt.pcsc_driver, /* Name of the PC/SC library. */
    2124             :               NULL);
    2125             :       _exit (31);
    2126             :     }
    2127             : 
    2128             :   /*
    2129             :      === Parent ===
    2130             :    */
    2131             :   close (wp[0]);
    2132             :   close (rp[1]);
    2133             :   slotp->pcsc.req_fd = wp[1];
    2134             :   slotp->pcsc.rsp_fd = rp[0];
    2135             : 
    2136             :   /* Wait for the intermediate child to terminate. */
    2137             : #ifdef USE_NPTH
    2138             : #define WAIT npth_waitpid
    2139             : #else
    2140             : #define WAIT waitpid
    2141             : #endif
    2142             :   while ( (i=WAIT (pid, NULL, 0)) == -1 && errno == EINTR)
    2143             :     ;
    2144             : #undef WAIT
    2145             : 
    2146             :   /* Now send the open request. */
    2147             :   msgbuf[0] = 0x01; /* OPEN command. */
    2148             :   len = portstr? strlen (portstr):0;
    2149             :   msgbuf[1] = (len >> 24);
    2150             :   msgbuf[2] = (len >> 16);
    2151             :   msgbuf[3] = (len >>  8);
    2152             :   msgbuf[4] = (len      );
    2153             :   if ( writen (slotp->pcsc.req_fd, msgbuf, 5)
    2154             :        || (portstr && writen (slotp->pcsc.req_fd, portstr, len)))
    2155             :     {
    2156             :       log_error ("error sending PC/SC OPEN request: %s\n",
    2157             :                  strerror (errno));
    2158             :       goto command_failed;
    2159             :     }
    2160             :   /* Read the response. */
    2161             :   if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9)
    2162             :     {
    2163             :       log_error ("error receiving PC/SC OPEN response: %s\n",
    2164             :                  i? strerror (errno) : "premature EOF");
    2165             :       goto command_failed;
    2166             :     }
    2167             :   len = buf32_to_size_t (msgbuf+1);
    2168             :   if (msgbuf[0] != 0x81 || len < 4)
    2169             :     {
    2170             :       log_error ("invalid response header from PC/SC received\n");
    2171             :       goto command_failed;
    2172             :     }
    2173             :   len -= 4; /* Already read the error code. */
    2174             :   if (len > DIM (slotp->atr))
    2175             :     {
    2176             :       log_error ("PC/SC returned a too large ATR (len=%lx)\n",
    2177             :                  (unsigned long)len);
    2178             :       goto command_failed;
    2179             :     }
    2180             :   err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5));
    2181             :   if (err)
    2182             :     {
    2183             :       log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err));
    2184             :       goto command_failed;
    2185             :     }
    2186             : 
    2187             :   slotp->last_status = 0;
    2188             : 
    2189             :   /* The open request may return a zero for the ATR length to
    2190             :      indicate that no card is present.  */
    2191             :   n = len;
    2192             :   if (n)
    2193             :     {
    2194             :       if ((i=readn (slotp->pcsc.rsp_fd, slotp->atr, n, &len)) || len != n)
    2195             :         {
    2196             :           log_error ("error receiving PC/SC OPEN response: %s\n",
    2197             :                      i? strerror (errno) : "premature EOF");
    2198             :           goto command_failed;
    2199             :         }
    2200             :       /* If we got to here we know that a card is present
    2201             :          and usable.  Thus remember this.  */
    2202             :       slotp->last_status = (  APDU_CARD_USABLE
    2203             :                             | APDU_CARD_PRESENT
    2204             :                             | APDU_CARD_ACTIVE);
    2205             :     }
    2206             :   slotp->atrlen = len;
    2207             : 
    2208             :   reader_table[slot].close_reader = close_pcsc_reader;
    2209             :   reader_table[slot].reset_reader = reset_pcsc_reader;
    2210             :   reader_table[slot].get_status_reader = pcsc_get_status;
    2211             :   reader_table[slot].send_apdu_reader = pcsc_send_apdu;
    2212             :   reader_table[slot].dump_status_reader = dump_pcsc_reader_status;
    2213             : 
    2214             :   pcsc_vendor_specific_init (slot);
    2215             : 
    2216             :   /* Read the status so that IS_T0 will be set. */
    2217             :   pcsc_get_status (slot, &dummy_status);
    2218             : 
    2219             :   dump_reader_status (slot);
    2220             :   unlock_slot (slot);
    2221             :   return slot;
    2222             : 
    2223             :  command_failed:
    2224             :   close (slotp->pcsc.req_fd);
    2225             :   close (slotp->pcsc.rsp_fd);
    2226             :   slotp->pcsc.req_fd = -1;
    2227             :   slotp->pcsc.rsp_fd = -1;
    2228             :   if (slotp->pcsc.pid != -1)
    2229             :     kill (slotp->pcsc.pid, SIGTERM);
    2230             :   slotp->pcsc.pid = (pid_t)(-1);
    2231             :   slotp->used = 0;
    2232             :   unlock_slot (slot);
    2233             :   /* There is no way to return SW. */
    2234             :   return -1;
    2235             : 
    2236             : }
    2237             : #endif /*NEED_PCSC_WRAPPER*/
    2238             : 
    2239             : 
    2240             : static int
    2241           0 : open_pcsc_reader (const char *portstr)
    2242             : {
    2243             : #ifdef NEED_PCSC_WRAPPER
    2244             :   return open_pcsc_reader_wrapped (portstr);
    2245             : #else
    2246           0 :   return open_pcsc_reader_direct (portstr);
    2247             : #endif
    2248             : }
    2249             : 
    2250             : 
    2251             : /* Check whether the reader supports the ISO command code COMMAND
    2252             :    on the pinpad.  Return 0 on success.  */
    2253             : static int
    2254           0 : check_pcsc_pinpad (int slot, int command, pininfo_t *pininfo)
    2255             : {
    2256             :   int r;
    2257             : 
    2258           0 :   if (reader_table[slot].pcsc.pinmin >= 0)
    2259           0 :     pininfo->minlen = reader_table[slot].pcsc.pinmin;
    2260             : 
    2261           0 :   if (reader_table[slot].pcsc.pinmax >= 0)
    2262           0 :     pininfo->maxlen = reader_table[slot].pcsc.pinmax;
    2263             : 
    2264           0 :   if (!pininfo->minlen)
    2265           0 :     pininfo->minlen = 1;
    2266           0 :   if (!pininfo->maxlen)
    2267           0 :     pininfo->maxlen = 15;
    2268             : 
    2269           0 :   if ((command == ISO7816_VERIFY && reader_table[slot].pcsc.verify_ioctl != 0)
    2270           0 :       || (command == ISO7816_CHANGE_REFERENCE_DATA
    2271           0 :           && reader_table[slot].pcsc.modify_ioctl != 0))
    2272           0 :     r = 0;                       /* Success */
    2273             :   else
    2274           0 :     r = SW_NOT_SUPPORTED;
    2275             : 
    2276           0 :   if (DBG_CARD_IO)
    2277           0 :     log_debug ("check_pcsc_pinpad: command=%02X, r=%d\n",
    2278             :                (unsigned int)command, r);
    2279             : 
    2280           0 :   if (reader_table[slot].pinpad_varlen_supported)
    2281           0 :     pininfo->fixedlen = 0;
    2282             : 
    2283           0 :   return r;
    2284             : }
    2285             : 
    2286             : #define PIN_VERIFY_STRUCTURE_SIZE 24
    2287             : static int
    2288           0 : pcsc_pinpad_verify (int slot, int class, int ins, int p0, int p1,
    2289             :                     pininfo_t *pininfo)
    2290             : {
    2291             :   int sw;
    2292             :   unsigned char *pin_verify;
    2293           0 :   int len = PIN_VERIFY_STRUCTURE_SIZE + pininfo->fixedlen;
    2294             :   /*
    2295             :    * The result buffer is only expected to have two-byte result on
    2296             :    * return.  However, some implementation uses this buffer for lower
    2297             :    * layer too and it assumes that there is enough space for lower
    2298             :    * layer communication.  Such an implementation fails for TPDU
    2299             :    * readers with "insufficient buffer", as it needs header and
    2300             :    * trailer.  Six is the number for header + result + trailer (TPDU).
    2301             :    */
    2302             :   unsigned char result[6];
    2303           0 :   pcsc_dword_t resultlen = 6;
    2304             :   int no_lc;
    2305             : 
    2306           0 :   if (!reader_table[slot].atrlen
    2307           0 :       && (sw = reset_pcsc_reader (slot)))
    2308           0 :     return sw;
    2309             : 
    2310           0 :   if (pininfo->fixedlen < 0 || pininfo->fixedlen >= 16)
    2311           0 :     return SW_NOT_SUPPORTED;
    2312             : 
    2313           0 :   pin_verify = xtrymalloc (len);
    2314           0 :   if (!pin_verify)
    2315           0 :     return SW_HOST_OUT_OF_CORE;
    2316             : 
    2317           0 :   no_lc = (!pininfo->fixedlen && reader_table[slot].is_spr532);
    2318             : 
    2319           0 :   pin_verify[0] = 0x00; /* bTimeOut */
    2320           0 :   pin_verify[1] = 0x00; /* bTimeOut2 */
    2321           0 :   pin_verify[2] = 0x82; /* bmFormatString: Byte, pos=0, left, ASCII. */
    2322           0 :   pin_verify[3] = pininfo->fixedlen; /* bmPINBlockString */
    2323           0 :   pin_verify[4] = 0x00; /* bmPINLengthFormat */
    2324           0 :   pin_verify[5] = pininfo->maxlen; /* wPINMaxExtraDigit */
    2325           0 :   pin_verify[6] = pininfo->minlen; /* wPINMaxExtraDigit */
    2326           0 :   pin_verify[7] = 0x02; /* bEntryValidationCondition: Validation key pressed */
    2327           0 :   if (pininfo->minlen && pininfo->maxlen && pininfo->minlen == pininfo->maxlen)
    2328           0 :     pin_verify[7] |= 0x01; /* Max size reached.  */
    2329           0 :   pin_verify[8] = 0x01; /* bNumberMessage: One message */
    2330           0 :   pin_verify[9] =  0x09; /* wLangId: 0x0409: US English */
    2331           0 :   pin_verify[10] = 0x04; /* wLangId: 0x0409: US English */
    2332           0 :   pin_verify[11] = 0x00; /* bMsgIndex */
    2333           0 :   pin_verify[12] = 0x00; /* bTeoPrologue[0] */
    2334           0 :   pin_verify[13] = 0x00; /* bTeoPrologue[1] */
    2335           0 :   pin_verify[14] = pininfo->fixedlen + 0x05 - no_lc; /* bTeoPrologue[2] */
    2336           0 :   pin_verify[15] = pininfo->fixedlen + 0x05 - no_lc; /* ulDataLength */
    2337           0 :   pin_verify[16] = 0x00; /* ulDataLength */
    2338           0 :   pin_verify[17] = 0x00; /* ulDataLength */
    2339           0 :   pin_verify[18] = 0x00; /* ulDataLength */
    2340           0 :   pin_verify[19] = class; /* abData[0] */
    2341           0 :   pin_verify[20] = ins; /* abData[1] */
    2342           0 :   pin_verify[21] = p0; /* abData[2] */
    2343           0 :   pin_verify[22] = p1; /* abData[3] */
    2344           0 :   pin_verify[23] = pininfo->fixedlen; /* abData[4] */
    2345           0 :   if (pininfo->fixedlen)
    2346           0 :     memset (&pin_verify[24], 0xff, pininfo->fixedlen);
    2347           0 :   else if (no_lc)
    2348           0 :     len--;
    2349             : 
    2350           0 :   if (DBG_CARD_IO)
    2351           0 :     log_debug ("send secure: c=%02X i=%02X p1=%02X p2=%02X len=%d pinmax=%d\n",
    2352             :                class, ins, p0, p1, len, pininfo->maxlen);
    2353             : 
    2354           0 :   sw = control_pcsc (slot, reader_table[slot].pcsc.verify_ioctl,
    2355             :                      pin_verify, len, result, &resultlen);
    2356           0 :   xfree (pin_verify);
    2357           0 :   if (sw || resultlen < 2)
    2358             :     {
    2359           0 :       log_error ("control_pcsc failed: %d\n", sw);
    2360           0 :       return sw? sw: SW_HOST_INCOMPLETE_CARD_RESPONSE;
    2361             :     }
    2362           0 :   sw = (result[resultlen-2] << 8) | result[resultlen-1];
    2363           0 :   if (DBG_CARD_IO)
    2364           0 :     log_debug (" response: sw=%04X  datalen=%d\n", sw, (unsigned int)resultlen);
    2365           0 :   return sw;
    2366             : }
    2367             : 
    2368             : 
    2369             : #define PIN_MODIFY_STRUCTURE_SIZE 29
    2370             : static int
    2371           0 : pcsc_pinpad_modify (int slot, int class, int ins, int p0, int p1,
    2372             :                     pininfo_t *pininfo)
    2373             : {
    2374             :   int sw;
    2375             :   unsigned char *pin_modify;
    2376           0 :   int len = PIN_MODIFY_STRUCTURE_SIZE + 2 * pininfo->fixedlen;
    2377             :   unsigned char result[6];      /* See the comment at pinpad_verify.  */
    2378           0 :   pcsc_dword_t resultlen = 6;
    2379             :   int no_lc;
    2380             : 
    2381           0 :   if (!reader_table[slot].atrlen
    2382           0 :       && (sw = reset_pcsc_reader (slot)))
    2383           0 :     return sw;
    2384             : 
    2385           0 :   if (pininfo->fixedlen < 0 || pininfo->fixedlen >= 16)
    2386           0 :     return SW_NOT_SUPPORTED;
    2387             : 
    2388           0 :   pin_modify = xtrymalloc (len);
    2389           0 :   if (!pin_modify)
    2390           0 :     return SW_HOST_OUT_OF_CORE;
    2391             : 
    2392           0 :   no_lc = (!pininfo->fixedlen && reader_table[slot].is_spr532);
    2393             : 
    2394           0 :   pin_modify[0] = 0x00; /* bTimeOut */
    2395           0 :   pin_modify[1] = 0x00; /* bTimeOut2 */
    2396           0 :   pin_modify[2] = 0x82; /* bmFormatString: Byte, pos=0, left, ASCII. */
    2397           0 :   pin_modify[3] = pininfo->fixedlen; /* bmPINBlockString */
    2398           0 :   pin_modify[4] = 0x00; /* bmPINLengthFormat */
    2399           0 :   pin_modify[5] = 0x00; /* bInsertionOffsetOld */
    2400           0 :   pin_modify[6] = pininfo->fixedlen; /* bInsertionOffsetNew */
    2401           0 :   pin_modify[7] = pininfo->maxlen; /* wPINMaxExtraDigit */
    2402           0 :   pin_modify[8] = pininfo->minlen; /* wPINMaxExtraDigit */
    2403           0 :   pin_modify[9] = (p0 == 0 ? 0x03 : 0x01);
    2404             :                   /* bConfirmPIN
    2405             :                    *    0x00: new PIN once
    2406             :                    *    0x01: new PIN twice (confirmation)
    2407             :                    *    0x02: old PIN and new PIN once
    2408             :                    *    0x03: old PIN and new PIN twice (confirmation)
    2409             :                    */
    2410           0 :   pin_modify[10] = 0x02; /* bEntryValidationCondition: Validation key pressed */
    2411           0 :   if (pininfo->minlen && pininfo->maxlen && pininfo->minlen == pininfo->maxlen)
    2412           0 :     pin_modify[10] |= 0x01; /* Max size reached.  */
    2413           0 :   pin_modify[11] = 0x03; /* bNumberMessage: Three messages */
    2414           0 :   pin_modify[12] = 0x09; /* wLangId: 0x0409: US English */
    2415           0 :   pin_modify[13] = 0x04; /* wLangId: 0x0409: US English */
    2416           0 :   pin_modify[14] = 0x00; /* bMsgIndex1 */
    2417           0 :   pin_modify[15] = 0x01; /* bMsgIndex2 */
    2418           0 :   pin_modify[16] = 0x02; /* bMsgIndex3 */
    2419           0 :   pin_modify[17] = 0x00; /* bTeoPrologue[0] */
    2420           0 :   pin_modify[18] = 0x00; /* bTeoPrologue[1] */
    2421           0 :   pin_modify[19] = 2 * pininfo->fixedlen + 0x05 - no_lc; /* bTeoPrologue[2] */
    2422           0 :   pin_modify[20] = 2 * pininfo->fixedlen + 0x05 - no_lc; /* ulDataLength */
    2423           0 :   pin_modify[21] = 0x00; /* ulDataLength */
    2424           0 :   pin_modify[22] = 0x00; /* ulDataLength */
    2425           0 :   pin_modify[23] = 0x00; /* ulDataLength */
    2426           0 :   pin_modify[24] = class; /* abData[0] */
    2427           0 :   pin_modify[25] = ins; /* abData[1] */
    2428           0 :   pin_modify[26] = p0; /* abData[2] */
    2429           0 :   pin_modify[27] = p1; /* abData[3] */
    2430           0 :   pin_modify[28] = 2 * pininfo->fixedlen; /* abData[4] */
    2431           0 :   if (pininfo->fixedlen)
    2432           0 :     memset (&pin_modify[29], 0xff, 2 * pininfo->fixedlen);
    2433           0 :   else if (no_lc)
    2434           0 :     len--;
    2435             : 
    2436           0 :   if (DBG_CARD_IO)
    2437           0 :     log_debug ("send secure: c=%02X i=%02X p1=%02X p2=%02X len=%d pinmax=%d\n",
    2438             :                class, ins, p0, p1, len, (int)pininfo->maxlen);
    2439             : 
    2440           0 :   sw = control_pcsc (slot, reader_table[slot].pcsc.modify_ioctl,
    2441             :                      pin_modify, len, result, &resultlen);
    2442           0 :   xfree (pin_modify);
    2443           0 :   if (sw || resultlen < 2)
    2444             :     {
    2445           0 :       log_error ("control_pcsc failed: %d\n", sw);
    2446           0 :       return sw? sw : SW_HOST_INCOMPLETE_CARD_RESPONSE;
    2447             :     }
    2448           0 :   sw = (result[resultlen-2] << 8) | result[resultlen-1];
    2449           0 :   if (DBG_CARD_IO)
    2450           0 :     log_debug (" response: sw=%04X  datalen=%d\n", sw, (unsigned int)resultlen);
    2451           0 :   return sw;
    2452             : }
    2453             : 
    2454             : #ifdef HAVE_LIBUSB
    2455             : /*
    2456             :      Internal CCID driver interface.
    2457             :  */
    2458             : 
    2459             : 
    2460             : static void
    2461           0 : dump_ccid_reader_status (int slot)
    2462             : {
    2463           0 :   log_info ("reader slot %d: using ccid driver\n", slot);
    2464           0 : }
    2465             : 
    2466             : static int
    2467           0 : close_ccid_reader (int slot)
    2468             : {
    2469           0 :   ccid_close_reader (reader_table[slot].ccid.handle);
    2470           0 :   reader_table[slot].rdrname = NULL;
    2471           0 :   reader_table[slot].used = 0;
    2472           0 :   return 0;
    2473             : }
    2474             : 
    2475             : 
    2476             : static int
    2477           0 : reset_ccid_reader (int slot)
    2478             : {
    2479             :   int err;
    2480           0 :   reader_table_t slotp = reader_table + slot;
    2481             :   unsigned char atr[33];
    2482             :   size_t atrlen;
    2483             : 
    2484           0 :   err = ccid_get_atr (slotp->ccid.handle, atr, sizeof atr, &atrlen);
    2485           0 :   if (err)
    2486           0 :     return err;
    2487             :   /* If the reset was successful, update the ATR. */
    2488             :   assert (sizeof slotp->atr >= sizeof atr);
    2489           0 :   slotp->atrlen = atrlen;
    2490           0 :   memcpy (slotp->atr, atr, atrlen);
    2491           0 :   dump_reader_status (slot);
    2492           0 :   return 0;
    2493             : }
    2494             : 
    2495             : 
    2496             : static int
    2497           0 : set_progress_cb_ccid_reader (int slot, gcry_handler_progress_t cb, void *cb_arg)
    2498             : {
    2499           0 :   reader_table_t slotp = reader_table + slot;
    2500             : 
    2501           0 :   return ccid_set_progress_cb (slotp->ccid.handle, cb, cb_arg);
    2502             : }
    2503             : 
    2504             : 
    2505             : static int
    2506           0 : get_status_ccid (int slot, unsigned int *status)
    2507             : {
    2508             :   int rc;
    2509             :   int bits;
    2510             : 
    2511           0 :   rc = ccid_slot_status (reader_table[slot].ccid.handle, &bits);
    2512           0 :   if (rc)
    2513           0 :     return rc;
    2514             : 
    2515           0 :   if (bits == 0)
    2516           0 :     *status = (APDU_CARD_USABLE|APDU_CARD_PRESENT|APDU_CARD_ACTIVE);
    2517           0 :   else if (bits == 1)
    2518           0 :     *status = APDU_CARD_PRESENT;
    2519             :   else
    2520           0 :     *status = 0;
    2521             : 
    2522           0 :   return 0;
    2523             : }
    2524             : 
    2525             : 
    2526             : /* Actually send the APDU of length APDULEN to SLOT and return a
    2527             :    maximum of *BUFLEN data in BUFFER, the actual returned size will be
    2528             :    set to BUFLEN.  Returns: Internal CCID driver error code. */
    2529             : static int
    2530           0 : send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen,
    2531             :                 unsigned char *buffer, size_t *buflen,
    2532             :                 pininfo_t *pininfo)
    2533             : {
    2534             :   long err;
    2535             :   size_t maxbuflen;
    2536             : 
    2537             :   /* If we don't have an ATR, we need to reset the reader first. */
    2538           0 :   if (!reader_table[slot].atrlen
    2539           0 :       && (err = reset_ccid_reader (slot)))
    2540           0 :     return err;
    2541             : 
    2542           0 :   if (DBG_CARD_IO)
    2543           0 :     log_printhex (" raw apdu:", apdu, apdulen);
    2544             : 
    2545           0 :   maxbuflen = *buflen;
    2546           0 :   if (pininfo)
    2547           0 :     err = ccid_transceive_secure (reader_table[slot].ccid.handle,
    2548             :                                   apdu, apdulen, pininfo,
    2549             :                                   buffer, maxbuflen, buflen);
    2550             :   else
    2551           0 :     err = ccid_transceive (reader_table[slot].ccid.handle,
    2552             :                            apdu, apdulen,
    2553             :                            buffer, maxbuflen, buflen);
    2554           0 :   if (err)
    2555           0 :     log_error ("ccid_transceive failed: (0x%lx)\n",
    2556             :                err);
    2557             : 
    2558           0 :   return err;
    2559             : }
    2560             : 
    2561             : 
    2562             : /* Check whether the CCID reader supports the ISO command code COMMAND
    2563             :    on the pinpad.  Return 0 on success.  For a description of the pin
    2564             :    parameters, see ccid-driver.c */
    2565             : static int
    2566           0 : check_ccid_pinpad (int slot, int command, pininfo_t *pininfo)
    2567             : {
    2568           0 :   unsigned char apdu[] = { 0, 0, 0, 0x81 };
    2569             : 
    2570           0 :   apdu[1] = command;
    2571           0 :   return ccid_transceive_secure (reader_table[slot].ccid.handle, apdu,
    2572             :                                  sizeof apdu, pininfo, NULL, 0, NULL);
    2573             : }
    2574             : 
    2575             : 
    2576             : static int
    2577           0 : ccid_pinpad_operation (int slot, int class, int ins, int p0, int p1,
    2578             :                        pininfo_t *pininfo)
    2579             : {
    2580             :   unsigned char apdu[4];
    2581             :   int err, sw;
    2582             :   unsigned char result[2];
    2583           0 :   size_t resultlen = 2;
    2584             : 
    2585           0 :   apdu[0] = class;
    2586           0 :   apdu[1] = ins;
    2587           0 :   apdu[2] = p0;
    2588           0 :   apdu[3] = p1;
    2589           0 :   err = ccid_transceive_secure (reader_table[slot].ccid.handle,
    2590             :                                 apdu, sizeof apdu, pininfo,
    2591             :                                 result, 2, &resultlen);
    2592           0 :   if (err)
    2593           0 :     return err;
    2594             : 
    2595           0 :   if (resultlen < 2)
    2596           0 :     return SW_HOST_INCOMPLETE_CARD_RESPONSE;
    2597             : 
    2598           0 :   sw = (result[resultlen-2] << 8) | result[resultlen-1];
    2599           0 :   return sw;
    2600             : }
    2601             : 
    2602             : 
    2603             : /* Open the reader and try to read an ATR.  */
    2604             : static int
    2605           0 : open_ccid_reader (const char *portstr)
    2606             : {
    2607             :   int err;
    2608             :   int slot;
    2609             :   reader_table_t slotp;
    2610             : 
    2611           0 :   slot = new_reader_slot ();
    2612           0 :   if (slot == -1)
    2613           0 :     return -1;
    2614           0 :   slotp = reader_table + slot;
    2615             : 
    2616           0 :   err = ccid_open_reader (&slotp->ccid.handle, portstr,
    2617           0 :                           (const char **)&slotp->rdrname);
    2618           0 :   if (err)
    2619             :     {
    2620           0 :       slotp->used = 0;
    2621           0 :       unlock_slot (slot);
    2622           0 :       return -1;
    2623             :     }
    2624             : 
    2625           0 :   err = ccid_get_atr (slotp->ccid.handle,
    2626           0 :                       slotp->atr, sizeof slotp->atr, &slotp->atrlen);
    2627           0 :   if (err)
    2628             :     {
    2629           0 :       slotp->atrlen = 0;
    2630           0 :       err = 0;
    2631             :     }
    2632             :   else
    2633             :     {
    2634             :       /* If we got to here we know that a card is present
    2635             :          and usable.  Thus remember this.  */
    2636           0 :       reader_table[slot].last_status = (APDU_CARD_USABLE
    2637             :                                         | APDU_CARD_PRESENT
    2638             :                                         | APDU_CARD_ACTIVE);
    2639             :     }
    2640             : 
    2641           0 :   reader_table[slot].close_reader = close_ccid_reader;
    2642           0 :   reader_table[slot].reset_reader = reset_ccid_reader;
    2643           0 :   reader_table[slot].get_status_reader = get_status_ccid;
    2644           0 :   reader_table[slot].send_apdu_reader = send_apdu_ccid;
    2645           0 :   reader_table[slot].check_pinpad = check_ccid_pinpad;
    2646           0 :   reader_table[slot].dump_status_reader = dump_ccid_reader_status;
    2647           0 :   reader_table[slot].set_progress_cb = set_progress_cb_ccid_reader;
    2648           0 :   reader_table[slot].pinpad_verify = ccid_pinpad_operation;
    2649           0 :   reader_table[slot].pinpad_modify = ccid_pinpad_operation;
    2650             :   /* Our CCID reader code does not support T=0 at all, thus reset the
    2651             :      flag.  */
    2652           0 :   reader_table[slot].is_t0 = 0;
    2653             : 
    2654           0 :   dump_reader_status (slot);
    2655           0 :   unlock_slot (slot);
    2656           0 :   return slot;
    2657             : }
    2658             : 
    2659             : 
    2660             : 
    2661             : #endif /* HAVE_LIBUSB */
    2662             : 
    2663             : 
    2664             : 
    2665             : #ifdef USE_G10CODE_RAPDU
    2666             : /*
    2667             :      The Remote APDU Interface.
    2668             : 
    2669             :      This uses the Remote APDU protocol to contact a reader.
    2670             : 
    2671             :      The port number is actually an index into the list of ports as
    2672             :      returned via the protocol.
    2673             :  */
    2674             : 
    2675             : 
    2676             : static int
    2677             : rapdu_status_to_sw (int status)
    2678             : {
    2679             :   int rc;
    2680             : 
    2681             :   switch (status)
    2682             :     {
    2683             :     case RAPDU_STATUS_SUCCESS:  rc = 0; break;
    2684             : 
    2685             :     case RAPDU_STATUS_INVCMD:
    2686             :     case RAPDU_STATUS_INVPROT:
    2687             :     case RAPDU_STATUS_INVSEQ:
    2688             :     case RAPDU_STATUS_INVCOOKIE:
    2689             :     case RAPDU_STATUS_INVREADER:  rc = SW_HOST_INV_VALUE;  break;
    2690             : 
    2691             :     case RAPDU_STATUS_TIMEOUT:  rc = SW_HOST_CARD_IO_ERROR; break;
    2692             :     case RAPDU_STATUS_CARDIO:   rc = SW_HOST_CARD_IO_ERROR; break;
    2693             :     case RAPDU_STATUS_NOCARD:   rc = SW_HOST_NO_CARD; break;
    2694             :     case RAPDU_STATUS_CARDCHG:  rc = SW_HOST_NO_CARD; break;
    2695             :     case RAPDU_STATUS_BUSY:     rc = SW_HOST_BUSY; break;
    2696             :     case RAPDU_STATUS_NEEDRESET: rc = SW_HOST_CARD_INACTIVE; break;
    2697             : 
    2698             :     default: rc = SW_HOST_GENERAL_ERROR; break;
    2699             :     }
    2700             : 
    2701             :   return rc;
    2702             : }
    2703             : 
    2704             : 
    2705             : 
    2706             : static int
    2707             : close_rapdu_reader (int slot)
    2708             : {
    2709             :   rapdu_release (reader_table[slot].rapdu.handle);
    2710             :   reader_table[slot].used = 0;
    2711             :   return 0;
    2712             : }
    2713             : 
    2714             : 
    2715             : static int
    2716             : reset_rapdu_reader (int slot)
    2717             : {
    2718             :   int err;
    2719             :   reader_table_t slotp;
    2720             :   rapdu_msg_t msg = NULL;
    2721             : 
    2722             :   slotp = reader_table + slot;
    2723             : 
    2724             :   err = rapdu_send_cmd (slotp->rapdu.handle, RAPDU_CMD_RESET);
    2725             :   if (err)
    2726             :     {
    2727             :       log_error ("sending rapdu command RESET failed: %s\n",
    2728             :                 err < 0 ? strerror (errno): rapdu_strerror (err));
    2729             :       rapdu_msg_release (msg);
    2730             :       return rapdu_status_to_sw (err);
    2731             :     }
    2732             :   err = rapdu_read_msg (slotp->rapdu.handle, &msg);
    2733             :   if (err)
    2734             :     {
    2735             :       log_error ("receiving rapdu message failed: %s\n",
    2736             :                 err < 0 ? strerror (errno): rapdu_strerror (err));
    2737             :       rapdu_msg_release (msg);
    2738             :       return rapdu_status_to_sw (err);
    2739             :     }
    2740             :   if (msg->cmd != RAPDU_STATUS_SUCCESS || !msg->datalen)
    2741             :     {
    2742             :       int sw = rapdu_status_to_sw (msg->cmd);
    2743             :       log_error ("rapdu command RESET failed: %s\n",
    2744             :                  rapdu_strerror (msg->cmd));
    2745             :       rapdu_msg_release (msg);
    2746             :       return sw;
    2747             :     }
    2748             :   if (msg->datalen > DIM (slotp->atr))
    2749             :     {
    2750             :       log_error ("ATR returned by the RAPDU layer is too large\n");
    2751             :       rapdu_msg_release (msg);
    2752             :       return SW_HOST_INV_VALUE;
    2753             :     }
    2754             :   slotp->atrlen = msg->datalen;
    2755             :   memcpy (slotp->atr, msg->data, msg->datalen);
    2756             : 
    2757             :   rapdu_msg_release (msg);
    2758             :   return 0;
    2759             : }
    2760             : 
    2761             : 
    2762             : static int
    2763             : my_rapdu_get_status (int slot, unsigned int *status)
    2764             : {
    2765             :   int err;
    2766             :   reader_table_t slotp;
    2767             :   rapdu_msg_t msg = NULL;
    2768             :   int oldslot;
    2769             : 
    2770             :   slotp = reader_table + slot;
    2771             : 
    2772             :   oldslot = rapdu_set_reader (slotp->rapdu.handle, slot);
    2773             :   err = rapdu_send_cmd (slotp->rapdu.handle, RAPDU_CMD_GET_STATUS);
    2774             :   rapdu_set_reader (slotp->rapdu.handle, oldslot);
    2775             :   if (err)
    2776             :     {
    2777             :       log_error ("sending rapdu command GET_STATUS failed: %s\n",
    2778             :                 err < 0 ? strerror (errno): rapdu_strerror (err));
    2779             :       return rapdu_status_to_sw (err);
    2780             :     }
    2781             :   err = rapdu_read_msg (slotp->rapdu.handle, &msg);
    2782             :   if (err)
    2783             :     {
    2784             :       log_error ("receiving rapdu message failed: %s\n",
    2785             :                 err < 0 ? strerror (errno): rapdu_strerror (err));
    2786             :       rapdu_msg_release (msg);
    2787             :       return rapdu_status_to_sw (err);
    2788             :     }
    2789             :   if (msg->cmd != RAPDU_STATUS_SUCCESS || !msg->datalen)
    2790             :     {
    2791             :       int sw = rapdu_status_to_sw (msg->cmd);
    2792             :       log_error ("rapdu command GET_STATUS failed: %s\n",
    2793             :                  rapdu_strerror (msg->cmd));
    2794             :       rapdu_msg_release (msg);
    2795             :       return sw;
    2796             :     }
    2797             :   *status = msg->data[0];
    2798             : 
    2799             :   rapdu_msg_release (msg);
    2800             :   return 0;
    2801             : }
    2802             : 
    2803             : 
    2804             : /* Actually send the APDU of length APDULEN to SLOT and return a
    2805             :    maximum of *BUFLEN data in BUFFER, the actual returned size will be
    2806             :    set to BUFLEN.  Returns: APDU error code. */
    2807             : static int
    2808             : my_rapdu_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
    2809             :                     unsigned char *buffer, size_t *buflen,
    2810             :                     pininfo_t *pininfo)
    2811             : {
    2812             :   int err;
    2813             :   reader_table_t slotp;
    2814             :   rapdu_msg_t msg = NULL;
    2815             :   size_t maxlen = *buflen;
    2816             : 
    2817             :   slotp = reader_table + slot;
    2818             : 
    2819             :   *buflen = 0;
    2820             :   if (DBG_CARD_IO)
    2821             :     log_printhex ("  APDU_data:", apdu, apdulen);
    2822             : 
    2823             :   if (apdulen < 4)
    2824             :     {
    2825             :       log_error ("rapdu_send_apdu: APDU is too short\n");
    2826             :       return SW_HOST_INV_VALUE;
    2827             :     }
    2828             : 
    2829             :   err = rapdu_send_apdu (slotp->rapdu.handle, apdu, apdulen);
    2830             :   if (err)
    2831             :     {
    2832             :       log_error ("sending rapdu command APDU failed: %s\n",
    2833             :                 err < 0 ? strerror (errno): rapdu_strerror (err));
    2834             :       rapdu_msg_release (msg);
    2835             :       return rapdu_status_to_sw (err);
    2836             :     }
    2837             :   err = rapdu_read_msg (slotp->rapdu.handle, &msg);
    2838             :   if (err)
    2839             :     {
    2840             :       log_error ("receiving rapdu message failed: %s\n",
    2841             :                 err < 0 ? strerror (errno): rapdu_strerror (err));
    2842             :       rapdu_msg_release (msg);
    2843             :       return rapdu_status_to_sw (err);
    2844             :     }
    2845             :   if (msg->cmd != RAPDU_STATUS_SUCCESS || !msg->datalen)
    2846             :     {
    2847             :       int sw = rapdu_status_to_sw (msg->cmd);
    2848             :       log_error ("rapdu command APDU failed: %s\n",
    2849             :                  rapdu_strerror (msg->cmd));
    2850             :       rapdu_msg_release (msg);
    2851             :       return sw;
    2852             :     }
    2853             : 
    2854             :   if (msg->datalen > maxlen)
    2855             :     {
    2856             :       log_error ("rapdu response apdu too large\n");
    2857             :       rapdu_msg_release (msg);
    2858             :       return SW_HOST_INV_VALUE;
    2859             :     }
    2860             : 
    2861             :   *buflen = msg->datalen;
    2862             :   memcpy (buffer, msg->data, msg->datalen);
    2863             : 
    2864             :   rapdu_msg_release (msg);
    2865             :   return 0;
    2866             : }
    2867             : 
    2868             : static int
    2869             : open_rapdu_reader (int portno,
    2870             :                    const unsigned char *cookie, size_t length,
    2871             :                    int (*readfnc) (void *opaque,
    2872             :                                    void *buffer, size_t size),
    2873             :                    void *readfnc_value,
    2874             :                    int (*writefnc) (void *opaque,
    2875             :                                     const void *buffer, size_t size),
    2876             :                    void *writefnc_value,
    2877             :                    void (*closefnc) (void *opaque),
    2878             :                    void *closefnc_value)
    2879             : {
    2880             :   int err;
    2881             :   int slot;
    2882             :   reader_table_t slotp;
    2883             :   rapdu_msg_t msg = NULL;
    2884             : 
    2885             :   slot = new_reader_slot ();
    2886             :   if (slot == -1)
    2887             :     return -1;
    2888             :   slotp = reader_table + slot;
    2889             : 
    2890             :   slotp->rapdu.handle = rapdu_new ();
    2891             :   if (!slotp->rapdu.handle)
    2892             :     {
    2893             :       slotp->used = 0;
    2894             :       unlock_slot (slot);
    2895             :       return -1;
    2896             :     }
    2897             : 
    2898             :   rapdu_set_reader (slotp->rapdu.handle, portno);
    2899             : 
    2900             :   rapdu_set_iofunc (slotp->rapdu.handle,
    2901             :                     readfnc, readfnc_value,
    2902             :                     writefnc, writefnc_value,
    2903             :                     closefnc, closefnc_value);
    2904             :   rapdu_set_cookie (slotp->rapdu.handle, cookie, length);
    2905             : 
    2906             :   /* First try to get the current ATR, but if the card is inactive
    2907             :      issue a reset instead.  */
    2908             :   err = rapdu_send_cmd (slotp->rapdu.handle, RAPDU_CMD_GET_ATR);
    2909             :   if (err == RAPDU_STATUS_NEEDRESET)
    2910             :     err = rapdu_send_cmd (slotp->rapdu.handle, RAPDU_CMD_RESET);
    2911             :   if (err)
    2912             :     {
    2913             :       log_info ("sending rapdu command GET_ATR/RESET failed: %s\n",
    2914             :                 err < 0 ? strerror (errno): rapdu_strerror (err));
    2915             :       goto failure;
    2916             :     }
    2917             :   err = rapdu_read_msg (slotp->rapdu.handle, &msg);
    2918             :   if (err)
    2919             :     {
    2920             :       log_info ("receiving rapdu message failed: %s\n",
    2921             :                 err < 0 ? strerror (errno): rapdu_strerror (err));
    2922             :       goto failure;
    2923             :     }
    2924             :   if (msg->cmd != RAPDU_STATUS_SUCCESS || !msg->datalen)
    2925             :     {
    2926             :       log_info ("rapdu command GET ATR failed: %s\n",
    2927             :                  rapdu_strerror (msg->cmd));
    2928             :       goto failure;
    2929             :     }
    2930             :   if (msg->datalen > DIM (slotp->atr))
    2931             :     {
    2932             :       log_error ("ATR returned by the RAPDU layer is too large\n");
    2933             :       goto failure;
    2934             :     }
    2935             :   slotp->atrlen = msg->datalen;
    2936             :   memcpy (slotp->atr, msg->data, msg->datalen);
    2937             : 
    2938             :   reader_table[slot].close_reader = close_rapdu_reader;
    2939             :   reader_table[slot].reset_reader = reset_rapdu_reader;
    2940             :   reader_table[slot].get_status_reader = my_rapdu_get_status;
    2941             :   reader_table[slot].send_apdu_reader = my_rapdu_send_apdu;
    2942             :   reader_table[slot].check_pinpad = NULL;
    2943             :   reader_table[slot].dump_status_reader = NULL;
    2944             :   reader_table[slot].pinpad_verify = NULL;
    2945             :   reader_table[slot].pinpad_modify = NULL;
    2946             : 
    2947             :   dump_reader_status (slot);
    2948             :   rapdu_msg_release (msg);
    2949             :   unlock_slot (slot);
    2950             :   return slot;
    2951             : 
    2952             :  failure:
    2953             :   rapdu_msg_release (msg);
    2954             :   rapdu_release (slotp->rapdu.handle);
    2955             :   slotp->used = 0;
    2956             :   unlock_slot (slot);
    2957             :   return -1;
    2958             : }
    2959             : 
    2960             : #endif /*USE_G10CODE_RAPDU*/
    2961             : 
    2962             : 
    2963             : 
    2964             : /*
    2965             :        Driver Access
    2966             :  */
    2967             : 
    2968             : 
    2969             : /* Open the reader and return an internal slot number or -1 on
    2970             :    error. If PORTSTR is NULL we default to a suitable port (for ctAPI:
    2971             :    the first USB reader.  For PC/SC the first listed reader). */
    2972             : int
    2973           0 : apdu_open_reader (const char *portstr)
    2974             : {
    2975             :   static int pcsc_api_loaded, ct_api_loaded;
    2976             :   int slot;
    2977             : 
    2978           0 :   if (DBG_READER)
    2979           0 :     log_debug ("enter: apdu_open_reader: portstr=%s\n", portstr);
    2980             : 
    2981             : #ifdef HAVE_LIBUSB
    2982           0 :   if (!opt.disable_ccid)
    2983             :     {
    2984             :       static int once_available;
    2985             :       int i;
    2986             :       const char *s;
    2987             : 
    2988           0 :       slot = open_ccid_reader (portstr);
    2989           0 :       if (slot != -1)
    2990             :         {
    2991           0 :           once_available = 1;
    2992           0 :           if (DBG_READER)
    2993           0 :             log_debug ("leave: apdu_open_reader => slot=%d [ccid]\n", slot);
    2994           0 :           return slot; /* got one */
    2995             :         }
    2996             : 
    2997             :       /* If we ever loaded successfully loaded a CCID reader we never
    2998             :          want to fallback to another driver.  This solves a problem
    2999             :          where ccid was used, the card unplugged and then scdaemon
    3000             :          tries to find a new reader and will eventually try PC/SC over
    3001             :          and over again.  To reset this flag "gpgconf --kill scdaemon"
    3002             :          can be used.  */
    3003           0 :       if (once_available)
    3004             :         {
    3005           0 :           if (DBG_READER)
    3006           0 :             log_debug ("leave: apdu_open_reader => slot=-1 (once_avail)\n");
    3007           0 :           return -1;
    3008             :         }
    3009             : 
    3010             :       /* If a CCID reader specification has been given, the user does
    3011             :          not want a fallback to other drivers. */
    3012           0 :       if (portstr)
    3013           0 :         for (s=portstr, i=0; *s; s++)
    3014           0 :           if (*s == ':' && (++i == 3))
    3015             :             {
    3016           0 :               if (DBG_READER)
    3017           0 :                 log_debug ("leave: apdu_open_reader => slot=-1 (no ccid)\n");
    3018           0 :               return -1;
    3019             :             }
    3020             :     }
    3021             : 
    3022             : #endif /* HAVE_LIBUSB */
    3023             : 
    3024           0 :   if (opt.ctapi_driver && *opt.ctapi_driver)
    3025             :     {
    3026           0 :       int port = portstr? atoi (portstr) : 32768;
    3027             : 
    3028           0 :       if (!ct_api_loaded)
    3029             :         {
    3030             :           void *handle;
    3031             : 
    3032           0 :           handle = dlopen (opt.ctapi_driver, RTLD_LAZY);
    3033           0 :           if (!handle)
    3034             :             {
    3035           0 :               log_error ("apdu_open_reader: failed to open driver: %s\n",
    3036             :                          dlerror ());
    3037           0 :               return -1;
    3038             :             }
    3039           0 :           CT_init = dlsym (handle, "CT_init");
    3040           0 :           CT_data = dlsym (handle, "CT_data");
    3041           0 :           CT_close = dlsym (handle, "CT_close");
    3042           0 :           if (!CT_init || !CT_data || !CT_close)
    3043             :             {
    3044           0 :               log_error ("apdu_open_reader: invalid CT-API driver\n");
    3045           0 :               dlclose (handle);
    3046           0 :               return -1;
    3047             :             }
    3048           0 :           ct_api_loaded = 1;
    3049             :         }
    3050           0 :       return open_ct_reader (port);
    3051             :     }
    3052             : 
    3053             : 
    3054             :   /* No ctAPI configured, so lets try the PC/SC API */
    3055           0 :   if (!pcsc_api_loaded)
    3056             :     {
    3057             : #ifndef NEED_PCSC_WRAPPER
    3058             :       void *handle;
    3059             : 
    3060           0 :       handle = dlopen (opt.pcsc_driver, RTLD_LAZY);
    3061           0 :       if (!handle)
    3062             :         {
    3063           0 :           log_error ("apdu_open_reader: failed to open driver '%s': %s\n",
    3064             :                      opt.pcsc_driver, dlerror ());
    3065           0 :           return -1;
    3066             :         }
    3067             : 
    3068           0 :       pcsc_establish_context = dlsym (handle, "SCardEstablishContext");
    3069           0 :       pcsc_release_context   = dlsym (handle, "SCardReleaseContext");
    3070           0 :       pcsc_list_readers      = dlsym (handle, "SCardListReaders");
    3071             : #if defined(_WIN32) || defined(__CYGWIN__)
    3072             :       if (!pcsc_list_readers)
    3073             :         pcsc_list_readers    = dlsym (handle, "SCardListReadersA");
    3074             : #endif
    3075           0 :       pcsc_get_status_change = dlsym (handle, "SCardGetStatusChange");
    3076             : #if defined(_WIN32) || defined(__CYGWIN__)
    3077             :       if (!pcsc_get_status_change)
    3078             :         pcsc_get_status_change = dlsym (handle, "SCardGetStatusChangeA");
    3079             : #endif
    3080           0 :       pcsc_connect           = dlsym (handle, "SCardConnect");
    3081             : #if defined(_WIN32) || defined(__CYGWIN__)
    3082             :       if (!pcsc_connect)
    3083             :         pcsc_connect         = dlsym (handle, "SCardConnectA");
    3084             : #endif
    3085           0 :       pcsc_reconnect         = dlsym (handle, "SCardReconnect");
    3086             : #if defined(_WIN32) || defined(__CYGWIN__)
    3087             :       if (!pcsc_reconnect)
    3088             :         pcsc_reconnect       = dlsym (handle, "SCardReconnectA");
    3089             : #endif
    3090           0 :       pcsc_disconnect        = dlsym (handle, "SCardDisconnect");
    3091           0 :       pcsc_status            = dlsym (handle, "SCardStatus");
    3092             : #if defined(_WIN32) || defined(__CYGWIN__)
    3093             :       if (!pcsc_status)
    3094             :         pcsc_status          = dlsym (handle, "SCardStatusA");
    3095             : #endif
    3096           0 :       pcsc_begin_transaction = dlsym (handle, "SCardBeginTransaction");
    3097           0 :       pcsc_end_transaction   = dlsym (handle, "SCardEndTransaction");
    3098           0 :       pcsc_transmit          = dlsym (handle, "SCardTransmit");
    3099           0 :       pcsc_set_timeout       = dlsym (handle, "SCardSetTimeout");
    3100           0 :       pcsc_control           = dlsym (handle, "SCardControl");
    3101             : 
    3102           0 :       if (!pcsc_establish_context
    3103           0 :           || !pcsc_release_context
    3104           0 :           || !pcsc_list_readers
    3105           0 :           || !pcsc_get_status_change
    3106           0 :           || !pcsc_connect
    3107           0 :           || !pcsc_reconnect
    3108           0 :           || !pcsc_disconnect
    3109           0 :           || !pcsc_status
    3110           0 :           || !pcsc_begin_transaction
    3111           0 :           || !pcsc_end_transaction
    3112           0 :           || !pcsc_transmit
    3113           0 :           || !pcsc_control
    3114             :           /* || !pcsc_set_timeout */)
    3115             :         {
    3116             :           /* Note that set_timeout is currently not used and also not
    3117             :              available under Windows. */
    3118           0 :           log_error ("apdu_open_reader: invalid PC/SC driver "
    3119             :                      "(%d%d%d%d%d%d%d%d%d%d%d%d%d)\n",
    3120             :                      !!pcsc_establish_context,
    3121             :                      !!pcsc_release_context,
    3122             :                      !!pcsc_list_readers,
    3123             :                      !!pcsc_get_status_change,
    3124             :                      !!pcsc_connect,
    3125             :                      !!pcsc_reconnect,
    3126             :                      !!pcsc_disconnect,
    3127             :                      !!pcsc_status,
    3128             :                      !!pcsc_begin_transaction,
    3129             :                      !!pcsc_end_transaction,
    3130             :                      !!pcsc_transmit,
    3131             :                      !!pcsc_set_timeout,
    3132             :                      !!pcsc_control );
    3133           0 :           dlclose (handle);
    3134           0 :           return -1;
    3135             :         }
    3136             : #endif /*!NEED_PCSC_WRAPPER*/
    3137           0 :       pcsc_api_loaded = 1;
    3138             :     }
    3139             : 
    3140           0 :   slot = open_pcsc_reader (portstr);
    3141             : 
    3142           0 :   if (DBG_READER)
    3143           0 :     log_debug ("leave: apdu_open_reader => slot=%d [pc/sc]\n", slot);
    3144           0 :   return slot;
    3145             : }
    3146             : 
    3147             : 
    3148             : /* Open an remote reader and return an internal slot number or -1 on
    3149             :    error. This function is an alternative to apdu_open_reader and used
    3150             :    with remote readers only.  Note that the supplied CLOSEFNC will
    3151             :    only be called once and the slot will not be valid afther this.
    3152             : 
    3153             :    If PORTSTR is NULL we default to the first available port.
    3154             : */
    3155             : int
    3156           0 : apdu_open_remote_reader (const char *portstr,
    3157             :                          const unsigned char *cookie, size_t length,
    3158             :                          int (*readfnc) (void *opaque,
    3159             :                                          void *buffer, size_t size),
    3160             :                          void *readfnc_value,
    3161             :                          int (*writefnc) (void *opaque,
    3162             :                                           const void *buffer, size_t size),
    3163             :                          void *writefnc_value,
    3164             :                          void (*closefnc) (void *opaque),
    3165             :                          void *closefnc_value)
    3166             : {
    3167             : #ifdef USE_G10CODE_RAPDU
    3168             :   return open_rapdu_reader (portstr? atoi (portstr) : 0,
    3169             :                             cookie, length,
    3170             :                             readfnc, readfnc_value,
    3171             :                             writefnc, writefnc_value,
    3172             :                             closefnc, closefnc_value);
    3173             : #else
    3174             :   (void)portstr;
    3175             :   (void)cookie;
    3176             :   (void)length;
    3177             :   (void)readfnc;
    3178             :   (void)readfnc_value;
    3179             :   (void)writefnc;
    3180             :   (void)writefnc_value;
    3181             :   (void)closefnc;
    3182             :   (void)closefnc_value;
    3183             : #ifdef _WIN32
    3184             :   errno = ENOENT;
    3185             : #else
    3186           0 :   errno = ENOSYS;
    3187             : #endif
    3188           0 :   return -1;
    3189             : #endif
    3190             : }
    3191             : 
    3192             : 
    3193             : int
    3194           0 : apdu_close_reader (int slot)
    3195             : {
    3196             :   int sw;
    3197             : 
    3198           0 :   if (DBG_READER)
    3199           0 :     log_debug ("enter: apdu_close_reader: slot=%d\n", slot);
    3200             : 
    3201           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    3202             :     {
    3203           0 :       if (DBG_READER)
    3204           0 :         log_debug ("leave: apdu_close_reader => SW_HOST_NO_DRIVER\n");
    3205           0 :       return SW_HOST_NO_DRIVER;
    3206             :     }
    3207           0 :   sw = apdu_disconnect (slot);
    3208           0 :   if (sw)
    3209             :     {
    3210             :       /*
    3211             :        * When the reader/token was removed it might come here.
    3212             :        * It should go through to call CLOSE_READER even if we got an error.
    3213             :        */
    3214           0 :       if (DBG_READER)
    3215           0 :         log_debug ("apdu_close_reader => 0x%x (apdu_disconnect)\n", sw);
    3216             :     }
    3217           0 :   if (reader_table[slot].close_reader)
    3218             :     {
    3219           0 :       sw = reader_table[slot].close_reader (slot);
    3220           0 :       if (DBG_READER)
    3221           0 :         log_debug ("leave: apdu_close_reader => 0x%x (close_reader)\n", sw);
    3222           0 :       return sw;
    3223             :     }
    3224           0 :   if (DBG_READER)
    3225           0 :     log_debug ("leave: apdu_close_reader => SW_HOST_NOT_SUPPORTED\n");
    3226           0 :   return SW_HOST_NOT_SUPPORTED;
    3227             : }
    3228             : 
    3229             : 
    3230             : /* Function suitable for a cleanup function to close all reader.  It
    3231             :    should not be used if the reader will be opened again.  The reason
    3232             :    for implementing this to properly close USB devices so that they
    3233             :    will startup the next time without error. */
    3234             : void
    3235           0 : apdu_prepare_exit (void)
    3236             : {
    3237             :   static int sentinel;
    3238             :   int slot;
    3239             : 
    3240           0 :   if (!sentinel)
    3241             :     {
    3242           0 :       sentinel = 1;
    3243           0 :       for (slot = 0; slot < MAX_READER; slot++)
    3244           0 :         if (reader_table[slot].used)
    3245             :           {
    3246           0 :             apdu_disconnect (slot);
    3247           0 :             if (reader_table[slot].close_reader)
    3248           0 :               reader_table[slot].close_reader (slot);
    3249           0 :             reader_table[slot].used = 0;
    3250             :           }
    3251           0 :       sentinel = 0;
    3252             :     }
    3253           0 : }
    3254             : 
    3255             : 
    3256             : /* Enumerate all readers and return information on whether this reader
    3257             :    is in use.  The caller should start with SLOT set to 0 and
    3258             :    increment it with each call until an error is returned. */
    3259             : int
    3260           0 : apdu_enum_reader (int slot, int *used)
    3261             : {
    3262           0 :   if (slot < 0 || slot >= MAX_READER)
    3263           0 :     return SW_HOST_NO_DRIVER;
    3264           0 :   *used = reader_table[slot].used;
    3265           0 :   return 0;
    3266             : }
    3267             : 
    3268             : 
    3269             : /* Connect a card.  This is used to power up the card and make sure
    3270             :    that an ATR is available.  Depending on the reader backend it may
    3271             :    return an error for an inactive card or if no card is
    3272             :    available.  */
    3273             : int
    3274           0 : apdu_connect (int slot)
    3275             : {
    3276           0 :   int sw = 0;
    3277           0 :   unsigned int status = 0;
    3278             : 
    3279           0 :   if (DBG_READER)
    3280           0 :     log_debug ("enter: apdu_connect: slot=%d\n", slot);
    3281             : 
    3282           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    3283             :     {
    3284           0 :       if (DBG_READER)
    3285           0 :         log_debug ("leave: apdu_connect => SW_HOST_NO_DRIVER\n");
    3286           0 :       return SW_HOST_NO_DRIVER;
    3287             :     }
    3288             : 
    3289             :   /* Only if the access method provides a connect function we use it.
    3290             :      If not, we expect that the card has been implicitly connected by
    3291             :      apdu_open_reader.  */
    3292           0 :   if (reader_table[slot].connect_card)
    3293             :     {
    3294           0 :       sw = lock_slot (slot);
    3295           0 :       if (!sw)
    3296             :         {
    3297           0 :           sw = reader_table[slot].connect_card (slot);
    3298           0 :           unlock_slot (slot);
    3299             :         }
    3300             :     }
    3301             : 
    3302             :   /* We need to call apdu_get_status_internal, so that the last-status
    3303             :      machinery gets setup properly even if a card is inserted while
    3304             :      scdaemon is fired up and apdu_get_status has not yet been called.
    3305             :      Without that we would force a reset of the card with the next
    3306             :      call to apdu_get_status.  */
    3307           0 :   if (!sw)
    3308           0 :     sw = apdu_get_status_internal (slot, 1, 1, &status, NULL);
    3309             : 
    3310           0 :   if (sw)
    3311             :     ;
    3312           0 :   else if (!(status & APDU_CARD_PRESENT))
    3313           0 :     sw = SW_HOST_NO_CARD;
    3314           0 :   else if ((status & APDU_CARD_PRESENT) && !(status & APDU_CARD_ACTIVE))
    3315           0 :     sw = SW_HOST_CARD_INACTIVE;
    3316             : 
    3317           0 :   if (DBG_READER)
    3318           0 :     log_debug ("leave: apdu_connect => sw=0x%x\n", sw);
    3319             : 
    3320           0 :   return sw;
    3321             : }
    3322             : 
    3323             : 
    3324             : int
    3325           0 : apdu_disconnect (int slot)
    3326             : {
    3327             :   int sw;
    3328             : 
    3329           0 :   if (DBG_READER)
    3330           0 :     log_debug ("enter: apdu_disconnect: slot=%d\n", slot);
    3331             : 
    3332           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    3333             :     {
    3334           0 :       if (DBG_READER)
    3335           0 :         log_debug ("leave: apdu_disconnect => SW_HOST_NO_DRIVER\n");
    3336           0 :       return SW_HOST_NO_DRIVER;
    3337             :     }
    3338             : 
    3339           0 :   if (reader_table[slot].disconnect_card)
    3340             :     {
    3341           0 :       sw = lock_slot (slot);
    3342           0 :       if (!sw)
    3343             :         {
    3344           0 :           sw = reader_table[slot].disconnect_card (slot);
    3345           0 :           unlock_slot (slot);
    3346             :         }
    3347             :     }
    3348             :   else
    3349           0 :     sw = 0;
    3350             : 
    3351           0 :   if (DBG_READER)
    3352           0 :     log_debug ("leave: apdu_disconnect => sw=0x%x\n", sw);
    3353           0 :   return sw;
    3354             : }
    3355             : 
    3356             : 
    3357             : /* Set the progress callback of SLOT to CB and its args to CB_ARG.  If
    3358             :    CB is NULL the progress callback is removed.  */
    3359             : int
    3360           0 : apdu_set_progress_cb (int slot, gcry_handler_progress_t cb, void *cb_arg)
    3361             : {
    3362             :   int sw;
    3363             : 
    3364           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    3365           0 :     return SW_HOST_NO_DRIVER;
    3366             : 
    3367           0 :   if (reader_table[slot].set_progress_cb)
    3368             :     {
    3369           0 :       sw = lock_slot (slot);
    3370           0 :       if (!sw)
    3371             :         {
    3372           0 :           sw = reader_table[slot].set_progress_cb (slot, cb, cb_arg);
    3373           0 :           unlock_slot (slot);
    3374             :         }
    3375             :     }
    3376             :   else
    3377           0 :     sw = 0;
    3378           0 :   return sw;
    3379             : }
    3380             : 
    3381             : 
    3382             : /* Do a reset for the card in reader at SLOT. */
    3383             : int
    3384           0 : apdu_reset (int slot)
    3385             : {
    3386             :   int sw;
    3387             : 
    3388           0 :   if (DBG_READER)
    3389           0 :     log_debug ("enter: apdu_reset: slot=%d\n", slot);
    3390             : 
    3391           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    3392             :     {
    3393           0 :       if (DBG_READER)
    3394           0 :         log_debug ("leave: apdu_reset => SW_HOST_NO_DRIVER\n");
    3395           0 :       return SW_HOST_NO_DRIVER;
    3396             :     }
    3397             : 
    3398           0 :   if ((sw = lock_slot (slot)))
    3399             :     {
    3400           0 :       if (DBG_READER)
    3401           0 :         log_debug ("leave: apdu_reset => sw=0x%x (lock_slot)\n", sw);
    3402           0 :       return sw;
    3403             :     }
    3404             : 
    3405           0 :   reader_table[slot].last_status = 0;
    3406           0 :   if (reader_table[slot].reset_reader)
    3407           0 :     sw = reader_table[slot].reset_reader (slot);
    3408             : 
    3409           0 :   if (!sw)
    3410             :     {
    3411             :       /* If we got to here we know that a card is present
    3412             :          and usable.  Thus remember this.  */
    3413           0 :       reader_table[slot].last_status = (APDU_CARD_USABLE
    3414             :                                         | APDU_CARD_PRESENT
    3415             :                                         | APDU_CARD_ACTIVE);
    3416             :     }
    3417             : 
    3418           0 :   unlock_slot (slot);
    3419           0 :   if (DBG_READER)
    3420           0 :     log_debug ("leave: apdu_reset => sw=0x%x\n", sw);
    3421           0 :   return sw;
    3422             : }
    3423             : 
    3424             : 
    3425             : /* Return the ATR or NULL if none is available.  On success the length
    3426             :    of the ATR is stored at ATRLEN.  The caller must free the returned
    3427             :    value.  */
    3428             : unsigned char *
    3429           0 : apdu_get_atr (int slot, size_t *atrlen)
    3430             : {
    3431             :   unsigned char *buf;
    3432             : 
    3433           0 :   if (DBG_READER)
    3434           0 :     log_debug ("enter: apdu_get_atr: slot=%d\n", slot);
    3435             : 
    3436           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    3437             :     {
    3438           0 :       if (DBG_READER)
    3439           0 :         log_debug ("leave: apdu_get_atr => NULL (bad slot)\n");
    3440           0 :       return NULL;
    3441             :     }
    3442           0 :   if (!reader_table[slot].atrlen)
    3443             :     {
    3444           0 :       if (DBG_READER)
    3445           0 :         log_debug ("leave: apdu_get_atr => NULL (no ATR)\n");
    3446           0 :       return NULL;
    3447             :     }
    3448             : 
    3449           0 :   buf = xtrymalloc (reader_table[slot].atrlen);
    3450           0 :   if (!buf)
    3451             :     {
    3452           0 :       if (DBG_READER)
    3453           0 :         log_debug ("leave: apdu_get_atr => NULL (out of core)\n");
    3454           0 :       return NULL;
    3455             :     }
    3456           0 :   memcpy (buf, reader_table[slot].atr, reader_table[slot].atrlen);
    3457           0 :   *atrlen = reader_table[slot].atrlen;
    3458           0 :   if (DBG_READER)
    3459           0 :     log_debug ("leave: apdu_get_atr => atrlen=%zu\n", *atrlen);
    3460           0 :   return buf;
    3461             : }
    3462             : 
    3463             : 
    3464             : 
    3465             : /* Retrieve the status for SLOT. The function does only wait for the
    3466             :    card to become available if HANG is set to true. On success the
    3467             :    bits in STATUS will be set to
    3468             : 
    3469             :      APDU_CARD_USABLE  (bit 0) = card present and usable
    3470             :      APDU_CARD_PRESENT (bit 1) = card present
    3471             :      APDU_CARD_ACTIVE  (bit 2) = card active
    3472             :                        (bit 3) = card access locked [not yet implemented]
    3473             : 
    3474             :    For must applications, testing bit 0 is sufficient.
    3475             : 
    3476             :    CHANGED will receive the value of the counter tracking the number
    3477             :    of card insertions.  This value may be used to detect a card
    3478             :    change.
    3479             : */
    3480             : static int
    3481           0 : apdu_get_status_internal (int slot, int hang, int no_atr_reset,
    3482             :                           unsigned int *status, unsigned int *changed)
    3483             : {
    3484             :   int sw;
    3485             :   unsigned int s;
    3486             : 
    3487           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    3488           0 :     return SW_HOST_NO_DRIVER;
    3489             : 
    3490           0 :   if ((sw = hang? lock_slot (slot) : trylock_slot (slot)))
    3491           0 :     return sw;
    3492             : 
    3493           0 :   if (reader_table[slot].get_status_reader)
    3494           0 :     sw = reader_table[slot].get_status_reader (slot, &s);
    3495             : 
    3496           0 :   unlock_slot (slot);
    3497             : 
    3498           0 :   if (sw)
    3499             :     {
    3500           0 :       reader_table[slot].last_status = 0;
    3501           0 :       return sw;
    3502             :     }
    3503             : 
    3504             :   /* Keep track of changes.  */
    3505           0 :   if (s != reader_table[slot].last_status
    3506           0 :       || !reader_table[slot].any_status )
    3507             :     {
    3508           0 :       reader_table[slot].change_counter++;
    3509             :       /* Make sure that the ATR is invalid so that a reset will be
    3510             :          triggered by apdu_activate.  */
    3511           0 :       if (!no_atr_reset)
    3512           0 :         reader_table[slot].atrlen = 0;
    3513             :     }
    3514           0 :   reader_table[slot].any_status = 1;
    3515           0 :   reader_table[slot].last_status = s;
    3516             : 
    3517           0 :   if (status)
    3518           0 :     *status = s;
    3519           0 :   if (changed)
    3520           0 :     *changed = reader_table[slot].change_counter;
    3521           0 :   return 0;
    3522             : }
    3523             : 
    3524             : 
    3525             : /* See above for a description.  */
    3526             : int
    3527           0 : apdu_get_status (int slot, int hang,
    3528             :                  unsigned int *status, unsigned int *changed)
    3529             : {
    3530             :   int sw;
    3531             : 
    3532           0 :   if (DBG_READER)
    3533           0 :     log_debug ("enter: apdu_get_status: slot=%d hang=%d\n", slot, hang);
    3534           0 :   sw = apdu_get_status_internal (slot, hang, 0, status, changed);
    3535           0 :   if (DBG_READER)
    3536             :     {
    3537           0 :       if (status && changed)
    3538           0 :         log_debug ("leave: apdu_get_status => sw=0x%x status=%u changecnt=%u\n",
    3539             :                    sw, *status, *changed);
    3540           0 :       else if (status)
    3541           0 :         log_debug ("leave: apdu_get_status => sw=0x%x status=%u\n",
    3542             :                    sw, *status);
    3543           0 :       else if (changed)
    3544           0 :         log_debug ("leave: apdu_get_status => sw=0x%x changed=%u\n",
    3545             :                    sw, *changed);
    3546             :       else
    3547           0 :         log_debug ("leave: apdu_get_status => sw=0x%x\n", sw);
    3548             :     }
    3549           0 :   return sw;
    3550             : }
    3551             : 
    3552             : 
    3553             : /* Check whether the reader supports the ISO command code COMMAND on
    3554             :    the pinpad.  Return 0 on success.  For a description of the pin
    3555             :    parameters, see ccid-driver.c */
    3556             : int
    3557           0 : apdu_check_pinpad (int slot, int command, pininfo_t *pininfo)
    3558             : {
    3559           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    3560           0 :     return SW_HOST_NO_DRIVER;
    3561             : 
    3562           0 :   if (opt.enable_pinpad_varlen)
    3563           0 :     pininfo->fixedlen = 0;
    3564             : 
    3565           0 :   if (reader_table[slot].check_pinpad)
    3566             :     {
    3567             :       int sw;
    3568             : 
    3569           0 :       if ((sw = lock_slot (slot)))
    3570           0 :         return sw;
    3571             : 
    3572           0 :       sw = reader_table[slot].check_pinpad (slot, command, pininfo);
    3573           0 :       unlock_slot (slot);
    3574           0 :       return sw;
    3575             :     }
    3576             :   else
    3577           0 :     return SW_HOST_NOT_SUPPORTED;
    3578             : }
    3579             : 
    3580             : 
    3581             : int
    3582           0 : apdu_pinpad_verify (int slot, int class, int ins, int p0, int p1,
    3583             :                     pininfo_t *pininfo)
    3584             : {
    3585           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    3586           0 :     return SW_HOST_NO_DRIVER;
    3587             : 
    3588           0 :   if (reader_table[slot].pinpad_verify)
    3589             :     {
    3590             :       int sw;
    3591             : 
    3592           0 :       if ((sw = lock_slot (slot)))
    3593           0 :         return sw;
    3594             : 
    3595           0 :       sw = reader_table[slot].pinpad_verify (slot, class, ins, p0, p1,
    3596             :                                              pininfo);
    3597           0 :       unlock_slot (slot);
    3598           0 :       return sw;
    3599             :     }
    3600             :   else
    3601           0 :     return SW_HOST_NOT_SUPPORTED;
    3602             : }
    3603             : 
    3604             : 
    3605             : int
    3606           0 : apdu_pinpad_modify (int slot, int class, int ins, int p0, int p1,
    3607             :                     pininfo_t *pininfo)
    3608             : {
    3609           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    3610           0 :     return SW_HOST_NO_DRIVER;
    3611             : 
    3612           0 :   if (reader_table[slot].pinpad_modify)
    3613             :     {
    3614             :       int sw;
    3615             : 
    3616           0 :       if ((sw = lock_slot (slot)))
    3617           0 :         return sw;
    3618             : 
    3619           0 :       sw = reader_table[slot].pinpad_modify (slot, class, ins, p0, p1,
    3620             :                                              pininfo);
    3621           0 :       unlock_slot (slot);
    3622           0 :       return sw;
    3623             :     }
    3624             :   else
    3625           0 :     return SW_HOST_NOT_SUPPORTED;
    3626             : }
    3627             : 
    3628             : 
    3629             : /* Dispatcher for the actual send_apdu function. Note, that this
    3630             :    function should be called in locked state. */
    3631             : static int
    3632           0 : send_apdu (int slot, unsigned char *apdu, size_t apdulen,
    3633             :            unsigned char *buffer, size_t *buflen, pininfo_t *pininfo)
    3634             : {
    3635           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    3636           0 :     return SW_HOST_NO_DRIVER;
    3637             : 
    3638           0 :   if (reader_table[slot].send_apdu_reader)
    3639           0 :     return reader_table[slot].send_apdu_reader (slot,
    3640             :                                                 apdu, apdulen,
    3641             :                                                 buffer, buflen,
    3642             :                                                 pininfo);
    3643             :   else
    3644           0 :     return SW_HOST_NOT_SUPPORTED;
    3645             : }
    3646             : 
    3647             : 
    3648             : /* Core APDU tranceiver function. Parameters are described at
    3649             :    apdu_send_le with the exception of PININFO which indicates pinpad
    3650             :    related operations if not NULL.  If EXTENDED_MODE is not 0
    3651             :    command chaining or extended length will be used according to these
    3652             :    values:
    3653             :        n < 0 := Use command chaining with the data part limited to -n
    3654             :                 in each chunk.  If -1 is used a default value is used.
    3655             :       n == 0 := No extended mode or command chaining.
    3656             :       n == 1 := Use extended length for input and output without a
    3657             :                 length limit.
    3658             :        n > 1 := Use extended length with up to N bytes.
    3659             : 
    3660             : */
    3661             : static int
    3662           0 : send_le (int slot, int class, int ins, int p0, int p1,
    3663             :          int lc, const char *data, int le,
    3664             :          unsigned char **retbuf, size_t *retbuflen,
    3665             :          pininfo_t *pininfo, int extended_mode)
    3666             : {
    3667             : #define SHORT_RESULT_BUFFER_SIZE 258
    3668             :   /* We allocate 8 extra bytes as a safety margin towards a driver bug.  */
    3669             :   unsigned char short_result_buffer[SHORT_RESULT_BUFFER_SIZE+10];
    3670           0 :   unsigned char *result_buffer = NULL;
    3671             :   size_t result_buffer_size;
    3672             :   unsigned char *result;
    3673             :   size_t resultlen;
    3674             :   unsigned char short_apdu_buffer[5+256+1];
    3675           0 :   unsigned char *apdu_buffer = NULL;
    3676             :   size_t apdu_buffer_size;
    3677             :   unsigned char *apdu;
    3678             :   size_t apdulen;
    3679             :   int sw;
    3680             :   long rc; /* We need a long here due to PC/SC. */
    3681           0 :   int did_exact_length_hack = 0;
    3682           0 :   int use_chaining = 0;
    3683           0 :   int use_extended_length = 0;
    3684             :   int lc_chunk;
    3685             : 
    3686           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    3687           0 :     return SW_HOST_NO_DRIVER;
    3688             : 
    3689           0 :   if (DBG_CARD_IO)
    3690           0 :     log_debug ("send apdu: c=%02X i=%02X p1=%02X p2=%02X lc=%d le=%d em=%d\n",
    3691             :                class, ins, p0, p1, lc, le, extended_mode);
    3692             : 
    3693           0 :   if (lc != -1 && (lc > 255 || lc < 0))
    3694             :     {
    3695             :       /* Data does not fit into an APDU.  What we do now depends on
    3696             :          the EXTENDED_MODE parameter.  */
    3697           0 :       if (!extended_mode)
    3698           0 :         return SW_WRONG_LENGTH; /* No way to send such an APDU.  */
    3699           0 :       else if (extended_mode > 0)
    3700           0 :         use_extended_length = 1;
    3701           0 :       else if (extended_mode < 0)
    3702             :         {
    3703             :           /* Send APDU using chaining mode.  */
    3704           0 :           if (lc > 16384)
    3705           0 :             return SW_WRONG_LENGTH;   /* Sanity check.  */
    3706           0 :           if ((class&0xf0) != 0)
    3707           0 :             return SW_HOST_INV_VALUE; /* Upper 4 bits need to be 0.  */
    3708           0 :           use_chaining = extended_mode == -1? 255 : -extended_mode;
    3709           0 :           use_chaining &= 0xff;
    3710             :         }
    3711             :       else
    3712           0 :         return SW_HOST_INV_VALUE;
    3713             :     }
    3714           0 :   else if (lc == -1 && extended_mode > 0)
    3715           0 :     use_extended_length = 1;
    3716             : 
    3717           0 :   if (le != -1 && (le > (extended_mode > 0? 255:256) || le < 0))
    3718             :     {
    3719             :       /* Expected Data does not fit into an APDU.  What we do now
    3720             :          depends on the EXTENDED_MODE parameter.  Note that a check
    3721             :          for command chaining does not make sense because we are
    3722             :          looking at Le.  */
    3723           0 :       if (!extended_mode)
    3724           0 :         return SW_WRONG_LENGTH; /* No way to send such an APDU.  */
    3725           0 :       else if (use_extended_length)
    3726             :         ; /* We are already using extended length.  */
    3727           0 :       else if (extended_mode > 0)
    3728           0 :         use_extended_length = 1;
    3729             :       else
    3730           0 :         return SW_HOST_INV_VALUE;
    3731             :     }
    3732             : 
    3733           0 :   if ((!data && lc != -1) || (data && lc == -1))
    3734           0 :     return SW_HOST_INV_VALUE;
    3735             : 
    3736           0 :   if (use_extended_length)
    3737             :     {
    3738           0 :       if (reader_table[slot].is_t0)
    3739           0 :         return SW_HOST_NOT_SUPPORTED;
    3740             : 
    3741             :       /* Space for: cls/ins/p1/p2+Z+2_byte_Lc+Lc+2_byte_Le.  */
    3742           0 :       apdu_buffer_size = 4 + 1 + (lc >= 0? (2+lc):0) + 2;
    3743           0 :       apdu_buffer = xtrymalloc (apdu_buffer_size + 10);
    3744           0 :       if (!apdu_buffer)
    3745           0 :         return SW_HOST_OUT_OF_CORE;
    3746           0 :       apdu = apdu_buffer;
    3747             :     }
    3748             :   else
    3749             :     {
    3750           0 :       apdu_buffer_size = sizeof short_apdu_buffer;
    3751           0 :       apdu = short_apdu_buffer;
    3752             :     }
    3753             : 
    3754           0 :   if (use_extended_length && (le > 256 || le < 0))
    3755             :     {
    3756           0 :       result_buffer_size = le < 0? 4096 : le;
    3757           0 :       result_buffer = xtrymalloc (result_buffer_size + 10);
    3758           0 :       if (!result_buffer)
    3759             :         {
    3760           0 :           xfree (apdu_buffer);
    3761           0 :           return SW_HOST_OUT_OF_CORE;
    3762             :         }
    3763           0 :       result = result_buffer;
    3764             :     }
    3765             :   else
    3766             :     {
    3767           0 :       result_buffer_size = SHORT_RESULT_BUFFER_SIZE;
    3768           0 :       result = short_result_buffer;
    3769             :     }
    3770             : #undef SHORT_RESULT_BUFFER_SIZE
    3771             : 
    3772           0 :   if ((sw = lock_slot (slot)))
    3773             :     {
    3774           0 :       xfree (apdu_buffer);
    3775           0 :       xfree (result_buffer);
    3776           0 :       return sw;
    3777             :     }
    3778             : 
    3779             :   do
    3780             :     {
    3781           0 :       if (use_extended_length)
    3782             :         {
    3783           0 :           use_chaining = 0;
    3784           0 :           apdulen = 0;
    3785           0 :           apdu[apdulen++] = class;
    3786           0 :           apdu[apdulen++] = ins;
    3787           0 :           apdu[apdulen++] = p0;
    3788           0 :           apdu[apdulen++] = p1;
    3789           0 :           if (lc > 0)
    3790             :             {
    3791           0 :               apdu[apdulen++] = 0;  /* Z byte: Extended length marker.  */
    3792           0 :               apdu[apdulen++] = ((lc >> 8) & 0xff);
    3793           0 :               apdu[apdulen++] = (lc & 0xff);
    3794           0 :               memcpy (apdu+apdulen, data, lc);
    3795           0 :               data += lc;
    3796           0 :               apdulen += lc;
    3797             :             }
    3798           0 :           if (le != -1)
    3799             :             {
    3800           0 :               if (lc <= 0)
    3801           0 :                 apdu[apdulen++] = 0;  /* Z byte: Extended length marker.  */
    3802           0 :               apdu[apdulen++] = ((le >> 8) & 0xff);
    3803           0 :               apdu[apdulen++] = (le & 0xff);
    3804             :             }
    3805             :         }
    3806             :       else
    3807             :         {
    3808           0 :           apdulen = 0;
    3809           0 :           apdu[apdulen] = class;
    3810           0 :           if (use_chaining && lc > 255)
    3811             :             {
    3812           0 :               apdu[apdulen] |= 0x10;
    3813           0 :               assert (use_chaining < 256);
    3814           0 :               lc_chunk = use_chaining;
    3815           0 :               lc -= use_chaining;
    3816             :             }
    3817             :           else
    3818             :             {
    3819           0 :               use_chaining = 0;
    3820           0 :               lc_chunk = lc;
    3821             :             }
    3822           0 :           apdulen++;
    3823           0 :           apdu[apdulen++] = ins;
    3824           0 :           apdu[apdulen++] = p0;
    3825           0 :           apdu[apdulen++] = p1;
    3826           0 :           if (lc_chunk != -1)
    3827             :             {
    3828           0 :               apdu[apdulen++] = lc_chunk;
    3829           0 :               memcpy (apdu+apdulen, data, lc_chunk);
    3830           0 :               data += lc_chunk;
    3831           0 :               apdulen += lc_chunk;
    3832             :               /* T=0 does not allow the use of Lc together with Le;
    3833             :                  thus disable Le in this case.  */
    3834           0 :               if (reader_table[slot].is_t0)
    3835           0 :                 le = -1;
    3836             :             }
    3837           0 :           if (le != -1 && !use_chaining)
    3838           0 :             apdu[apdulen++] = le; /* Truncation is okay (0 means 256). */
    3839             :         }
    3840             : 
    3841             :     exact_length_hack:
    3842             :       /* As a safeguard don't pass any garbage to the driver.  */
    3843           0 :       assert (apdulen <= apdu_buffer_size);
    3844           0 :       memset (apdu+apdulen, 0, apdu_buffer_size - apdulen);
    3845           0 :       resultlen = result_buffer_size;
    3846           0 :       rc = send_apdu (slot, apdu, apdulen, result, &resultlen, pininfo);
    3847           0 :       if (rc || resultlen < 2)
    3848             :         {
    3849           0 :           log_info ("apdu_send_simple(%d) failed: %s\n",
    3850             :                     slot, apdu_strerror (rc));
    3851           0 :           unlock_slot (slot);
    3852           0 :           xfree (apdu_buffer);
    3853           0 :           xfree (result_buffer);
    3854           0 :           return rc? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE;
    3855             :         }
    3856           0 :       sw = (result[resultlen-2] << 8) | result[resultlen-1];
    3857           0 :       if (!use_extended_length
    3858           0 :           && !did_exact_length_hack && SW_EXACT_LENGTH_P (sw))
    3859             :         {
    3860           0 :           apdu[apdulen-1] = (sw & 0x00ff);
    3861           0 :           did_exact_length_hack = 1;
    3862           0 :           goto exact_length_hack;
    3863             :         }
    3864             :     }
    3865           0 :   while (use_chaining && sw == SW_SUCCESS);
    3866             : 
    3867           0 :   if (apdu_buffer)
    3868             :     {
    3869           0 :       xfree (apdu_buffer);
    3870           0 :       apdu_buffer = NULL;
    3871           0 :       apdu_buffer_size = 0;
    3872             :     }
    3873             : 
    3874             :   /* Store away the returned data but strip the statusword. */
    3875           0 :   resultlen -= 2;
    3876           0 :   if (DBG_CARD_IO)
    3877             :     {
    3878           0 :       log_debug (" response: sw=%04X  datalen=%d\n",
    3879             :                  sw, (unsigned int)resultlen);
    3880           0 :       if ( !retbuf && (sw == SW_SUCCESS || (sw & 0xff00) == SW_MORE_DATA))
    3881           0 :         log_printhex ("    dump: ", result, resultlen);
    3882             :     }
    3883             : 
    3884           0 :   if (sw == SW_SUCCESS || sw == SW_EOF_REACHED)
    3885             :     {
    3886           0 :       if (retbuf)
    3887             :         {
    3888           0 :           *retbuf = xtrymalloc (resultlen? resultlen : 1);
    3889           0 :           if (!*retbuf)
    3890             :             {
    3891           0 :               unlock_slot (slot);
    3892           0 :               xfree (result_buffer);
    3893           0 :               return SW_HOST_OUT_OF_CORE;
    3894             :             }
    3895           0 :           *retbuflen = resultlen;
    3896           0 :           memcpy (*retbuf, result, resultlen);
    3897             :         }
    3898             :     }
    3899           0 :   else if ((sw & 0xff00) == SW_MORE_DATA)
    3900             :     {
    3901           0 :       unsigned char *p = NULL, *tmp;
    3902           0 :       size_t bufsize = 4096;
    3903             : 
    3904             :       /* It is likely that we need to return much more data, so we
    3905             :          start off with a large buffer. */
    3906           0 :       if (retbuf)
    3907             :         {
    3908           0 :           *retbuf = p = xtrymalloc (bufsize);
    3909           0 :           if (!*retbuf)
    3910             :             {
    3911           0 :               unlock_slot (slot);
    3912           0 :               xfree (result_buffer);
    3913           0 :               return SW_HOST_OUT_OF_CORE;
    3914             :             }
    3915           0 :           assert (resultlen < bufsize);
    3916           0 :           memcpy (p, result, resultlen);
    3917           0 :           p += resultlen;
    3918             :         }
    3919             : 
    3920             :       do
    3921             :         {
    3922           0 :           int len = (sw & 0x00ff);
    3923             : 
    3924           0 :           if (DBG_CARD_IO)
    3925           0 :             log_debug ("apdu_send_simple(%d): %d more bytes available\n",
    3926             :                        slot, len);
    3927           0 :           apdu_buffer_size = sizeof short_apdu_buffer;
    3928           0 :           apdu = short_apdu_buffer;
    3929           0 :           apdulen = 0;
    3930           0 :           apdu[apdulen++] = class;
    3931           0 :           apdu[apdulen++] = 0xC0;
    3932           0 :           apdu[apdulen++] = 0;
    3933           0 :           apdu[apdulen++] = 0;
    3934           0 :           apdu[apdulen++] = len;
    3935           0 :           assert (apdulen <= apdu_buffer_size);
    3936           0 :           memset (apdu+apdulen, 0, apdu_buffer_size - apdulen);
    3937           0 :           resultlen = result_buffer_size;
    3938           0 :           rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL);
    3939           0 :           if (rc || resultlen < 2)
    3940             :             {
    3941           0 :               log_error ("apdu_send_simple(%d) for get response failed: %s\n",
    3942             :                          slot, apdu_strerror (rc));
    3943           0 :               unlock_slot (slot);
    3944           0 :               xfree (result_buffer);
    3945           0 :               return rc? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE;
    3946             :             }
    3947           0 :           sw = (result[resultlen-2] << 8) | result[resultlen-1];
    3948           0 :           resultlen -= 2;
    3949           0 :           if (DBG_CARD_IO)
    3950             :             {
    3951           0 :               log_debug ("     more: sw=%04X  datalen=%d\n",
    3952             :                          sw, (unsigned int)resultlen);
    3953           0 :               if (!retbuf && (sw==SW_SUCCESS || (sw&0xff00)==SW_MORE_DATA))
    3954           0 :                 log_printhex ("     dump: ", result, resultlen);
    3955             :             }
    3956             : 
    3957           0 :           if ((sw & 0xff00) == SW_MORE_DATA
    3958           0 :               || sw == SW_SUCCESS
    3959           0 :               || sw == SW_EOF_REACHED )
    3960             :             {
    3961           0 :               if (retbuf && resultlen)
    3962             :                 {
    3963           0 :                   if (p - *retbuf + resultlen > bufsize)
    3964             :                     {
    3965           0 :                       bufsize += resultlen > 4096? resultlen: 4096;
    3966           0 :                       tmp = xtryrealloc (*retbuf, bufsize);
    3967           0 :                       if (!tmp)
    3968             :                         {
    3969           0 :                           unlock_slot (slot);
    3970           0 :                           xfree (result_buffer);
    3971           0 :                           return SW_HOST_OUT_OF_CORE;
    3972             :                         }
    3973           0 :                       p = tmp + (p - *retbuf);
    3974           0 :                       *retbuf = tmp;
    3975             :                     }
    3976           0 :                   memcpy (p, result, resultlen);
    3977           0 :                   p += resultlen;
    3978             :                 }
    3979             :             }
    3980             :           else
    3981           0 :             log_info ("apdu_send_simple(%d) "
    3982             :                       "got unexpected status %04X from get response\n",
    3983             :                       slot, sw);
    3984             :         }
    3985           0 :       while ((sw & 0xff00) == SW_MORE_DATA);
    3986             : 
    3987           0 :       if (retbuf)
    3988             :         {
    3989           0 :           *retbuflen = p - *retbuf;
    3990           0 :           tmp = xtryrealloc (*retbuf, *retbuflen);
    3991           0 :           if (tmp)
    3992           0 :             *retbuf = tmp;
    3993             :         }
    3994             :     }
    3995             : 
    3996           0 :   unlock_slot (slot);
    3997           0 :   xfree (result_buffer);
    3998             : 
    3999           0 :   if (DBG_CARD_IO && retbuf && sw == SW_SUCCESS)
    4000           0 :     log_printhex ("      dump: ", *retbuf, *retbuflen);
    4001             : 
    4002           0 :   return sw;
    4003             : }
    4004             : 
    4005             : /* Send an APDU to the card in SLOT.  The APDU is created from all
    4006             :    given parameters: CLASS, INS, P0, P1, LC, DATA, LE.  A value of -1
    4007             :    for LC won't sent this field and the data field; in this case DATA
    4008             :    must also be passed as NULL.  If EXTENDED_MODE is not 0 command
    4009             :    chaining or extended length will be used; see send_le for details.
    4010             :    The return value is the status word or -1 for an invalid SLOT or
    4011             :    other non card related error.  If RETBUF is not NULL, it will
    4012             :    receive an allocated buffer with the returned data.  The length of
    4013             :    that data will be put into *RETBUFLEN.  The caller is responsible
    4014             :    for releasing the buffer even in case of errors.  */
    4015             : int
    4016           0 : apdu_send_le(int slot, int extended_mode,
    4017             :              int class, int ins, int p0, int p1,
    4018             :              int lc, const char *data, int le,
    4019             :              unsigned char **retbuf, size_t *retbuflen)
    4020             : {
    4021           0 :   return send_le (slot, class, ins, p0, p1,
    4022             :                   lc, data, le,
    4023             :                   retbuf, retbuflen,
    4024             :                   NULL, extended_mode);
    4025             : }
    4026             : 
    4027             : 
    4028             : /* Send an APDU to the card in SLOT.  The APDU is created from all
    4029             :    given parameters: CLASS, INS, P0, P1, LC, DATA.  A value of -1 for
    4030             :    LC won't sent this field and the data field; in this case DATA must
    4031             :    also be passed as NULL.  If EXTENDED_MODE is not 0 command chaining
    4032             :    or extended length will be used; see send_le for details.  The
    4033             :    return value is the status word or -1 for an invalid SLOT or other
    4034             :    non card related error.  If RETBUF is not NULL, it will receive an
    4035             :    allocated buffer with the returned data.  The length of that data
    4036             :    will be put into *RETBUFLEN.  The caller is responsible for
    4037             :    releasing the buffer even in case of errors.  */
    4038             : int
    4039           0 : apdu_send (int slot, int extended_mode,
    4040             :            int class, int ins, int p0, int p1,
    4041             :            int lc, const char *data, unsigned char **retbuf, size_t *retbuflen)
    4042             : {
    4043           0 :   return send_le (slot, class, ins, p0, p1, lc, data, 256,
    4044             :                   retbuf, retbuflen, NULL, extended_mode);
    4045             : }
    4046             : 
    4047             : /* Send an APDU to the card in SLOT.  The APDU is created from all
    4048             :    given parameters: CLASS, INS, P0, P1, LC, DATA.  A value of -1 for
    4049             :    LC won't sent this field and the data field; in this case DATA must
    4050             :    also be passed as NULL.  If EXTENDED_MODE is not 0 command chaining
    4051             :    or extended length will be used; see send_le for details.  The
    4052             :    return value is the status word or -1 for an invalid SLOT or other
    4053             :    non card related error.  No data will be returned.  */
    4054             : int
    4055           0 : apdu_send_simple (int slot, int extended_mode,
    4056             :                   int class, int ins, int p0, int p1,
    4057             :                   int lc, const char *data)
    4058             : {
    4059           0 :   return send_le (slot, class, ins, p0, p1, lc, data, -1, NULL, NULL, NULL,
    4060             :                   extended_mode);
    4061             : }
    4062             : 
    4063             : 
    4064             : /* This is a more generic version of the apdu sending routine.  It
    4065             :    takes an already formatted APDU in APDUDATA or length APDUDATALEN
    4066             :    and returns with an APDU including the status word.  With
    4067             :    HANDLE_MORE set to true this function will handle the MORE DATA
    4068             :    status and return all APDUs concatenated with one status word at
    4069             :    the end.  If EXTENDED_LENGTH is != 0 extended lengths are allowed
    4070             :    with a max. result data length of EXTENDED_LENGTH bytes.  The
    4071             :    function does not return a regular status word but 0 on success.
    4072             :    If the slot is locked, the function returns immediately with an
    4073             :    error.  */
    4074             : int
    4075           0 : apdu_send_direct (int slot, size_t extended_length,
    4076             :                   const unsigned char *apdudata, size_t apdudatalen,
    4077             :                   int handle_more,
    4078             :                   unsigned char **retbuf, size_t *retbuflen)
    4079             : {
    4080             : #define SHORT_RESULT_BUFFER_SIZE 258
    4081             :   unsigned char short_result_buffer[SHORT_RESULT_BUFFER_SIZE+10];
    4082           0 :   unsigned char *result_buffer = NULL;
    4083             :   size_t result_buffer_size;
    4084             :   unsigned char *result;
    4085             :   size_t resultlen;
    4086             :   unsigned char short_apdu_buffer[5+256+10];
    4087           0 :   unsigned char *apdu_buffer = NULL;
    4088             :   unsigned char *apdu;
    4089             :   size_t apdulen;
    4090             :   int sw;
    4091             :   long rc; /* we need a long here due to PC/SC. */
    4092             :   int class;
    4093             : 
    4094           0 :   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
    4095           0 :     return SW_HOST_NO_DRIVER;
    4096             : 
    4097           0 :   if (apdudatalen > 65535)
    4098           0 :     return SW_HOST_INV_VALUE;
    4099             : 
    4100           0 :   if (apdudatalen > sizeof short_apdu_buffer - 5)
    4101             :     {
    4102           0 :       apdu_buffer = xtrymalloc (apdudatalen + 5);
    4103           0 :       if (!apdu_buffer)
    4104           0 :         return SW_HOST_OUT_OF_CORE;
    4105           0 :       apdu = apdu_buffer;
    4106             :     }
    4107             :   else
    4108             :     {
    4109           0 :       apdu = short_apdu_buffer;
    4110             :     }
    4111           0 :   apdulen = apdudatalen;
    4112           0 :   memcpy (apdu, apdudata, apdudatalen);
    4113           0 :   class = apdulen? *apdu : 0;
    4114             : 
    4115           0 :   if (extended_length >= 256 && extended_length <= 65536)
    4116             :     {
    4117           0 :       result_buffer_size = extended_length;
    4118           0 :       result_buffer = xtrymalloc (result_buffer_size + 10);
    4119           0 :       if (!result_buffer)
    4120             :         {
    4121           0 :           xfree (apdu_buffer);
    4122           0 :           return SW_HOST_OUT_OF_CORE;
    4123             :         }
    4124           0 :       result = result_buffer;
    4125             :     }
    4126             :   else
    4127             :     {
    4128           0 :       result_buffer_size = SHORT_RESULT_BUFFER_SIZE;
    4129           0 :       result = short_result_buffer;
    4130             :     }
    4131             : #undef SHORT_RESULT_BUFFER_SIZE
    4132             : 
    4133           0 :   if ((sw = trylock_slot (slot)))
    4134             :     {
    4135           0 :       xfree (apdu_buffer);
    4136           0 :       xfree (result_buffer);
    4137           0 :       return sw;
    4138             :     }
    4139             : 
    4140           0 :   resultlen = result_buffer_size;
    4141           0 :   rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL);
    4142           0 :   xfree (apdu_buffer);
    4143           0 :   apdu_buffer = NULL;
    4144           0 :   if (rc || resultlen < 2)
    4145             :     {
    4146           0 :       log_error ("apdu_send_direct(%d) failed: %s\n",
    4147             :                  slot, apdu_strerror (rc));
    4148           0 :       unlock_slot (slot);
    4149           0 :       xfree (result_buffer);
    4150           0 :       return rc? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE;
    4151             :     }
    4152           0 :   sw = (result[resultlen-2] << 8) | result[resultlen-1];
    4153             :   /* Store away the returned data but strip the statusword. */
    4154           0 :   resultlen -= 2;
    4155           0 :   if (DBG_CARD_IO)
    4156             :     {
    4157           0 :       log_debug (" response: sw=%04X  datalen=%d\n",
    4158             :                  sw, (unsigned int)resultlen);
    4159           0 :       if ( !retbuf && (sw == SW_SUCCESS || (sw & 0xff00) == SW_MORE_DATA))
    4160           0 :         log_printhex ("     dump: ", result, resultlen);
    4161             :     }
    4162             : 
    4163           0 :   if (handle_more && (sw & 0xff00) == SW_MORE_DATA)
    4164           0 :     {
    4165           0 :       unsigned char *p = NULL, *tmp;
    4166           0 :       size_t bufsize = 4096;
    4167             : 
    4168             :       /* It is likely that we need to return much more data, so we
    4169             :          start off with a large buffer. */
    4170           0 :       if (retbuf)
    4171             :         {
    4172           0 :           *retbuf = p = xtrymalloc (bufsize + 2);
    4173           0 :           if (!*retbuf)
    4174             :             {
    4175           0 :               unlock_slot (slot);
    4176           0 :               xfree (result_buffer);
    4177           0 :               return SW_HOST_OUT_OF_CORE;
    4178             :             }
    4179           0 :           assert (resultlen < bufsize);
    4180           0 :           memcpy (p, result, resultlen);
    4181           0 :           p += resultlen;
    4182             :         }
    4183             : 
    4184             :       do
    4185             :         {
    4186           0 :           int len = (sw & 0x00ff);
    4187             : 
    4188           0 :           if (DBG_CARD_IO)
    4189           0 :             log_debug ("apdu_send_direct(%d): %d more bytes available\n",
    4190             :                        slot, len);
    4191           0 :           apdu = short_apdu_buffer;
    4192           0 :           apdulen = 0;
    4193           0 :           apdu[apdulen++] = class;
    4194           0 :           apdu[apdulen++] = 0xC0;
    4195           0 :           apdu[apdulen++] = 0;
    4196           0 :           apdu[apdulen++] = 0;
    4197           0 :           apdu[apdulen++] = len;
    4198           0 :           memset (apdu+apdulen, 0, sizeof (short_apdu_buffer) - apdulen);
    4199           0 :           resultlen = result_buffer_size;
    4200           0 :           rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL);
    4201           0 :           if (rc || resultlen < 2)
    4202             :             {
    4203           0 :               log_error ("apdu_send_direct(%d) for get response failed: %s\n",
    4204             :                          slot, apdu_strerror (rc));
    4205           0 :               unlock_slot (slot);
    4206           0 :               xfree (result_buffer);
    4207           0 :               return rc ? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE;
    4208             :             }
    4209           0 :           sw = (result[resultlen-2] << 8) | result[resultlen-1];
    4210           0 :           resultlen -= 2;
    4211           0 :           if (DBG_CARD_IO)
    4212             :             {
    4213           0 :               log_debug ("     more: sw=%04X  datalen=%d\n",
    4214             :                          sw, (unsigned int)resultlen);
    4215           0 :               if (!retbuf && (sw==SW_SUCCESS || (sw&0xff00)==SW_MORE_DATA))
    4216           0 :                 log_printhex ("     dump: ", result, resultlen);
    4217             :             }
    4218             : 
    4219           0 :           if ((sw & 0xff00) == SW_MORE_DATA
    4220           0 :               || sw == SW_SUCCESS
    4221           0 :               || sw == SW_EOF_REACHED )
    4222             :             {
    4223           0 :               if (retbuf && resultlen)
    4224             :                 {
    4225           0 :                   if (p - *retbuf + resultlen > bufsize)
    4226             :                     {
    4227           0 :                       bufsize += resultlen > 4096? resultlen: 4096;
    4228           0 :                       tmp = xtryrealloc (*retbuf, bufsize + 2);
    4229           0 :                       if (!tmp)
    4230             :                         {
    4231           0 :                           unlock_slot (slot);
    4232           0 :                           xfree (result_buffer);
    4233           0 :                           return SW_HOST_OUT_OF_CORE;
    4234             :                         }
    4235           0 :                       p = tmp + (p - *retbuf);
    4236           0 :                       *retbuf = tmp;
    4237             :                     }
    4238           0 :                   memcpy (p, result, resultlen);
    4239           0 :                   p += resultlen;
    4240             :                 }
    4241             :             }
    4242             :           else
    4243           0 :             log_info ("apdu_send_direct(%d) "
    4244             :                       "got unexpected status %04X from get response\n",
    4245             :                       slot, sw);
    4246             :         }
    4247           0 :       while ((sw & 0xff00) == SW_MORE_DATA);
    4248             : 
    4249           0 :       if (retbuf)
    4250             :         {
    4251           0 :           *retbuflen = p - *retbuf;
    4252           0 :           tmp = xtryrealloc (*retbuf, *retbuflen + 2);
    4253           0 :           if (tmp)
    4254           0 :             *retbuf = tmp;
    4255             :         }
    4256             :     }
    4257             :   else
    4258             :     {
    4259           0 :       if (retbuf)
    4260             :         {
    4261           0 :           *retbuf = xtrymalloc ((resultlen? resultlen : 1)+2);
    4262           0 :           if (!*retbuf)
    4263             :             {
    4264           0 :               unlock_slot (slot);
    4265           0 :               xfree (result_buffer);
    4266           0 :               return SW_HOST_OUT_OF_CORE;
    4267             :             }
    4268           0 :           *retbuflen = resultlen;
    4269           0 :           memcpy (*retbuf, result, resultlen);
    4270             :         }
    4271             :     }
    4272             : 
    4273           0 :   unlock_slot (slot);
    4274           0 :   xfree (result_buffer);
    4275             : 
    4276             :   /* Append the status word.  Note that we reserved the two extra
    4277             :      bytes while allocating the buffer.  */
    4278           0 :   if (retbuf)
    4279             :     {
    4280           0 :       (*retbuf)[(*retbuflen)++] = (sw >> 8);
    4281           0 :       (*retbuf)[(*retbuflen)++] = sw;
    4282             :     }
    4283             : 
    4284           0 :   if (DBG_CARD_IO && retbuf)
    4285           0 :     log_printhex ("      dump: ", *retbuf, *retbuflen);
    4286             : 
    4287           0 :   return 0;
    4288             : }
    4289             : 
    4290             : 
    4291             : const char *
    4292           0 : apdu_get_reader_name (int slot)
    4293             : {
    4294           0 :   return reader_table[slot].rdrname;
    4295             : }

Generated by: LCOV version 1.11