diff --git a/scd/apdu.c b/scd/apdu.c index 21cd57430..2fd2d4bc7 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -59,10 +59,9 @@ #include "exechelp.h" #endif /* GNUPG_MAJOR_VERSION != 1 */ +#include "iso7816.h" #include "apdu.h" #include "ccid-driver.h" -#include "iso7816.h" - /* Due to conflicting use of threading libraries we usually can't link against libpcsclite. Instead we use a wrapper program. */ @@ -82,8 +81,6 @@ #define DLSTDCALL #endif -#define pininfo_s iso7816_pininfo_s - /* A structure to collect information pertaining to one reader slot. */ struct reader_table_s { @@ -98,12 +95,12 @@ struct reader_table_s { int (*reset_reader)(int); int (*get_status_reader)(int, unsigned int *); int (*send_apdu_reader)(int,unsigned char *,size_t, - unsigned char *, size_t *, struct pininfo_s *); - int (*check_keypad)(int, int, int, int, int); + unsigned char *, size_t *, pininfo_t *); + int (*check_keypad)(int, int, pininfo_t *); void (*dump_status_reader)(int); int (*set_progress_cb)(int, gcry_handler_progress_t, void*); - int (*keypad_verify)(int, int, int, int, int, struct pininfo_s *); - int (*keypad_modify)(int, int, int, int, int, struct pininfo_s *); + int (*keypad_verify)(int, int, int, int, int, pininfo_t *); + int (*keypad_modify)(int, int, int, int, int, pininfo_t *); struct { ccid_driver_t handle; @@ -304,12 +301,11 @@ static int reset_pcsc_reader (int slot); static int apdu_get_status_internal (int slot, int hang, int no_atr_reset, unsigned int *status, unsigned int *changed); -static int check_pcsc_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max); +static int check_pcsc_keypad (int slot, int command, pininfo_t *pininfo); static int pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, - struct pininfo_s *pininfo); + pininfo_t *pininfo); static int pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, - struct pininfo_s *pininfo); + pininfo_t *pininfo); @@ -621,7 +617,7 @@ ct_get_status (int slot, unsigned int *status) set to BUFLEN. Returns: CT API error code. */ static int ct_send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen, struct pininfo_s *pininfo) + unsigned char *buffer, size_t *buflen, pininfo_t *pininfo) { int rc; unsigned char dad[1], sad[1]; @@ -1053,7 +1049,7 @@ pcsc_get_status (int slot, unsigned int *status) static int pcsc_send_apdu_direct (int slot, unsigned char *apdu, size_t apdulen, unsigned char *buffer, size_t *buflen, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { long err; struct pcsc_io_request_s send_pci; @@ -1089,7 +1085,7 @@ pcsc_send_apdu_direct (int slot, unsigned char *apdu, size_t apdulen, static int pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen, unsigned char *buffer, size_t *buflen, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { long err; reader_table_t slotp; @@ -1208,7 +1204,7 @@ pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen, static int pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, unsigned char *buffer, size_t *buflen, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { #ifdef NEED_PCSC_WRAPPER return pcsc_send_apdu_wrapped (slot, apdu, apdulen, buffer, buflen, pininfo); @@ -2014,16 +2010,13 @@ open_pcsc_reader (const char *portstr) /* Check whether the reader supports the ISO command code COMMAND on the keypad. Return 0 on success. */ static int -check_pcsc_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max) +check_pcsc_keypad (int slot, int command, pininfo_t *pininfo) { unsigned char buf[256]; size_t len = 256; int sw; - (void)pin_mode; - (void)pinlen_min; - (void)pinlen_max; + (void)pininfo; check_again: if (command == ISO7816_VERIFY) @@ -2075,7 +2068,7 @@ check_pcsc_keypad (int slot, int command, int pin_mode, #define PIN_VERIFY_STRUCTURE_SIZE 24 static int pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { int sw; unsigned char *pin_verify; @@ -2154,7 +2147,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, #define PIN_MODIFY_STRUCTURE_SIZE 29 static int pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { int sw; unsigned char *pin_modify; @@ -2325,7 +2318,7 @@ get_status_ccid (int slot, unsigned int *status) static int send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, unsigned char *buffer, size_t *buflen, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { long err; size_t maxbuflen; @@ -2341,10 +2334,7 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, maxbuflen = *buflen; if (pininfo) err = ccid_transceive_secure (reader_table[slot].ccid.handle, - apdu, apdulen, - pininfo->mode, - pininfo->minlen, - pininfo->maxlen, + apdu, apdulen, pininfo, buffer, maxbuflen, buflen); else err = ccid_transceive (reader_table[slot].ccid.handle, @@ -2362,22 +2352,19 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, on the keypad. Return 0 on success. For a description of the pin parameters, see ccid-driver.c */ static int -check_ccid_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max) +check_ccid_keypad (int slot, int command, pininfo_t *pininfo) { unsigned char apdu[] = { 0, 0, 0, 0x81 }; apdu[1] = command; - return ccid_transceive_secure (reader_table[slot].ccid.handle, - apdu, sizeof apdu, - pin_mode, pinlen_min, pinlen_max, - NULL, 0, NULL); + return ccid_transceive_secure (reader_table[slot].ccid.handle, apdu, + sizeof apdu, pininfo, NULL, 0, NULL); } static int ccid_keypad_operation (int slot, int class, int ins, int p0, int p1, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { unsigned char apdu[4]; int err, sw; @@ -2389,8 +2376,7 @@ ccid_keypad_operation (int slot, int class, int ins, int p0, int p1, apdu[2] = p0; apdu[3] = p1; err = ccid_transceive_secure (reader_table[slot].ccid.handle, - apdu, sizeof apdu, - pininfo->mode, pininfo->minlen, pininfo->maxlen, + apdu, sizeof apdu, pininfo, result, 2, &resultlen); if (err) return err; @@ -2610,7 +2596,7 @@ my_rapdu_get_status (int slot, unsigned int *status) static int my_rapdu_send_apdu (int slot, unsigned char *apdu, size_t apdulen, unsigned char *buffer, size_t *buflen, - struct pininfo_s *pininfo) + pininfo_t *pininfo) { int err; reader_table_t slotp; @@ -3300,12 +3286,14 @@ apdu_get_status (int slot, int hang, the keypad. Return 0 on success. For a description of the pin parameters, see ccid-driver.c */ int -apdu_check_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max) +apdu_check_keypad (int slot, int command, pininfo_t *pininfo) { if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; + if (opt.enable_keypad_varlen) + pininfo->mode = 0; + if (reader_table[slot].check_keypad) { int sw; @@ -3313,8 +3301,7 @@ apdu_check_keypad (int slot, int command, int pin_mode, if ((sw = lock_slot (slot))) return sw; - sw = reader_table[slot].check_keypad (slot, command, - pin_mode, pinlen_min, pinlen_max); + sw = reader_table[slot].check_keypad (slot, command, pininfo); unlock_slot (slot); return sw; } @@ -3324,15 +3311,9 @@ apdu_check_keypad (int slot, int command, int pin_mode, int -apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, int pin_mode, - int pinlen_min, int pinlen_max) +apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, + pininfo_t *pininfo) { - struct pininfo_s pininfo; - - pininfo.mode = pin_mode; - pininfo.minlen = pinlen_min; - pininfo.maxlen = pinlen_max; - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; @@ -3344,7 +3325,7 @@ apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, int pin_mode, return sw; sw = reader_table[slot].keypad_verify (slot, class, ins, p0, p1, - &pininfo); + pininfo); unlock_slot (slot); return sw; } @@ -3354,15 +3335,9 @@ apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, int pin_mode, int -apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, int pin_mode, - int pinlen_min, int pinlen_max) +apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, + pininfo_t *pininfo) { - struct pininfo_s pininfo; - - pininfo.mode = pin_mode; - pininfo.minlen = pinlen_min; - pininfo.maxlen = pinlen_max; - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; @@ -3374,7 +3349,7 @@ apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, int pin_mode, return sw; sw = reader_table[slot].keypad_modify (slot, class, ins, p0, p1, - &pininfo); + pininfo); unlock_slot (slot); return sw; } @@ -3387,7 +3362,7 @@ apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, int pin_mode, function should be called in locked state. */ static int send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen, struct pininfo_s *pininfo) + unsigned char *buffer, size_t *buflen, pininfo_t *pininfo) { if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; @@ -3419,7 +3394,7 @@ static int send_le (int slot, int class, int ins, int p0, int p1, int lc, const char *data, int le, unsigned char **retbuf, size_t *retbuflen, - struct pininfo_s *pininfo, int extended_mode) + pininfo_t *pininfo, int extended_mode) { #define SHORT_RESULT_BUFFER_SIZE 258 /* We allocate 8 extra bytes as a safety margin towards a driver bug. */ diff --git a/scd/apdu.h b/scd/apdu.h index 64c216231..011806caa 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -112,12 +112,11 @@ int apdu_activate (int slot); int apdu_reset (int slot); int apdu_get_status (int slot, int hang, unsigned int *status, unsigned int *changed); -int apdu_check_keypad (int slot, int command, int pin_mode, - int pinlen_min, int pinlen_max); +int apdu_check_keypad (int slot, int command, pininfo_t *pininfo); int apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, - int pin_mode, int pinlen_min, int pinlen_max); + pininfo_t *pininfo); int apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, - int pin_mode, int pinlen_min, int pinlen_max); + pininfo_t *pininfo); int apdu_send_simple (int slot, int extended_mode, int class, int ins, int p0, int p1, int lc, const char *data); diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c index 697cdf6d1..5a2a90222 100644 --- a/scd/app-dinsig.c +++ b/scd/app-dinsig.c @@ -282,7 +282,7 @@ verify_pin (app_t app, { const char *s; int rc; - iso7816_pininfo_t pininfo; + pininfo_t pininfo; if ( app->did_chv1 && !app->force_chv1 ) return 0; /* No need to verify it again. */ diff --git a/scd/app-nks.c b/scd/app-nks.c index b51e1fc97..c53f45ac8 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -781,7 +781,7 @@ verify_pin (app_t app, int pwid, const char *desc, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { - iso7816_pininfo_t pininfo; + pininfo_t pininfo; int rc; if (!desc) @@ -1144,7 +1144,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *pwidstr, int is_sigg; const char *newdesc; int pwid; - iso7816_pininfo_t pininfo; + pininfo_t pininfo; (void)ctrl; diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 98af5e84a..5292f1d8b 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1489,7 +1489,7 @@ verify_a_chv (app_t app, int rc = 0; char *prompt_buffer = NULL; const char *prompt; - iso7816_pininfo_t pininfo; + pininfo_t pininfo; int minlen = 6; assert (chvno == 1 || chvno == 2); @@ -1707,7 +1707,7 @@ verify_chv3 (app_t app, if (!app->did_chv3) { - iso7816_pininfo_t pininfo; + pininfo_t pininfo; int minlen = 8; char *prompt; @@ -1917,7 +1917,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, char *pinvalue = NULL; int reset_mode = !!(flags & APP_CHANGE_FLAG_RESET); int set_resetcode = 0; - iso7816_pininfo_t pininfo; + pininfo_t pininfo; int use_keypad = 0; int minlen = 6; diff --git a/scd/app.c b/scd/app.c index 7cbbf6ea6..8bdfefae5 100644 --- a/scd/app.c +++ b/scd/app.c @@ -26,8 +26,8 @@ #include "scdaemon.h" #include "app-common.h" -#include "apdu.h" #include "iso7816.h" +#include "apdu.h" #include "tlv.h" /* This table is used to keep track of locks on a per reader base. diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index b8a98096f..b0578612d 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -91,6 +91,8 @@ #include +#include "scdaemon.h" +#include "iso7816.h" #include "ccid-driver.h" #define DRVNAME "ccid-driver: " @@ -3297,7 +3299,7 @@ ccid_transceive (ccid_driver_t handle, int ccid_transceive_secure (ccid_driver_t handle, const unsigned char *apdu_buf, size_t apdu_buflen, - int pin_mode, int pinlen_min, int pinlen_max, + pininfo_t *pininfo, unsigned char *resp, size_t maxresplen, size_t *nresp) { int rc; @@ -3308,7 +3310,7 @@ ccid_transceive_secure (ccid_driver_t handle, size_t dummy_nresp; int testmode; int cherry_mode = 0; - int enable_varlen = opt.enable_keypad_varlen; + int enable_varlen = 0; testmode = !resp && !nresp; @@ -3322,19 +3324,16 @@ ccid_transceive_secure (ccid_driver_t handle, ; else return CCID_DRIVER_ERR_NO_KEYPAD; - - if (pin_mode != 1) - return CCID_DRIVER_ERR_NOT_SUPPORTED; - if (!pinlen_min) - pinlen_min = 1; - if (!pinlen_max) - pinlen_max = 25; + if (!pininfo->minlen) + pininfo->minlen = 1; + if (!pininfo->maxlen) + pininfo->maxlen = 25; /* Note that the 25 is the maximum value the SPR532 allows. */ - if (pinlen_min < 1 || pinlen_min > 25 - || pinlen_max < 1 || pinlen_max > 25 - || pinlen_min > pinlen_max) + if (pininfo->minlen < 1 || pininfo->minlen > 25 + || pininfo->maxlen < 1 || pininfo->maxlen > 25 + || pininfo->minlen > pininfo->maxlen) return CCID_DRIVER_ERR_INV_VALUE; /* We have only tested a few readers so better don't risk anything @@ -3348,7 +3347,7 @@ ccid_transceive_secure (ccid_driver_t handle, break; case VENDOR_VASCO: /* Tested with DIGIPASS 920 */ enable_varlen = 1; - pinlen_max = 15; + pininfo->maxlen = 15; break; case VENDOR_CHERRY: enable_varlen = 1; @@ -3371,6 +3370,12 @@ ccid_transceive_secure (ccid_driver_t handle, return CCID_DRIVER_ERR_NOT_SUPPORTED; } + if (enable_varlen) + pininfo->mode = 0; + + if (pininfo->mode != 0 && pininfo->mode != 1) + return CCID_DRIVER_ERR_NOT_SUPPORTED; + if (testmode) return 0; /* Success */ @@ -3418,8 +3423,8 @@ ccid_transceive_secure (ccid_driver_t handle, } /* The following is a little endian word. */ - msg[msglen++] = pinlen_max; /* wPINMaxExtraDigit-Maximum. */ - msg[msglen++] = pinlen_min; /* wPINMaxExtraDigit-Minimum. */ + msg[msglen++] = pininfo->maxlen; /* wPINMaxExtraDigit-Maximum. */ + msg[msglen++] = pininfo->minlen; /* wPINMaxExtraDigit-Minimum. */ if (apdu_buf[1] == 0x24) msg[msglen++] = apdu_buf[2] == 0 ? 0x03 : 0x01; @@ -3432,7 +3437,7 @@ ccid_transceive_secure (ccid_driver_t handle, msg[msglen] = 0x02; /* bEntryValidationCondition: Validation key pressed */ - if (pinlen_min && pinlen_max && pinlen_min == pinlen_max) + if (pininfo->minlen && pininfo->maxlen && pininfo->minlen == pininfo->maxlen) msg[msglen] |= 0x01; /* Max size reached. */ msglen++; diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h index d5e40ca43..549e858e3 100644 --- a/scd/ccid-driver.h +++ b/scd/ccid-driver.h @@ -93,8 +93,7 @@ int ccid_transceive (ccid_driver_t handle, unsigned char *resp, size_t maxresplen, size_t *nresp); int ccid_transceive_secure (ccid_driver_t handle, const unsigned char *apdu, size_t apdulen, - int pin_mode, - int pinlen_min, int pinlen_max, + pininfo_t *pininfo, unsigned char *resp, size_t maxresplen, size_t *nresp); int ccid_transceive_escape (ccid_driver_t handle, const unsigned char *data, size_t datalen, diff --git a/scd/command.c b/scd/command.c index 2123b9d6d..cea71bf8f 100644 --- a/scd/command.c +++ b/scd/command.c @@ -34,6 +34,7 @@ #include #include #include "app-common.h" +#include "iso7816.h" #include "apdu.h" /* Required for apdu_*_reader (). */ #include "exechelp.h" #ifdef HAVE_LIBUSB diff --git a/scd/iso7816.c b/scd/iso7816.c index 23b84cf6f..78e3c811c 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -269,12 +269,11 @@ iso7816_apdu_direct (int slot, const void *apdudata, size_t apdudatalen, /* Check whether the reader supports the ISO command code COMMAND on the keypad. Returns 0 on success. */ gpg_error_t -iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo) +iso7816_check_keypad (int slot, int command, pininfo_t *pininfo) { int sw; - sw = apdu_check_keypad (slot, command, - pininfo->mode, pininfo->minlen, pininfo->maxlen); + sw = apdu_check_keypad (slot, command, pininfo); return iso7816_map_sw (sw); } @@ -283,12 +282,11 @@ iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo) vector CHVNO. With PININFO non-NULL the keypad of the reader will be used. Returns 0 on success. */ gpg_error_t -iso7816_verify_kp (int slot, int chvno, iso7816_pininfo_t *pininfo) +iso7816_verify_kp (int slot, int chvno, pininfo_t *pininfo) { int sw; - sw = apdu_keypad_verify (slot, 0x00, CMD_VERIFY, 0, chvno, - pininfo->mode, pininfo->minlen, pininfo->maxlen); + sw = apdu_keypad_verify (slot, 0x00, CMD_VERIFY, 0, chvno, pininfo); return map_sw (sw); } @@ -309,14 +307,12 @@ iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen) data" is done, otherwise an "exchange reference data". */ gpg_error_t iso7816_change_reference_data_kp (int slot, int chvno, int is_exchange, - iso7816_pininfo_t *pininfo) + pininfo_t *pininfo) { int sw; sw = apdu_keypad_modify (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, - is_exchange ? 1 : 0, - chvno, pininfo->mode, pininfo->minlen, - pininfo->maxlen); + is_exchange ? 1 : 0, chvno, pininfo); return map_sw (sw); } diff --git a/scd/iso7816.h b/scd/iso7816.h index 1d66f6df7..3db07a52b 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -32,13 +32,13 @@ /* Information to be passed to keypad equipped readers. See ccid-driver.c for details. */ -struct iso7816_pininfo_s +struct pininfo_s { - int mode; /* A mode of 0 means: Do not use the keypad. */ + int mode; /* 0: Use variable length input. 1: Use fixed length input. */ int minlen; int maxlen; }; -typedef struct iso7816_pininfo_s iso7816_pininfo_t; +typedef struct pininfo_s pininfo_t; gpg_error_t iso7816_map_sw (int sw); @@ -58,16 +58,16 @@ gpg_error_t iso7816_apdu_direct (int slot, int handle_more, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_check_keypad (int slot, int command, - iso7816_pininfo_t *pininfo); + pininfo_t *pininfo); gpg_error_t iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen); -gpg_error_t iso7816_verify_kp (int slot, int chvno, iso7816_pininfo_t *pininfo); +gpg_error_t iso7816_verify_kp (int slot, int chvno, pininfo_t *pininfo); gpg_error_t iso7816_change_reference_data (int slot, int chvno, const char *oldchv, size_t oldchvlen, const char *newchv, size_t newchvlen); gpg_error_t iso7816_change_reference_data_kp (int slot, int chvno, int is_exchange, - iso7816_pininfo_t *pininfo); + pininfo_t *pininfo); gpg_error_t iso7816_reset_retry_counter (int slot, int chvno, const char *newchv, size_t newchvlen); gpg_error_t iso7816_reset_retry_counter_with_rc (int slot, int chvno, diff --git a/scd/sc-copykeys.c b/scd/sc-copykeys.c index 615e4b28a..521764526 100644 --- a/scd/sc-copykeys.c +++ b/scd/sc-copykeys.c @@ -33,6 +33,7 @@ #include "../common/ttyio.h" #include "../common/simple-pwquery.h" +#include "iso7816.h" #include "apdu.h" /* for open_reader */ #include "atr.h" #include "app-common.h" diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 98f037f30..ce72d259f 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -48,6 +48,7 @@ #include "i18n.h" #include "sysutils.h" #include "app-common.h" +#include "iso7816.h" #include "apdu.h" #include "ccid-driver.h" #include "mkdtemp.h"