aboutsummaryrefslogtreecommitdiffstats
path: root/scd/ccid-driver.c
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2020-09-24 08:05:13 +0000
committerNIIBE Yutaka <[email protected]>2020-09-24 08:05:13 +0000
commit7cbb513a2dc150a90a30c53316970df2a439d494 (patch)
treee34c7ebbb4285f11921344858c01037e1d32aff2 /scd/ccid-driver.c
parentgpg: Set the found-by flags in the keyblock in keyboxd mode. (diff)
downloadgnupg-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.c39
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;