/* *********************************************************** * Smart Cards: Toward a Modern Run-time Platform * ETH Zurich, WS 2005/2006 * * Exercise 3b - Solution *************************************************************/ package exercise3b; import javacard.framework.APDU; import javacard.framework.Applet; import javacard.framework.ISO7816; import javacard.framework.ISOException; import javacard.framework.JCSystem; import javacard.framework.MultiSelectable; import javacard.framework.Util; public class Exercise3b extends Applet implements MultiSelectable { private final short[] mod_since_select; private final short[] mod_since_reset; private final short[] history; private short mod_since_install; public Exercise3b() { mod_since_select = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_DESELECT); mod_since_reset = JCSystem.makeTransientShortArray((short) 1, JCSystem.CLEAR_ON_RESET); mod_since_install = 0; history = new short[4]; } public static void install(byte[] bArray, short bOffset, byte bLength) { new Exercise3b().register(bArray, (short) (bOffset + 1), bArray[bOffset]); } public boolean select(boolean appInstStillActive) { return true; } public void deselect(boolean appInstStillActive) { } public void process(APDU apdu) { if (selectingApplet()) { return; } byte[] buf = apdu.getBuffer(); if (JCSystem.getAssignedChannel() == 0) { short value = history[mod_since_install & 0x03]; switch (buf[ISO7816.OFFSET_INS]) { case (byte) 0x00: // add p1 to value value += buf[ISO7816.OFFSET_P1]; break; case (byte) 0x02: // subtract p2 to value value -= buf[ISO7816.OFFSET_P2]; break; case (byte) 0x04: // set value to p1 * p2 value = (short) (buf[ISO7816.OFFSET_P1] * buf[ISO7816.OFFSET_P2]); break; default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } if (value != history[mod_since_install & 0x03]) { JCSystem.beginTransaction(); mod_since_select[0]++; mod_since_reset[0]++; mod_since_install++; history[mod_since_install & 0x03] = value; JCSystem.commitTransaction(); } } else { switch (buf[ISO7816.OFFSET_INS]) { case (byte) 0x00: Util .setShort(buf, (short) 0, history[mod_since_install & 0x03]); break; case (byte) 0x02: Util.setShort(buf, (short) 0, mod_since_select[0]); break; case (byte) 0x04: Util.setShort(buf, (short) 0, mod_since_reset[0]); break; case (byte) 0x06: Util.setShort(buf, (short) 0, mod_since_install); break; case (byte) 0x08: if (mod_since_install < 3) { ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); } else { Util.setShort(buf, (short) 0, history[(mod_since_install - 3) & 0x03]); } break; default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } apdu.setOutgoingAndSend((short) 0, (short) 2); } } }