LudovicRousseau / CCID

CCID driver
https://ccid.apdu.fr/
GNU Lesser General Public License v2.1
235 stars 79 forks source link

Problem with MacOS truncated second HID packet #97

Closed makavity closed 2 years ago

makavity commented 2 years ago

Hello! I encountered a problem in which the library does not process the second HID data packet on macOS. At the same time, on Windows everything is processed correctly. I solved my problem by limiting the request to 236 bytes with Le component (excluding headers). Do I understand correctly that this issue is related to the CCID library?

You can see system logs and discussion in pcsc-rust library issue 262 bytes response in windows (Used HHD Device Monitoring Studio)

image
LudovicRousseau commented 2 years ago

HID is Human Interface Devices?

makavity commented 2 years ago

Yes, as far as reader is HID device. The protocol is CCID for smartcard communication, I mean. If I’m right.

LudovicRousseau commented 2 years ago

Smart card readers do not use HID. They use CCID only. So I don't understand your sentence "MacOS truncated second HID packet".

What smart card reader are you using? Do you reproduce the problem with a C, Objective C or Swift program? https://ludovicrousseau.blogspot.com/2010/04/pcsc-sample-in-c.html https://ludovicrousseau.blogspot.com/2017/03/pcsc-sample-in-objective-c-synchronous.html https://ludovicrousseau.blogspot.com/2015/09/pcsc-sample-in-swift.html

makavity commented 2 years ago

Okay, not HID, just second USB packet, my bad, sorry. Yes, with a C - is the same problem. Not tested with a ObjC or Swift.

Smartcard reader is the Belarus innovative technology

system_profiler SPUSBDataType output:

General Purpose USB Hub:

              Product ID: 0x2036
              Vendor ID: 0x0451  (Texas Instruments)
              Version: 1.01
              Speed: Up to 12 Mb/s
              Location ID: 0x01120000 / 5
              Current Available (mA): 500
              Current Required (mA): 0
              Extra Operating Current (mA): 0

                PN7462AU CCID:

                  Product ID: 0x0117
                  Vendor ID: 0x1fc9  (NXP Semiconductors)
                  Version: 1.01
                  Serial Number: 1.00
                  Speed: Up to 12 Mb/s
                  Manufacturer: NXP
                  Location ID: 0x01122000 / 4
                  Current Available (mA): 500
                  Current Required (mA): 500
                  Extra Operating Current (mA): 0

                HID keyboard:

                  Product ID: 0x2401
                  Vendor ID: 0x03eb  (Atmel Corporation)
                  Version: 1.00
                  Serial Number: 7CEBC1C1
                  Speed: Up to 12 Mb/s
                  Manufacturer: Atmel ASF
                  Location ID: 0x01121000 / 3
                  Current Available (mA): 500
                  Current Required (mA): 40
                  Extra Operating Current (mA): 0
LudovicRousseau commented 2 years ago

This reader is in my "Should work but untested by me" list https://ccid.apdu.fr/ccid/shouldwork.html#0x1FC90x0117

Can you share your C sample source code? What size of data do you send? What size of data do you expect?

makavity commented 2 years ago
int32_t transmit(const void *ctx_data, const Data *data, Data **response) {
    SCARDHANDLE hCard = *(SCARDHANDLE *) ctx_data;
    SCARD_IO_REQUEST pioSendPci = *SCARD_PCI_T1;

    *response = new Data;
    (*response)->len = 255;
    (*response)->data = (uint8_t *) malloc((*response)->len);

    int32_t rv = SCardTransmit(hCard, &pioSendPci,
                               data->data,
                               data->len,
                               NULL,
                               (*response)->data,
                               &(*response)->len);

    return rv;
}

int main() {
    LONG rv;

    SCARDCONTEXT hContext;
    LPTSTR mszReaders;
    SCARDHANDLE hCard;
    DWORD dwReaders, dwActiveProtocol, dwRecvLength;
    SCARD_IO_REQUEST pioSendPci;

    rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
    CHECK("SCardEstablishContext", rv)

    rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
    CHECK("SCardListReaders", rv)

    mszReaders = static_cast<LPTSTR>(calloc(dwReaders, sizeof(char)));
    rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
    CHECK("SCardListReaders", rv)

    printf("reader name: %s\n", mszReaders);

    rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED,
                      SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
    CHECK("SCardConnect", rv)

    switch (dwActiveProtocol) {
        case SCARD_PROTOCOL_T0:
            pioSendPci = *SCARD_PCI_T0;
            break;

        case SCARD_PROTOCOL_T1:
            pioSendPci = *SCARD_PCI_T1;
            break;
    }

    void *ctx = malloc(1024);
    id_kta_init_raw(&hCard, &ctx, transmit);
    id_kta_get_cok(ctx);

    return 0;
}

I am using rust ffi library, writen by me.

19 bytes transmitted, expect 262 bytes, but getting only 252. Fixed by Le component, but, windows pcsc works fine without Le.

LudovicRousseau commented 2 years ago

Your reader does NOT support extended APDU. So the maximum data you can receive is for Le = 0, i.e. 256 bytes + 2 SW bytes. You will not be able to receive 262 bytes. See https://ccid.apdu.fr/ccid_extended_apdu.html You can also consult ISO 7816-3, 12.1.3 Decoding conventions for command APDUs, page 33.

I requested your source code to know what APDU you are sending. But this information is not included in the code you attached. The Windows driver may use some non-CCID command to switch the reader in extended APDU mode.