diff options
author | NIIBE Yutaka <[email protected]> | 2020-09-24 08:05:13 +0000 |
---|---|---|
committer | NIIBE Yutaka <[email protected]> | 2020-09-24 08:05:13 +0000 |
commit | 7cbb513a2dc150a90a30c53316970df2a439d494 (patch) | |
tree | e34c7ebbb4285f11921344858c01037e1d32aff2 /scd/ccid-driver.c | |
parent | gpg: Set the found-by flags in the keyblock in keyboxd mode. (diff) | |
download | gnupg-7cbb513a2dc150a90a30c53316970df2a439d494.tar.gz gnupg-7cbb513a2dc150a90a30c53316970df2a439d494.zip |
scd: Fix CCID internal driver for interrupt transfer.
* scd/ccid-driver.c (intr_cb): Handle the case of multiple messages.
--
SPR532 USB Smart Card Reader (also know as SPR332) may send two
messages at once for a single interrupt transfer. An example transfer
observed was like: 50 03 50 02, which is considered valid, according
to the CCID specification.
GnuPG-bug-id: 5065
Signed-off-by: NIIBE Yutaka <[email protected]>
Diffstat (limited to 'scd/ccid-driver.c')
-rw-r--r-- | scd/ccid-driver.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 4f21baf1a..ee4a5b356 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -1490,9 +1490,42 @@ intr_cb (struct libusb_transfer *transfer) } else if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { - if (transfer->actual_length == 2 - && transfer->buffer[0] == 0x50 - && (transfer->buffer[1] & 1) == 0) + size_t len = transfer->actual_length; + unsigned char *p = transfer->buffer; + int card_removed = 0; + + while (len) + { + if (*p == RDR_to_PC_NotifySlotChange) + { + if (len < 2) + break; + + if ((p[1] & 1)) + card_removed = 0; + else + card_removed = 1; + + p += 2; + len -= 2; + } + else if (*p == RDR_to_PC_HardwareError) + { + if (len < 4) + break; + + DEBUGOUT_1 ("CCID: hardware error detected: %02x\n", p[3]); + p += 4; + len -= 4; + } + else + { + DEBUGOUT_1 ("CCID: unknown intr: %02x\n", p[0]); + break; + } + } + + if (card_removed) { DEBUGOUT ("CCID: card removed\n"); handle->powered_off = 1; |