Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add kapelse readers support in COMPOSITE_AS_MULTISLOT mode #118

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/ccid.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ typedef struct
*/
int IFD_bcdDevice;

#ifdef USE_COMPOSITE_AS_MULTISLOT
int max_num_interfaces;
#endif

/*
* Gemalto extra features, if any
*/
Expand Down Expand Up @@ -257,7 +261,10 @@ typedef struct
#define ACS_ACR1252 0x072F223B
#define ACS_ACR1252IMP 0x072F2259
#define ACS_ACR1552 0x072F2303
#define KAPELSE_KAPLIN2 0x29470105
#define KAPELSE_KAPECV 0x29470112

#define VENDOR_KAPELSE 0x2947
#define VENDOR_GEMALTO 0x08E6
#define GET_VENDOR(readerID) ((readerID >> 16) & 0xFFFF)

Expand Down
37 changes: 37 additions & 0 deletions src/ccid_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,39 @@ status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
}
#endif

#ifdef USE_COMPOSITE_AS_MULTISLOT
if (VENDOR_KAPELSE == GET_VENDOR(readerID))
{
switch (readerID)
{
case KAPELSE_KAPECV :
LudovicRousseau marked this conversation as resolved.
Show resolved Hide resolved
/* KAP-eCV : only first interface is a ccid one */
max_interface_number=0;
DEBUG_INFO1("Kapelse reader forced as monoslot!");
break;

case KAPELSE_KAPLIN2 :
/* KAP&LINK2 : only 3 first interfaces are ccid ones */
if(config_desc->bNumInterfaces > 3)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this test?
In my list the KAP-LINK2 has 3 CCID interfaces https://ccid.apdu.fr/ccid/shouldwork.html#0x29470x0105

Do you have another model with a different configuration but using the same idProduct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is needed as KAP-LINK2 is a USB composite device presenting either 3 CCID interfaces or 3 CCID interfaces (the 3 first ones) and a CDC-ACM interface according user configuration

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see.
It should work fine if you something like use:

max_interface_number = 3; /* up to 4 interfaces */
num_CCID_interfaces = 3;  /* 3 CCID interfaces */

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bmoraine Is it possible for the KAP-LINK2 to NOT have 3 CCID interfaces?

Why can't we use max_interface_number = 2; in all cases without checking the value of config_desc->bNumInterfaces?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LudovicRousseau Effectively, KAP-LINK2 has always 3 CCID interfaces (the 3 first ones) and an optional 4th CDC-ACM interface. So, you are right, we can use max_interface_number = 2; in all cases without checking the value of config_desc->bNumInterfaces

{
max_interface_number=2;
DEBUG_INFO1("Kapelse reader restricted as multislot with 3 slots!");
}
else
{
max_interface_number=config_desc->bNumInterfaces-1;
DEBUG_INFO2("Kapelse reader forced as multislot with %d slots!",max_interface_number+1);
}
break;

default :
/* Kapelse : all interfaces are ccid ones */
max_interface_number=config_desc->bNumInterfaces-1;
DEBUG_INFO2("Kapelse reader forced as multislot with %d slots!",max_interface_number+1);
break;
}
}
#endif

usb_interface = get_ccid_usb_interface(config_desc, &num);
if (usb_interface == NULL)
Expand Down Expand Up @@ -723,6 +756,7 @@ status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
|| (ACS_ACR1252 == readerID)
|| (ACS_ACR1252IMP == readerID)
|| (ACS_ACR1552 == readerID)
|| (VENDOR_KAPELSE == GET_VENDOR(readerID))
|| (FEITIANR502DUAL == readerID))
{
/* use the next interface for the next "slot" */
Expand Down Expand Up @@ -751,6 +785,9 @@ status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
usbDevice[reader_index].disconnected = false;

/* CCID common information */
#ifdef USE_COMPOSITE_AS_MULTISLOT
usbDevice[reader_index].ccid.max_num_interfaces = max_interface_number + 1;
#endif
usbDevice[reader_index].ccid.real_bSeq = 0;
usbDevice[reader_index].ccid.pbSeq = &usbDevice[reader_index].ccid.real_bSeq;
usbDevice[reader_index].ccid.readerID =
Expand Down
26 changes: 1 addition & 25 deletions src/ifdhandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,31 +466,7 @@ EXTERNAL RESPONSECODE IFDHGetCapabilities(DWORD Lun, DWORD Tag,
*Value = 1 + get_ccid_descriptor(reader_index) -> bMaxSlotIndex;
#ifdef USE_COMPOSITE_AS_MULTISLOT
{
/* On MacOS X or Linux+libusb we can simulate a
* composite device with 2 CCID interfaces by a
* multi-slot reader */
int readerID = get_ccid_descriptor(reader_index) -> readerID;

/* 2 CCID interfaces */
if ((GEMALTOPROXDU == readerID)
|| (GEMALTOPROXSU == readerID)
|| (ALCOR_LINK_AK9567 == readerID)
|| (ALCOR_LINK_AK9572 == readerID)
|| (ACS_WALLETMATE == readerID)
|| (ACS_ACR1251 == readerID)
|| (ACS_ACR1252 == readerID)
|| (ACS_ACR1252IMP == readerID)
|| (ACS_ACR1552 == readerID)
|| (HID_OMNIKEY_5422 == readerID))
*Value = 2;

/* 3 CCID interfaces */
if (ACS_ACR1581 == readerID)
*Value = 3;

/* 4 CCID interfaces */
if (FEITIANR502DUAL == readerID)
*Value = 4;
*Value = get_ccid_descriptor(reader_index) -> max_num_interfaces;
}
#endif
DEBUG_INFO2("Reader supports %d slot(s)", *Value);
Expand Down