2

I am trying to learn Java Card. I have just started and have not found many resources. My first question is how to understand APDU commands. (such as those defined in ISO/IEC 7816-4)

For example, if I see a byte pattern such as 10101010 how can I understand the meaning of this, and in particular determine the CLA or INS, for example?

TT--
  • 2,956
  • 1
  • 27
  • 46
user366312
  • 16,949
  • 65
  • 235
  • 452

2 Answers2

20

APDU commands are a queue of binary numbers in the following form:

CLA | INS | P1 | P2 | Lc | CData | Le

The first four sections, i.e CLA , INS , P1 and P2 are mandatory in all APDU commands and each one has one byte length. These one-byte-length sections stand for Class, Instruction, Parameter1 and Parameter2 respectively.

The last three sections, i.e Lc , CData and Le are optional.Lc is the encoding of Nc, which is the encoding of the length of the CDATA field. Le is the encoding of Ne, then encoding of the maximum response data that may be send. Based on presence or absence of these sections, we have 4 case for APDU commands, as below:

  • Case1: CLA | INS | P1 | P2
  • Case2: CLA | INS | P1 | P2 | Le
  • Case3: CLA | INS | P1 | P2 | Lc | Data
  • Case4: CLA | INS | P1 | P2 | Lc | Data | Le

The length of CData is different for different commands and different applets. based on the length of CData (i.e Lc) and the length of maximum response data that may send (i.e Le), we have to type of APDU commands:

  • Normal/Short APDU commands, when Lc and Le are smaller than 0xFF
  • Extended length APDU commands, when Lc and/or Le are greater than 0xFF.

So for the length of these sections we have:

Lc : 1 byte for Short APDU commands and 3 byte (they specify this length, because its enough) for Extended APDU commands.

Data : Different lengths.

Le : Same as Lc.


How can I understand APDU commands?

Answer:

When you write an applet, you specify the response of your applet to different APDU commands that it will receive in the future. Card Manager is an applet also. The commands that it support is defined in your card's specifications/datasheet. Normally almost all cards are GlobalPlatform and ISO7816 compliant, so they must support those mandatory APDU commands that is defined in these documents. For example, as 0xA4 is defined as SELECT FILE command in ISO7816-4 standard, If you see an APDU like xx A4 xx xx is sending to Card Manager, you can conclude that it is related with SELECT FILE.

Note that you can choose one value for different functions in your different applets. For example in the following, Applet1 will return 0x6990 in the reception of 00 B0 xx xx APDU commands, while Applet2 will return 0x6991 in the reception of the same command:

Applet1:

public class SOQ extends Applet {

    private SOQ() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new SOQ().register();
    }

    public void process(APDU arg0) throws ISOException {
        byte buffer[] = arg0.getBuffer();
        
        if(buffer[ISO7816.OFFSET_CLA] == (byte) 0x00 &&buffer[ISO7816.OFFSET_INS] == (byte) 0xB0){
            ISOException.throwIt((short)0x6990);
        }

    }

}

Output:

OpenSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00B00000 -s 00B00
100
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x90)
Sending: 00 B0 00 00
Received (SW1=0x69, SW2=0x90)
Sending: 00 B0 01 00
Received (SW1=0x69, SW2=0x90)

Applet2:

public class SOQ extends Applet {

    private SOQ() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new SOQ().register();
    }

    public void process(APDU arg0) throws ISOException {
        byte buffer[] = arg0.getBuffer();
        
        if(buffer[ISO7816.OFFSET_CLA] == (byte) 0x00 && buffer[ISO7816.OFFSET_INS] == (byte) 0xB0){
            ISOException.throwIt((short)0x6991);
        }

    }

}

Output:

OpenSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00B00000 -s 00B00
100
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x00)
Sending: 00 B0 00 00
Received (SW1=0x69, SW2=0x91)
Sending: 00 B0 01 00
Received (SW1=0x69, SW2=0x91)

So the final and short answer to your question (How can I understand APDU commands?) is:

  • You are dealing with your applet?

    You defined the supported commands and their forms, yourself!

  • You are dealing with another applet (Card Manager, for example)?

    You need the source code of that applet or its documentation about its supported commands and their forms or the standard/specification that that applet is compliant with (Global Platform for Card Managers for example).

Note: we have almost the same for APDU responses.

Community
  • 1
  • 1
Ebrahim Ghasemi
  • 5,850
  • 10
  • 52
  • 113
  • 2
    I think the CLA and INS specified were in binary, not hex. Lc is the encoding of Nc, which is the encoding of the length of the CDATA field. Le is the encoding of Ne, then encoding of the *maximum* response data that may be send. This is currently incorrect in the Java Card specifications as well :) – Maarten Bodewes Jun 06 '15 at 23:54
  • Thank you again dear Mr Bodewes :) I changed that parts that you mentioned. But I didn't understand the first sentence of your comment (i.e: _CLA and INS specified were in binary, not hex._). Doesn't only the value matters? I mean as you know the Hex or Bin is only the form of view and doesn't matter. I was said _"a queue of **hex** numbers"_, because I almost always see APDU commands in their hex form". Am I miss a point in your comment? I think I didn't got the point :) – Ebrahim Ghasemi Jun 07 '15 at 04:37
  • From your answer: "The first four sections, i.e CLA , INS , P1 and P2 are mandatory in all APDU commands and each one has one byte length (So there is no CLA = 10101010 or INS = 10101010)." . I think this is a bit of a misunderstanding. The question first specified an APDU in hex, and now the INS and CLA in binary. If it is binary it is a valid encoding of CLA and INS, even if BROY just jotted down some bits. – Maarten Bodewes Jun 07 '15 at 09:33
  • @Maarten Bodewes Ah, you are right again :) I was look at those values as `0x10 0x10 0x10 0x10`. I removed that sentence. Thank you. – Ebrahim Ghasemi Jun 07 '15 at 09:53
  • How do you send commands from terminal to the JavaCardApplet ?@Abraham – Teja Nandamuri Feb 03 '16 at 17:58
  • @Mr.T Almost all card readers have their own tool for sending APDU commands to card. But there are also a lot of free tools to aim this goal. OpenSCTool is an old free open source tool for that. The other is PyAPDUTool. You can also write your own program simply. Pyscard is a python library for that. Javax.smartcardio is its Java counterpart :) – Ebrahim Ghasemi Feb 03 '16 at 23:50
  • @Abraham- Could you please guide me in setting up the environment ? I couldnt run the apdutool from the command terminal. It is saying could not find or load main class com.sun.javacard.apdutool.main!!! – Teja Nandamuri Feb 04 '16 at 22:13
  • @Mr.T The version of pyAPDUtool that I have, has a GUI ,not command line. So I think we are using two different tools.Try to add all the `.jar` files in your tool install directory, to your JRE lib directory. It may solve the issue. Anyway, comments is not supposed to be a way to asking new questions :) If my comment doesn't solve the issue, please remove your last comments and ask it in details as a new question (Then I'll delete mine too) – Ebrahim Ghasemi Feb 05 '16 at 04:39
  • @Abraham, so if i am in my own applet, I could forward the APDU to the CardManager applet if i need to? – codenamezero Feb 03 '17 at 20:09
  • this was extremely helpfull thank you very much. – Moritz Schmidt Sep 23 '17 at 21:33
  • This answer is El Magnifeco! If request has no data content, then packet size is either 4 or 5. In which case if packet size is 5, then the fifth describes response len max size. Then if packet size is 7, then the fifth should be 2. If that packet size is 8 and fifth is 2, then the 8th byte describes the response Max Len. That iis why a request APDU "80:00:00:00:00:F2" is invalid because the correct format should have been "80:00:00:00:F2" – daparic Nov 10 '19 at 04:18
8

I am afraid such a "complete" e-book simply does not exist. Honestly, I think it is not necessary at all. If you know the basic Java syntax, you will find JavaCard quite easy to learn (although annoying to use). All the usual difficult stuff (threading, GUI, IO, annotations, templates, databases, ...) is just missing in Javacard and the standard libraries are so limited you will be able to learn them in a few days.

There are a few nice tutorials out there:

http://www.oracle.com/technetwork/java/embedded/javacard/overview/index.html http://javacard.vetilles.com/tutorial/

and a very good SO question:

How to get started with Java Cards?

To answer your question: JavaCard is just a language for writing smartcard applications called applets. It handles all the application logic, but it does not specify the APDU format. That is because JavaCard is not the only smartcard technology. APDU format is specifed in ISO7816 standard, which I really recommend you to read through. It is not free to download, but you can find the most important parts here:

http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_5_basic_organizations.aspx

You would find there, that your APDU command consists of a header:

00A404000E

and a data part:

63616C63756C61746F722E617070.

The header specifies what function should be called:

00 - class byte (CLA, 00 means "inter-industry command sent to logical channel 0")

A4 - instruction byte (INS, A4 means "SELECT applet command")

04 - parameter 1 (P1)

00 - parameter 2 (P2)

0E - length of the data part (Lc)

and the data part contains the identifier of the applet which should be selected for future usage (in your case it is an ASCII encoded string "calculator.app" btw).

Community
  • 1
  • 1
vojta
  • 5,591
  • 2
  • 24
  • 64
  • How to comprehend any values of CLA or INS? There are no well formed documents on the Internet. For example, how can I understand the meaning if CLA = 10101010? or, if INS = 10101010? – user366312 Jun 04 '15 at 09:35
  • @BROY Have a look at chapters 5.4.1 and 5.4.2 in this document: http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_5_basic_organizations.aspx#chap5_3 – vojta Jun 05 '15 at 06:27
  • Good answer and informative. Isn't it that "select" command uses hexadecimal numeric AID rather than alphabetic strings? Pls correct me if I'm wrong. Thanks. – daparic Nov 10 '19 at 04:29
  • @typelogic Yes, the alphabetical string is encoded to bytes using ASCII. – vojta Nov 10 '19 at 08:05