[Pcsclite-muscle] What's responsible to filter out Le in Case 4 C-APDUs under T=0?
fgrieu at gmail.com
Tue Feb 8 08:29:51 PST 2022
On 2022-02-08 14:44, Bruno Jesus wrote:
> On Tue, Feb 8, 2022 at 6:59 AM Francois Grieu <fgrieu at gmail.com> wrote:
> <snip>t is there an authoritative reference that it's
> valid for an application to send complete C-APDU (thus including Le in
> case 4S)
> to SCardTransmit? And perhaps one that it's not SCardTransmit's job to
> remove Le
> under T=0?
> I believe there is a mix of concepts about T=0, T=1 and APDU commands. On T=0
> there is no DATA+LE, T=0 is half-duplex, it either sends data or receives
> responses. On T=1 you can send data and request a response length at the same
> command since it uses a different approach to transmit data.
Per ISO/IEC 7816-3:2006 section 12, in case 4 (that is APDUs with data to and
from the card), the Command APDU includes Le, regardless of the protocol.
Quoting 12.3.1 about "Decoding conventions for command APDUs (..) Case 4S ⎯ The
short Lc field consists of C(5) ≠ '00', encoding Nc from 1 to 255. The data
field consists of C(6) to C(5+Nc). The short Le field consists of C(6+Nc)
encoding Ne from 1 to 256 ('00' means the maximum, 256)."
> Just to add context: On T=0 if the command has 5 bytes the P3 is the "LE" and
> for commands with more than 5 bytes the P3 is always the LC and the extra
> bytes are command data. For example:
> 00C0000010 -> 10 is the LE.
> 00B2000004 00000000 -> the 04 is the LC followed by data.
> On T=0 for APDU with data (LC > 0) the transfer direction is switched after
> sending the amount of data pointed at P3, so it can't receive the LE, sending
> the LE (or any other extra bytes not accounted at LC) would mix the extra bits
> being sent with a response being received. If you have the ISO IEC 7816-4
> document you can check the Annex A (Transportation of APDU messages by T=0)
> and B (Transportation of APDU messages by T=1).
That's what there is at the TPDU level (Transport Protocol Data Unit). The
mapping from APDU to TPDU is explained in section 12.2 for T=0, 12.3 for T=1.
The physical level has some more bytes.
> My answer to the original questions would be that it is up to the caller to
> know the protocol it is using and format the commands correctly. I wouldn't
> expect a driver to "fix" the command by removing the LE since you requested it
> to be sent, I believe some drivers may be sending 5 + P3 value instead of
> sending the size received by SCardTransmit, thus hiding the problem (e.g
> 00B2000001 00 00 would send 5 + 1 and not 7).
> About the question on how to fix this on the client side it is not difficult.
> When doing SCardConnect you can request the protocols supported and as a
> response you will receive the one actually in use. You can use this to
> properly format the commands by not adding LE to T=0. To account for the
> missing LE the T=0 has the 61XX status word. Always check the 61XX SW and
> transmit the GET RESPONSE command. Then all remaining code is the same for T=0
> and T=1 at the PCSC level.
In essence, the suggestion is to pass SCardTransmit a C-TPDU, rather than a
C-APDU as I do. That's feasible, and fixes the problem I'm having with this
particular driver. However:
- I don't know any specification suggesting to do this. It's not necessary in
most contexts I've used SCardTransmit with, including pcsclite, and Windows
except with one of >12 drivers I practice. If it was generally deemed necessary,
I'd expect a plethora of standard wrappers on top of SCardConnect and
ScardTransmit for that conditional stripping of Le, but Javax.smartcardio is the
only such wrapper I know of.
- At least in cases 1, 2(S) and 3(S), the cbSendLength parameter of
SCardTransmit is the length of the C-APDU, and in case 1 that differs from the
length of the first C-TPDU: the spec (
) requires that "For T=0, in the special case where no data is sent to the card
and no data expected in return", cbSendLength is set to 4. This suggests
ScardTransmit is designed to receive C-APDUs, not C-TPDUs.
- I fear that it could cause issue with some hypothetical readers, either ISO
14443 contactless readers disguising as T=0, or readers capable of T=0 which
incorporate the full APDU to TPDU translation layer (I admit I never met any
CCID reader/driver doing either ).
So: is there some authoritative source on if and when ScardTransmit requires Le
in a C-APDU to be stripped from it's input by the caller ?
More information about the pcsclite-muscle