Using javax.smartcardio classes for smartcard programming, I encountered a persistent error - getting back 6700 (invalid length) and similar error codes from the card when the code looked fine. Example code:
req = new CommandAPDU(0x00, 0xA4, 0x04, 0x00, aid, 0x00);
This is supposed to construct a case 4 APDU. Why does the card respond as if I were missing something?
Short answer
Use
aid, 0x100
instead ofaid, 0x00
.Long answer (better get some coffee):
That's because of the confusion between
Ne
andLe
.Ne
is the maximum amount of bytes that can be returned to the terminal.Ne
is a number without specific representation.Le
however is the encoding or representation in bytes ofNe
.Now for ISO/IEC 7816-4 there is a little trick:
Le
is absent (no bytes) in case of an ISO case 1 or 3 command without response data (RDATA). So definingLe = 00
to mean "no response data" is spurious. Instead 7816-4 usesLe = 00
to meanNe = 256
. Similarly,Le = 0000
(orLe = 000000
) meansNe = 65536
, i.e. 2^16. The double and triple byte encoding are only used for extended length APDU's.As you can see in the
CommandAPDU
constructor however you have to specifyNe
, notLe
. What you specify is therefore the same as saying that there is no response data. So the APDU will not be interpreted correctly as an ISO case 4 and the command will fail (correctly in this case,6700
is exactly what you should expect).So just specify how many bytes you expect. If the value is larger than 256 then an extended length APDU will be required (or command chaining, but that's a topic in itself).
Ne < 0
orNe > 64Ki
is of course not supported.Note that many protocol descriptions including the Java Card API got the distinction between
Ne
andLe
wrong (this has been fixed in the Java Card API v3.0.5 by the way). That's kind of strange as there are many many issues with 7816-4, but this is not one of them. It's specified pretty clearly.