I have 4 different types of JavaCards. For a weird purpose, I wrote the following applet to return whole the APDU buffer on reception of each APDU command:
p
Nothing is wrong with your cards. Actually, the three "T=0" cards respond as "expected". It's rather the "T=1" card / JCOP that returns unexpected results.
You are sending the following APDUs:
00A404000B0102030405060708090101
00000000
00000000020101
The first and the third are case-3 APDUs (Lc and command DATA field present, Le field absent). The second APDU is a case-1 APDU (only command header, but no Lc, DATA and LE fields present). Hence, all three APDUs clearly indicate that no response data field should be returned. Consequently, you should never call setOutgoing*()
methods for such commands. Note that the Java Card API specification is quite clear on this and clearly states that calling setOutgoing*()
on case-1/case-3 commands may lead to unexpected/wrong behavior:
This method should only be called on a case 2 or case 4 command, otherwise erroneous behavior may result.
Thus, you should always check what command case you have and only receive/respond data when it is appropriate (you can typically determine this based on the instruction code, since you know what you would expect for each instruction).
Why the case-1 APDU works as you expect (i.e. returns a response data field) has to do with the format of T=0 TPDUs and the way that APDUs are mapped that format. A T=0 TPDU has the format
CLA INS P1 P2 P3 [DATA]
The P3 field is always present, while the DATA field is only present for case-3 APDUs. The following mapping between TPDU and APDU is applied:
As you see, the P3 field is filled with zero for case-1 APDUs. This means that the card cannot distinguish between a case-2 APDU with Le = 0 and a case-1 APDU. As a result, with T=0, any case-1 APDU will be treatd as a case-2 APDU. Consequently, the setOutgoingAndSend()
method will work for the case-1 APDU (00000000
in your case).