A Java Card Primer: Part 2—A Java Card Example
In order to run the code in this example, it is necessary to have installed the Java Card Development Kit Version 2.1.2 or higher from Sun. The kit is available for downloads at http://www.javasoft.com/products/javacard/.
As for the scripts, you will use simple Windows scripting that can be adapted easily to any Unix-like command-line environment.
A Demonstrative Applet
Listing 1 shows an example of a Java Card applet. It is very simple, but will serve the purpose of illustrating the deployment of Java Card applets from the Java source code to the final data transfer into the chip card.
To deploy your applet, follow these steps:
Write the Java source code, and compile it successfully.
Run the converter tool provided with the development kit, which obtains a CAP file.
Convert the CAP file in a sequence of low-level APDU commands to install the applet onto the card.
Listing 1 shows the CardTest applet. It is only a demonstrative applet it does not perform any useful task or use any standard APDU type in the processing. Nevertheless, it helps you follow all the main steps from the source development to a basic, on-card applet installation.
Listing 1. The CardTest Applet Class
package com.marinilli; import javacard.framework.*; /** * An example Java Card Applet * This applet writes back dummy byte sequences. * It shows the Java Card applet development process only. * * @author Mauro Marinilli */ public class CardTest extends Applet { //standard APDU input offset values public final static byte THIS_CLA = (byte)0x90; public final static byte INITIALIZE_TRANSACTION = (byte)0x20; public final static byte COMPLETE_TRANSACTION= (byte)0x22; public final static byte INITIALIZE_UPDATE= (byte)0x24; public final static byte COMPLETE_UPDATE= (byte)0x26; // dummy byte sequences returned by this applet private final static byte[] INIT_SEQUENCE = { (byte)0x1, (byte)0x2 }; private final static byte[] COMPLETE_SEQUENCE = { (byte)0x1, (byte)0x3 }; private final static byte[] INIT_UPDATE_SEQUENCE = { (byte)0x1, (byte)0x2, (byte)0x3 }; private final static byte[] COMPLETE_UPDATE_SEQUENCE = { (byte)0x1, (byte)0x1 }; /** * Constructor. * Only this class's install method can create the applet object. */ private CardTest() { //perform some initialization here // ... register();//register this instance } /** * Installs this applet. * @param byteArray the array containing installation parameters * @param offset the starting offset in byteArray * @param length the length in bytes of the parameter data in byteArray */ public static void install(byte[] byteArray, short offset, byte length) { new CardTest(); } /** * Implementation of the standard method for processing an incoming APDU. * @param apdu the incoming APDU * @exception ISOException with ISO 7816-4 response bytes */ public void process(APDU apdu) { byte buffer[] = apdu.getBuffer(); if (buffer[ISO7816.OFFSET_CLA] == THIS_CLA) { switch (buffer[ISO7816.OFFSET_INS]) { case INITIALIZE_TRANSACTION: writeBack(apdu, INIT_SEQUENCE); break; case COMPLETE_TRANSACTION: writeBack(apdu, COMPLETE_SEQUENCE); break; case INITIALIZE_UPDATE: writeBack(apdu, INIT_UPDATE_SEQUENCE); break; case COMPLETE_UPDATE: writeBack(apdu, COMPLETE_UPDATE_SEQUENCE); break; default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } } } /** * An example method that writes back a given byte array through the apdu. */ protected void writeBack(APDU apdu, byte[] bytes) { byte buffer[] = apdu.getBuffer(); // set apdu for data output apdu.setOutgoing(); apdu.setOutgoingLength( (short) (3) ); // output header apdu.sendBytes( (short)0, (short) 3); // writes data apdu.sendBytesLong( bytes, (short) 0, (short) 0 ); } }
Because we are interested in providing the overall picture, not in the details of Java Card programming, the proposed code in Listing 1 is not discussed.