mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
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>
This commit is contained in:
parent
4fae55f8ee
commit
93e3c97889
57
scd/apdu.c
57
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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user