diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2020-09-25 04:24:39 +0200 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2020-09-25 04:24:39 +0200 |
commit | 93e3c97889120dd17d79b7c8dd04293553785c9b (patch) | |
tree | 3df1e86b7e82d7ed244e2421aecb2be248bad29c /scd | |
parent | scd: For SPR532, submit the ESCape command at initialization. (diff) | |
download | gnupg2-93e3c97889120dd17d79b7c8dd04293553785c9b.tar.xz gnupg2-93e3c97889120dd17d79b7c8dd04293553785c9b.zip |
scd: For PC/SC, send the ESC command at init for SPR532 reader.
* scd/apdu.c (struct reader_table_s): Remove is_spr532.
(pcsc_vendor_specific_init): Send the ESC command for SPR532.
(pcsc_pinpad_verify, pcsc_pinpad_modify): Remove no_lc hack.
--
The "no_lc" hack lets PC/SC-lite send the ESC command for SPR532
internally, for pcsc_pinpad_verify. However, PC/SC-lite doesn't do
that for pcsc_pinpad_modify, unfortunately. Besides, I'm not sure
this hack works on Windows, which has different implementation of
PC/SC service.
It's better to send the ESC command by the driver explicitly, at the
initialization. Sending the ESC command results PCSC_E_NOT_TRANSACTED
error when a card is not active (that is the case, usually). We
ignore this error.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'scd')
-rw-r--r-- | scd/apdu.c | 57 |
1 files changed, 32 insertions, 25 deletions
diff --git a/scd/apdu.c b/scd/apdu.c index 29ad0a20a..008842a55 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -130,7 +130,6 @@ struct reader_table_s { #endif /*USE_G10CODE_RAPDU*/ char *rdrname; /* Name of the connected reader or NULL if unknown. */ unsigned int is_t0:1; /* True if we know that we are running T=0. */ - unsigned int is_spr532:1; /* True if we know that the reader is a SPR532. */ unsigned int pinpad_varlen_supported:1; /* True if we know that the reader supports variable length pinpad input. */ @@ -470,7 +469,6 @@ new_reader_slot (void) reader_table[reader].pinpad_modify = pcsc_pinpad_modify; reader_table[reader].is_t0 = 1; - reader_table[reader].is_spr532 = 0; reader_table[reader].pinpad_varlen_supported = 0; reader_table[reader].require_get_status = 1; reader_table[reader].pcsc.verify_ioctl = 0; @@ -991,7 +989,16 @@ pcsc_vendor_specific_init (int slot) { if (strstr (reader_table[slot].rdrname, "SPRx32")) { - reader_table[slot].is_spr532 = 1; + const unsigned char cmd[] = { '\x80', '\x02', '\x00' }; + sw = control_pcsc (slot, CM_IOCTL_VENDOR_IFD_EXCHANGE, + cmd, sizeof (cmd), NULL, 0); + + /* Even though it's control at IFD level (request to the + * reader, not card), it returns an error when card is + * not active. Just ignore the error. + */ + if (sw) + log_debug ("Ignore control_pcsc failure.\n"); reader_table[slot].pinpad_varlen_supported = 1; } else if (strstr (reader_table[slot].rdrname, "ST-2xxx")) @@ -1060,12 +1067,21 @@ pcsc_vendor_specific_init (int slot) if (sw) return SW_NOT_SUPPORTED; } - else if (vendor == VENDOR_SCM && product == SCM_SPR532) /* SCM SPR532 */ + else if (vendor == VENDOR_SCM && product == SCM_SPR532) { - reader_table[slot].is_spr532 = 1; + const unsigned char cmd[] = { '\x80', '\x02', '\x00' }; + + sw = control_pcsc (slot, CM_IOCTL_VENDOR_IFD_EXCHANGE, + cmd, sizeof (cmd), NULL, 0); + /* Even though it's control at IFD level (request to the + * reader, not card), it returns an error when card is + * not active. Just ignore the error. + */ + if (sw) + log_debug ("Ignore control_pcsc failure.\n"); reader_table[slot].pinpad_varlen_supported = 1; } - else if (vendor == 0x046a) + else if (vendor == VENDOR_CHERRY) { /* Cherry ST-2xxx (product == 0x003e) supports TPDU level * exchange. Other products which only support short APDU level @@ -1074,11 +1090,12 @@ pcsc_vendor_specific_init (int slot) reader_table[slot].pcsc.pinmax = 15; reader_table[slot].pinpad_varlen_supported = 1; } - else if (vendor == 0x0c4b /* Tested with Reiner cyberJack GO */ - || vendor == 0x1a44 /* Tested with Vasco DIGIPASS 920 */ - || vendor == 0x234b /* Tested with FSIJ Gnuk Token */ - || vendor == 0x0d46 /* Tested with KAAN Advanced??? */ - || (vendor == 0x1fc9 && product == 0x81e6) /* Tested with Trustica Cryptoucan */) + else if (vendor == VENDOR_REINER /* Tested with Reiner cyberJack GO */ + || vendor == VENDOR_VASCO /* Tested with Vasco DIGIPASS 920 */ + || vendor == VENDOR_FSIJ /* Tested with FSIJ Gnuk Token */ + || vendor == VENDOR_KAAN /* Tested with KAAN Advanced??? */ + || (vendor == VENDOR_NXP + && product == CRYPTOUCAN) /* Tested with Trustica Cryptoucan */) reader_table[slot].pinpad_varlen_supported = 1; return 0; @@ -1278,7 +1295,6 @@ pcsc_pinpad_verify (int slot, int class, int ins, int p0, int p1, */ unsigned char result[6]; pcsc_dword_t resultlen = 6; - int no_lc; if (!reader_table[slot].atrlen && (sw = reset_pcsc_reader (slot))) @@ -1291,8 +1307,6 @@ pcsc_pinpad_verify (int slot, int class, int ins, int p0, int p1, if (!pin_verify) return SW_HOST_OUT_OF_CORE; - no_lc = (!pininfo->fixedlen && reader_table[slot].is_spr532); - pin_verify[0] = 0x00; /* bTimeOut */ pin_verify[1] = 0x00; /* bTimeOut2 */ pin_verify[2] = 0x82; /* bmFormatString: Byte, pos=0, left, ASCII. */ @@ -1309,8 +1323,8 @@ pcsc_pinpad_verify (int slot, int class, int ins, int p0, int p1, pin_verify[11] = 0x00; /* bMsgIndex */ pin_verify[12] = 0x00; /* bTeoPrologue[0] */ pin_verify[13] = 0x00; /* bTeoPrologue[1] */ - pin_verify[14] = pininfo->fixedlen + 0x05 - no_lc; /* bTeoPrologue[2] */ - pin_verify[15] = pininfo->fixedlen + 0x05 - no_lc; /* ulDataLength */ + pin_verify[14] = pininfo->fixedlen + 0x05; /* bTeoPrologue[2] */ + pin_verify[15] = pininfo->fixedlen + 0x05; /* ulDataLength */ pin_verify[16] = 0x00; /* ulDataLength */ pin_verify[17] = 0x00; /* ulDataLength */ pin_verify[18] = 0x00; /* ulDataLength */ @@ -1321,8 +1335,6 @@ pcsc_pinpad_verify (int slot, int class, int ins, int p0, int p1, pin_verify[23] = pininfo->fixedlen; /* abData[4] */ if (pininfo->fixedlen) memset (&pin_verify[24], 0xff, pininfo->fixedlen); - else if (no_lc) - len--; if (DBG_CARD_IO) log_debug ("send secure: c=%02X i=%02X p1=%02X p2=%02X len=%d pinmax=%d\n", @@ -1353,7 +1365,6 @@ pcsc_pinpad_modify (int slot, int class, int ins, int p0, int p1, int len = PIN_MODIFY_STRUCTURE_SIZE + 2 * pininfo->fixedlen; unsigned char result[6]; /* See the comment at pinpad_verify. */ pcsc_dword_t resultlen = 6; - int no_lc; if (!reader_table[slot].atrlen && (sw = reset_pcsc_reader (slot))) @@ -1366,8 +1377,6 @@ pcsc_pinpad_modify (int slot, int class, int ins, int p0, int p1, if (!pin_modify) return SW_HOST_OUT_OF_CORE; - no_lc = (!pininfo->fixedlen && reader_table[slot].is_spr532); - pin_modify[0] = 0x00; /* bTimeOut */ pin_modify[1] = 0x00; /* bTimeOut2 */ pin_modify[2] = 0x82; /* bmFormatString: Byte, pos=0, left, ASCII. */ @@ -1395,8 +1404,8 @@ pcsc_pinpad_modify (int slot, int class, int ins, int p0, int p1, pin_modify[16] = 0x02; /* bMsgIndex3 */ pin_modify[17] = 0x00; /* bTeoPrologue[0] */ pin_modify[18] = 0x00; /* bTeoPrologue[1] */ - pin_modify[19] = 2 * pininfo->fixedlen + 0x05 - no_lc; /* bTeoPrologue[2] */ - pin_modify[20] = 2 * pininfo->fixedlen + 0x05 - no_lc; /* ulDataLength */ + pin_modify[19] = 2 * pininfo->fixedlen + 0x05; /* bTeoPrologue[2] */ + pin_modify[20] = 2 * pininfo->fixedlen + 0x05; /* ulDataLength */ pin_modify[21] = 0x00; /* ulDataLength */ pin_modify[22] = 0x00; /* ulDataLength */ pin_modify[23] = 0x00; /* ulDataLength */ @@ -1407,8 +1416,6 @@ pcsc_pinpad_modify (int slot, int class, int ins, int p0, int p1, pin_modify[28] = 2 * pininfo->fixedlen; /* abData[4] */ if (pininfo->fixedlen) memset (&pin_modify[29], 0xff, 2 * pininfo->fixedlen); - else if (no_lc) - len--; if (DBG_CARD_IO) log_debug ("send secure: c=%02X i=%02X p1=%02X p2=%02X len=%d pinmax=%d\n", |