acshk / acsccid

acsccid is a PC/SC driver for Linux/Mac OS X and it supports ACS CCID smart card readers. This library provides a PC/SC IFD handler implementation and communicates with the readers through the PC/SC Lite resource manager (pcscd).
GNU Lesser General Public License v2.1
104 stars 19 forks source link

ACR33U - CCID_Receive() Can't read all data 49174kbytes #19

Closed vjardin closed 1 year ago

vjardin commented 4 years ago

Hi,

When using the: 00000024 hotplug_libudev.c:436:HPAddDevice() Adding USB device: ACS ACR33U-A1 3SAM ICC Reader 00000028 readerfactory.c:1075:RFInitializeReader() Attempting startup of ACS ACR33U-A1 3SAM ICC Reader 00 00 using /usr/lib/pcsc/drivers/ifd-acsccid.bundle/Contents/Linux/libacsccid.so 00072079 ccid_usb.c:754:OpenUSBByName() Found Vendor/Product: 072F/8300 (ACS ACR33U-A1 3SAM ICC Reader)

it cannot support some French pkcs11 card because of: 00000046 APDU: 00 A4 09 04 04 3F 00 D0 03 00000046 ifdhandler.c:1640:IFDHTransmitToICC() usb:072f/8300:libudev:0:/dev/bus/usb/001/011 (lun: 0) 00030608 commands.c:1678:CCID_Receive() Can't read all data (49174 out of 2 expected) 00000037 SW: 00000003 ifdwrapper.c:543:IFDTransmit() Card not transacted: 612 00000003 winscard.c:1620:SCardTransmit() Card not transacted: 0x80100016

It guess because the driver does not support some Extended APDU.

Should you need more log, feel free to ask.

Best regards, Vincent

vjardin commented 4 years ago

I guess, this trace is more explicit and it should help: 00000008 winscard_svc.c:562:ContextThread() BEGIN_TRANSACTION rv=0x0 for client 15 00000192 winscard_svc.c:362:ContextThread() Received command: TRANSMIT from client 15 00000056 readerfactory.c:848:RFReaderInfoById() RefReader() count was: 1 00000050 winscard.c:1595:SCardTransmit() Send Protocol: T=0 00000046 APDU: 00 A4 09 04 04 3F 00 D0 03 00000046 ifdhandler.c:1640:IFDHTransmitToICC() usb:072f/8300:libudev:0:/dev/bus/usb/001/011 (lun: 0) 00030608 commands.c:1678:CCID_Receive() Can't read all data (49174 out of 2 expected) 00000037 SW: 00000003 ifdwrapper.c:543:IFDTransmit() Card not transacted: 612 00000003 winscard.c:1620:SCardTransmit() Card not transacted: 0x80100016

godfreychung commented 4 years ago

Please use the following command to log CCID command/response: sudo LIBCCID_ifdLogLevel=0x0007 pcscd -fd | tee log.txt

vjardin commented 4 years ago

Enclosed an extract: 00000001 winscard_svc.c:562:ContextThread() BEGIN_TRANSACTION rv=0x0 for client 14 00000121 winscard_svc.c:362:ContextThread() Received command: TRANSMIT from client 14 00000030 readerfactory.c:848:RFReaderInfoById() RefReader() count was: 1 00000002 winscard.c:1595:SCardTransmit() Send Protocol: T=0 00000003 ifdhandler.c:1640:IFDHTransmitToICC() usb:072f/8300:libudev:0:/dev/bus/usb/001/011 (lun: 0) 00000002 commands.c:1726:CmdXfrBlockAPDU_short() T=0: 9 bytes 00000003 -> 000000 6F 09 00 00 00 00 2D 00 00 00 00 A4 09 04 04 3F 00 D0 03 00033873 <- 000000 80 02 00 00 00 00 2D 00 00 00 61 27 00 00 00 00 00 00 00 [...] 00002330 commands.c:1682:CCID_Receive() Can't read all data (49174 out of 2 expected) 00000015 ifdwrapper.c:543:IFDTransmit() Card not transacted: 612 00000003 winscard.c:1620:SCardTransmit() Card not transacted: 0x80100016

Should you want the full log, I can direct mail it to you.

I guess, the dwFeatures is relevant too: 00069337 ccid_usb.c:754:OpenUSBByName() Found Vendor/Product: 072F/8300 (ACS ACR33U-A1 3SAM ICC Reader) 00000027 ccid_usb.c:756:OpenUSBByName() Using USB bus/device: 1/11 00000003 ccid_usb.c:934:OpenUSBByName() bNumDataRatesSupported is 0 00003889 ccid_usb.c:1941:Multi_PollingProc() Multi_PollingProc (1/11): thread starting 00000029 ccid_usb.c:1948:Multi_PollingProc() Multi_PollingProc (1/11): waiting 00100205 -> 000000 65 00 00 00 00 00 00 00 00 00 00003964 <- 000000 81 00 00 00 00 00 00 01 00 01 00000026 ifdhandler.c:333:CreateChannelByNameOrChannel() dwFeatures: 0x000204B0 00000002 ifdhandler.c:334:CreateChannelByNameOrChannel() wLcdLayout: 0x0000 00000001 ifdhandler.c:335:CreateChannelByNameOrChannel() bPINSupport: 0x03 00000001 ifdhandler.c:336:CreateChannelByNameOrChannel() dwMaxCCIDMessageLength: 271

It is just a guess: it gets called for a short APDU:

                case CCID_CLASS_SHORT_APDU:
                        ccid_descriptor -> readTimeout = 0;     // Infinite
                        return_value = CmdXfrBlockAPDU_short(reader_index,
                                tx_length, tx_buffer, rx_length, rx_buffer);
                        break;

instead of the EXTENDED one:

                case CCID_CLASS_EXTENDED_APDU:
                        ccid_descriptor -> readTimeout = 0;     // Infinite
                        return_value = CmdXfrBlockAPDU_extended(reader_index,
                                tx_length, tx_buffer, rx_length, rx_buffer);
                        break;

Since:

#define CCID_CLASS_SHORT_APDU           0x00020000
#define CCID_CLASS_EXTENDED_APDU        0x00040000

while: 00000026 ifdhandler.c:333:CreateChannelByNameOrChannel() dwFeatures: 0x000204B0

best regards,

godfreychung commented 4 years ago
00000002 commands.c:1726:CmdXfrBlockAPDU_short() T=0: 9 bytes
00000003 -> 000000 6F 09 00 00 00 00 2D 00 00 00 00 A4 09 04 04 3F 00 D0 03
00033873 <- 000000 80 02 00 00 00 00 2D 00 00 00 61 27 00 00 00 00 00 00 00
[...]
00002330 commands.c:1682:CCID_Receive() Can't read all data (49174 out of 2 expected)

According to the log, the response should be correct but the reader added too many zeros to the response. The actual response APDU is 61 27.

Line 1674 in commands.c

/* we have read less (or more) data than the CCID frame says to contain */
if (length-10 != dw2i(cmd, 1))
{
    DEBUG_CRITICAL3("Can't read all data (%d out of %d expected)",
        length-10, dw2i(cmd, 1));
    return_value = IFD_COMMUNICATION_ERROR;
}

After reviewing the code, I found that it may be too strict (!= instead of <) to check the data length from CCID response. I think that the following modification can solve the issue:

if (length-10 < dw2i(cmd, 1))

Can you try it and report the result?

vjardin commented 4 years ago

Thanks for your comment. Your fix solved the problem. I was able to run a full pkcs11-dump on the card.

I hope my pull request is good enough.

godfreychung commented 4 years ago

Yes, I merged your pull request. Thanks!

vjardin commented 4 years ago

Thanks. Please, can you streamline it for the Ubuntu 18.04 distributions ?

godfreychung commented 4 years ago

Let me review the side effect of code modification before submitting a bug report to Ubuntu.

In the meantime, can you provide your test environment to reproduce the issue?

LudovicRousseau commented 4 years ago

@godfreychung I rejected this patch in my driver because the problem happens only in a virtual machine host. I guess the problem comes for the virtualization software, not the CCID driver or the reader.

See https://github.com/LudovicRousseau/CCID/pull/67