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

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

Generated by: LCOV version 1.11