3
votes

In case of T=0 protocol, the TPDU of case 1 & case 2 APDUs and case 3 and case 4 APDUs are the same, therefore, in the case of T=0 protocol from the smart card side it is not possible to distinguish between case 1&2 and case 3&4 APDUs. In fact, it is not even possible to distinguish between case 2 & 3 APDU, unless smart card tries to read the data bytes, which will lead to failure if the actual APDU send by the terminal was case 2 APDU.

However, since in T=1 protocol the TPDU corresponds to APDU the card knows to which case the APDU received belongs.

The question is does the Java Card API provides any means in case of T=1 protocol to:

  1. know if the received APDU is data APDU and hence setIncomingAndReceive() can be called safely;
  2. read the Le byte from case 4 APDU;
  3. know if Le byte was actually received from the terminal (in the ambiguous case where P3 in APDU buffer is 0x00).
1

1 Answers

1
votes

1. know if the received APDU is data APDU and hence setIncomingAndReceive() can be called safely

Now this is an interesting one; it seems that getIncomingLength could be used for that:

the incoming byte length indicated by the Lc field in the APDU header. Return 0 if no incoming data (Case 1)

but it says itself in the exception description that:

APDUException.ILLEGAL_USE if setIncomingAndReceive() not called or if setOutgoing() or setOutgoingNoChaining() previously invoked.

And for setIncomingAndReceive() you can read that:

This method should only be called on a case 3 or case 4 command, otherwise erroneous behavior may result.

There seems to be a catch 22 here; I'll ask one of my resources on how to deal with this. In the mean time, it is unlikely (but not impossible) that setIncomingAndReceive or getIncomingLength throws an exception for case 1 or 2 APDUs.


2. read the Le byte from case 4 APDU

Well, yes, by reading the Nc value, then progress through the received bytes to get to the Le byte or bytes that follow the command. But generally it is easier to use Ne (the actual length rather than the encoding of the length) by calling setOutgoing which returns:

Ne, the expected length of response

3. know if Le byte was actually received from the terminal (in the ambiguous case where P3 in APDU buffer is 0x00)

If P3 = 0x00 then P3 is the Le byte as far as I know. I don't see how that is ambiguous. Lc is prohibited from having this value.


Notes:

  • most APDU commands have a pre-described format, so you know in advance (during processing of the APDU using the process method) if you should get a specific case - you can throw an exception you do not;
  • I've referenced Java Card 3.0.5 because it is available online and because it correctly distinguises between Nc, Lc, Ne and Le - the interface is however not different from earlier versions.