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

Generated by: LCOV version 1.11