Java Card Application Development by Darryl Barnes Example 1: public class Loyalty extends javacard.framework.Applet { public void static install(APDU _apdu) { } public boolean select() { } public void process(APDU _apdu) { } public void deselect() { } } Example 2: public static void install(APDU _apdu) { Loyalty loyalty = new Loyalty(); // initialize user PIN loyalty.pin = new OwnerPIN((byte)5, PIN_LENGTH); loyalty.pin.updateAndUnblock(baPINValue, (short)0, PIN_LENGTH); // register the applet loyalty.register(); } Example 3: public void process(APDU _apdu) { // get reference to apdu buffer byte[] baBuffer = _apdu.getBuffer(); // verify class if(baBuffer[ISO.OFFSET_CLA] != CLA_LOYALTY) ISOException.throwIt(ISO.SW_CLA_NOT_SUPPORTED); // branch to each instruction switch(baBuffer[ISO.OFFSET_INS]) { case INS_VALIDATE_PIN: this.validatePIN(_apdu); break; case INS_DEBIT: this.debit(_apdu); break; case INS_CREDIT: this.credit(_apdu); break; case INS_GETBALANCE: this.getBalance(_apdu); break; } } Example 4: protected void validatePIN(APDU _apdu) { // get reference to apdu buffer baBuffer = _apdu.getBuffer(); // get data from terminal byte bLc = (byte)_apdu.setIncomingAndReceive(); // check length being sent if(bLc != PIN_LENGTH) ISOException.throwIt(ISO.SW_WRONG_LENGTH); // validate PIN if(pin.check(baBuffer, ISO.OFFSET_CDATA, PIN_LENGTH)) zIsAuthorized = true; else ISOException.throwIt(ISO.SW_SECURITY_STATUS_NOT_SATISFIED); } protected void debit(APDU _apdu) { // check if PIN is validated if(!zIsAuthorized) ISOException.throwIt(ISO.SW_SECURITY_STATUS_NOT_SATISFIED); // get reference to apdu buffer baBuffer = _apdu.getBuffer(); // get data from terminal byte bLc = (byte)_apdu.setIncomingAndReceive(); // get amount from apdu buffer short sAmount = Util.getShort(baBuffer, ISO.OFFSET_P1); // don't allow negative balance if((sPoints - sAmount) < 0) sPoints = 0; else // debit account sPoints = (short)(sPoints - sAmount); } protected void credit(APDU _apdu) { // check if PIN is validated if(!zIsAuthorized) ISOException.throwIt(ISO.SW_SECURITY_STATUS_NOT_SATISFIED); // get reference to apdu buffer baBuffer = _apdu.getBuffer(); // get data from terminal byte bLc = (byte)_apdu.setIncomingAndReceive(); // get amount from apdu buffer short sAmount = Util.getShort(baBuffer, ISO.OFFSET_P1); // increment balance sPoints = (short)(sPoints + sAmount); } protected void getBalance(APDU _apdu) { // check access permissions if(!zIsAuthorized) ISOException.throwIt(ISO.SW_SECURITY_STATUS_NOT_SATISFIED); // get reference to apdu buffer baBuffer = _apdu.getBuffer(); // put balance value into apdu buffer Util.setShort(baBuffer, ISO.OFFSET_CDATA, sPoints); // send balance _apdu.setOutgoingAndSend(ISO.OFFSET_CDATA, (short)2); } Listing One package article; import javacard.framework.*; public class Loyalty extends Applet { // these attributes are made static because they // are referenced in the static install method protected static short sPoints = 0; protected static byte[] baBuffer; // CLA & INS definitions public static final byte CLA_LOYALTY = (byte)0xAA; public static final byte INS_VALIDATE_PIN = 0x10; public static final byte INS_GETBALANCE = 0x20; public static final byte INS_DEBIT = 0x30; public static final byte INS_CREDIT = 0x40; // PIN attributes public static final byte PIN_LENGTH = 8; protected OwnerPIN pin; protected static byte[] baPINValue = {0x0A, 0x0B, 0x0A, 0x0B, 0x0A, 0x0B, 0x0A, 0x0B}; protected transient boolean zIsAuthorized = false; public static void install(APDU _apdu) { Loyalty loyalty = new Loyalty(); // initialize user PIN loyalty.pin = new OwnerPIN((byte)5, PIN_LENGTH); loyalty.pin.updateAndUnblock(baPINValue, (short)0, PIN_LENGTH); // register the applet loyalty.register(); } public void process(APDU _apdu) { // get reference to apdu buffer byte[] baBuffer = _apdu.getBuffer(); // verify class if(baBuffer[ISO.OFFSET_CLA] != CLA_LOYALTY) ISOException.throwIt(ISO.SW_CLA_NOT_SUPPORTED); // branch to each instruction switch(baBuffer[ISO.OFFSET_INS]) { case INS_VALIDATE_PIN: this.validatePIN(_apdu); break; case INS_DEBIT: this.debit(_apdu); break; case INS_CREDIT: this.credit(_apdu); break; case INS_GETBALANCE: this.getBalance(_apdu); break; } } protected void validatePIN(APDU _apdu) { // get reference to apdu buffer baBuffer = _apdu.getBuffer(); // get data from terminal byte bLc = (byte)_apdu.setIncomingAndReceive(); // check length being sent if(bLc != PIN_LENGTH) ISOException.throwIt(ISO.SW_WRONG_LENGTH); // validate PIN if(pin.check(baBuffer, ISO.OFFSET_CDATA, PIN_LENGTH)) zIsAuthorized = true; else ISOException.throwIt(ISO.SW_SECURITY_STATUS_NOT_SATISFIED); } protected void debit(APDU _apdu) { // check if PIN is validated if(!zIsAuthorized) ISOException.throwIt(ISO.SW_SECURITY_STATUS_NOT_SATISFIED); // get reference to apdu buffer baBuffer = _apdu.getBuffer(); // get data from terminal byte bLc = (byte)_apdu.setIncomingAndReceive(); // get amount from apdu buffer short sAmount = Util.getShort(baBuffer, ISO.OFFSET_P1); // don't allow negative balance if((sPoints - sAmount) < 0) sPoints = 0; else // debit account sPoints = (short)(sPoints - sAmount); } protected void credit(APDU _apdu) { // check if PIN is validated if(!zIsAuthorized) ISOException.throwIt(ISO.SW_SECURITY_STATUS_NOT_SATISFIED); // get reference to apdu buffer baBuffer = _apdu.getBuffer(); // get data from terminal byte bLc = (byte)_apdu.setIncomingAndReceive(); // get amount from apdu buffer short sAmount = Util.getShort(baBuffer, ISO.OFFSET_P1); // increment balance sPoints = (short)(sPoints + sAmount); } protected void getBalance(APDU _apdu) { // check access permissions if(!zIsAuthorized) ISOException.throwIt(ISO.SW_SECURITY_STATUS_NOT_SATISFIED); // get reference to apdu buffer baBuffer = _apdu.getBuffer(); // put balance value into apdu buffer Util.setShort(baBuffer, ISO.OFFSET_CDATA, sPoints); // send balance _apdu.setOutgoingAndSend(ISO.OFFSET_CDATA, (short)2); } } 5