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 <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2020-09-24 17:05:13 +09:00
parent 1835097561
commit 7cbb513a2d
1 changed files with 36 additions and 3 deletions

View File

@ -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;