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.