1

I'm trying to set the CommandAPDU buffer with a byte array. However, if the length is >7, it throws the following error:

Exception in thread "main" java.lang.IllegalArgumentException: Invalid APDU: length=8, b1=1 at javax.smartcardio.CommandAPDU.parse(CommandAPDU.java:318) at javax.smartcardio.CommandAPDU.(CommandAPDU.java:98) at terminal.Main.main(Main.java:78)

My code:

byte terminal = 0x00;
byte instruction = 0x01;
byte [] msg = {0x01,0x00,0x01,0x00};
byte [] fullmsg = new byte[msg.length + 4];
System.arraycopy(new byte []{terminal}, 0, fullmsg, 0, 1);
System.arraycopy(new byte [] {instruction}, 0, fullmsg, 1, 1);
System.arraycopy(new byte [] {0,0}, 0, fullmsg, 2, 2);
System.arraycopy(msg, 0, fullmsg, 4, msg.length);
CommandAPDU cmdapdu = new CommandAPDU(fullmsg);

Can someone help me out?

Cees Mandjes
  • 195
  • 12
  • That code is hardly readable. vlp already posted a perfect answer for this, but if you ever write code like that then 1. use an `offset` variable (and `++` or `+= 2`) 2. use constants for specific byte values (also for use within vlp's answer) and 3. please write a comment on *what* the code line is doing, because currently it is not easy to extract any meaning from the code. And the code failed because you forgot to write the fifth `Lc` byte which encodes the length of the command data, known as `Nc`. – Maarten Bodewes Jul 03 '18 at 21:48
  • Oh, and the byte before the INStruction byte is called the CLAss byte, not the *terminal* byte. – Maarten Bodewes Jul 03 '18 at 21:49

1 Answers1

3

Consider using CommandAPDU(int cla, int ins, int p1, int p2, byte[] data) (if you do not expect any data in return from card -- i.e. command is ISO-7816 case 3) or CommandAPDU(int cla, int ins, int p1, int p2, byte[] data, int ne) (if you expect some data in return from card -- i.e. command is ISO-7816 case 4) to create your CommandAPDU object.

See ISO 7816-3, section 12.1 "Application protocol data units" for further details on Command APDU formats (partially available here).

E.g.:

CommandAPDU cmdapdu = new CommandAPDU(terminal, instruction, 0, 0, msg);

or (feel free to replace 256 with any other expected length of response data):

CommandAPDU cmdapdu = new CommandAPDU(terminal, instruction, 0, 0, msg, 256);

Good luck!

vlp
  • 7,811
  • 2
  • 23
  • 51