JCDebug – JavaCard Applet Logging System and on-card debugger

Introduction

Going agile, requires responding as quickly to end user requests. Developers thus need tools to shorten the testing and developpement cycle of JavaCard applets.

Due to size optimization JavaCard standard dropped all the debugging features of the Java plateform. JCDebug tries to close this gap by offering logging services for javacard applets with zero footprint at runtime.

The main features of JCDebug are :
* Debugs applets on-card in the target plateform.
* Log messages, variable values and Exceptions.
* Log APDUs history.
* Breakpoints.

Quick start

Chapter 1. Phase 1: Install JCDebug

You can install jcdebug from following location :

Download and unzip JCDebug in your system. This folder will be refered to as $JCD_HOME in this guide.

Chapter 2. Phase 2: Setup your javacard project

Section 1. Step 1: Create you project directory

Create a project folder, in project folder create src folder and place your applet code inside (i). The project folder will be referred to as $PORJECT_DIR.

Section 2. Step 2: Initalize your project directory with jcd init

cd $PROJECT_DIR
$JCD_HOME/jcd init

Your project will be initialized with default values (i).

Section 3. Step 3: Add JCD markers to your code

There are two mandatory annotations to use in your code :

  1. In the install() function of your applet add //--JCD-INSTALL comment as the first line :
    public static void install(byte[] bArray, short bOffset, byte bLength) {
        //--JCD-INSTALL
        ... rest of install code ...
    }
    
  2. In the process() function of your applet add //--JCD-PROCESS{...} comment as the first line :
    public void process(APDU apdu) throws ISOException {
        //--JCD-PROCESS{apdu}
        ... rest of process code ...
    }
    

    Notice that between the two braces ({ and }) the value is the name of the APDU argument of process function.

Chapter 3. Phase 3: Work with JCD

Section 1. Step 1 : add log lines to your code with //! comments

JCD supports logging arbirary strings with eventually the value of byte, short or byte[] variables. This is done through special purpose one line comments starting with //! like :

byte a;
byte[] buffer;
... do some coding ...
if(testCondition()) { 
    //!Condition was verified
    ... do something...
}
//! calling doFoo with buffer {buffer}
doFoo(buffer)
...

As you see comment inside the if statement will log a single string wheras the comment after the if statment will also log the content of the byte[] buffer.

Section 2. Step 2 : enable debugging on your project – jcd gen

From inside your project folder enable jcd debug for your project

$JCD_HOME\jcd gen

Section 3. Step 3 : Compile and use your applet

Using your classic javacard tools.

Section 4. Step 4 : Dump binary log – jcd show

After execution send APDU command D0 66 (i) to dump the binary log :

//Select your applet 
I: ...
O: ...
//Dump binary log
I: D0 66 00 00 00
O: 61 XX <- XX is the length in hex of the binlog
//Red the log
I: 00 C0 00 00 XX <- XX is the length in hex of the binlog
O: 90 00
   YY YY ... YY <- This is the binlog you want to copy into show

Decode binary log using JCD :

$JCD_HOME/jcd show 
YY YY ... YY  <- Copy past data obtained from card respons
0001: Condition was verified
0004: calling doFoo with buffer { 0A DD ... } <- Between braces is the logged data

Section 5. Step 4: Back to you clean code – jcd clean

Before coding again with you project you can use
$JCD_HOME\jcd clean
To remove all the generated code, this is not mandatory but it avoids working with some cumbersome generated code.

Going further

You can check JCD Command Reference for details on functions or use jcd -h for help.

  • Customizing source folder : Source folder can be customized using jcd setup --source-folder=<new-folder>
  • Customizing CLA INS : Class / instruction for logs are not forced to be D0 66, you can customize this using jcd setup --cla=XX --ins=YY
  • More setup options are available through jcd setup.

Fork me on GitHub