[Pcsclite-muscle] What's responsible to filter out Le in Case 4 C-APDUs under T=0?

Francois Grieu fgrieu at gmail.com
Thu Feb 10 03:36:53 PST 2022

On 2022-02-10 et 03:42, Michael StJohns wrote :
> On 2/9/2022 3:30 PM, Francois Grieu wrote:
> >> Michael StJohns wrote :
> >>> • A case 4 APDU cannot be used. It is the responsibility of the
> >>> application or the service provider to generate a « get response »
> >>> if they need it.
> >> This is not exactly what ISO7816-3 says, but it's sort of a reasonable
> >> interpretation of how to map APDUs to TPDUs for T=0. Case 3 and Case 4
> >> APDUs have the same format for the first command TPDU.
> > Does PCSC specify the interface between the application and 
> > ScardTransmit ? I though it was one layer closer to the reader. In 
> > which case "A case 4 APDU cannot be used" would not necessarily apply 
> > to the input of ScardTransmit. 
> This is from the definition of the IFD_Transmit_to_ICC function in PCSC
> 3 - Section   Given that the CommandData definition matches up
> pretty closely with how SCardTransmit is defined (e.g. pioSendPci
> followed by pbSendBuffer)  I'd say whoever designed SCardTransmit
> probably did a pretty close mapping between the two.  (Maybe look at
> Ludovic's driver code to confirm at least one implementation?).
That makes a lot of sense, including when we look at the historical context.
I now assume SCardTransmit of winscard implements IFD_Transmit_to_ICC of PCSC 
Part 3, with a different way of passing parameters. The text
is clear that what's passed as CommandData (aka pbSendBuffer of SCardTransmit) 
is a C-APDU, but that under T=0 only Case 1, Case 2S, and Case 3S are supported.

It follows the caller of SCardTransmit is responsible to filter out Le in Case 
4S C-APDUs specifically under T=0, in effect making it case 3. That answers the 
original question.

I wish that was made apparent in the documentation of SCardTransmit
perhaps with:
SCardTransmit is passed a Command APDU, as defined in ISO/IEC 7816-3:2006 
(section 12).
If the protocol is T=0, the C-APDU should be restricted to one of
- case 1 (cbSendLength = 4) coding CLA INS P1 P2
- case 2S (cbSendLength = 5) with additional fifth byte Le
- case 3S (cbSendLength = 6 to 260) with the fifth byte Lc equal to cbSendLength-5.

SCardTransmit (both pcsclite and Windows) do not enforce that, nor perform the 
filtering of Le if passed a case 4S C-APDU (with the fifth byte Lc equal to 
cbSendLength-4, and the last byte Le).
They pass a Case 4S C-APDU (one with the fifth byte Lc equal to cbSendLength-4) 
unmodified to the driver, which can
- pass it unchanged to the interface device (both pcsclite's companion CCID 
driver and Microsoft's Usbccid WUDF driver do this for the two readers I tested),
- reject it (as the GemCCID driver 4.1.4 that motivated the question does)
- shorten it under T=0 (not observed).

   François Grieu

More information about the pcsclite-muscle mailing list