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, 0x100instead ofaid, 0x00.Long answer (better get some coffee):
That's because of the confusion between
NeandLe.Neis the maximum amount of bytes that can be returned to the terminal.Neis a number without specific representation.Lehowever is the encoding or representation in bytes ofNe.Now for ISO/IEC 7816-4 there is a little trick:
Leis absent (no bytes) in case of an ISO case 1 or 3 command without response data (RDATA). So definingLe = 00to mean "no response data" is spurious. Instead 7816-4 usesLe = 00to 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
CommandAPDUconstructor 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,6700is 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 < 0orNe > 64Kiis of course not supported.Note that many protocol descriptions including the Java Card API got the distinction between
NeandLewrong (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.