package org.dogtagpki.javacard; import javacard.framework.*; /** * @author Endi Sukma Dewata */ public class ProxyApplet extends Applet implements MultiSelectable { private final static byte[] TEST_APPLET_AID = {(byte) 0xa0, 0x00, 0x00, 0x00, 0x62, 0x03, 0x01, 0x0c, 0x01, 0x01 }; private final static byte SAY_HELLO_INS = (byte) 0x01; private final static byte SAY_ECHO2_INS = (byte) 0x03; private final static byte SAY_IPARAMS_INS = (byte) 0x04; private final static byte NOP_INS = (byte) 0x02; private static byte[] helloMessage = new byte[] { 'P', 'r', 'o', 'x', 'y', 'A', 'p', 'p', 'l', 'e', 't' }; private byte[] echoBytes; private byte[] initParamsBytes; private static final short LENGTH_ECHO_BYTES = 256; protected ProxyApplet(byte[] bArray, short bOffset, byte bLength) { echoBytes = new byte[LENGTH_ECHO_BYTES]; if (bLength > 0) { byte iLen = bArray[bOffset]; // aid length bOffset = (short) (bOffset + iLen + 1); byte cLen = bArray[bOffset]; // info length bOffset = (short) (bOffset + cLen + 1); byte aLen = bArray[bOffset]; // applet data length initParamsBytes = new byte[aLen]; Util.arrayCopyNonAtomic(bArray, (short) (bOffset + 1), initParamsBytes, (short) 0, aLen); } register(); } public static void install(byte[] bArray, short bOffset, byte bLength) throws ISOException { new ProxyApplet(bArray, bOffset,bLength); } public void process(APDU apdu) { if(selectingApplet()) return; byte[] buffer = apdu.getBuffer(); switch (buffer[ISO7816.OFFSET_INS]) { case SAY_HELLO_INS: sayHello(apdu); return; case SAY_ECHO2_INS: sayEcho2(apdu); return; case SAY_IPARAMS_INS: sayIParams(apdu); return; case NOP_INS: return; default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } return; } private void sayHello(APDU apdu) { byte[] buffer = apdu.getBuffer(); short incomeBytes = apdu.setIncomingAndReceive(); byte[] echo; if (buffer[ISO7816.OFFSET_P1] == 0x01) { echo = JCSystem.makeTransientByteArray(incomeBytes, JCSystem.CLEAR_ON_RESET); Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echo, (short) 0, incomeBytes); } else { echo = JCSystem.makeTransientByteArray((short) helloMessage.length, JCSystem.CLEAR_ON_RESET); Util.arrayCopyNonAtomic(helloMessage, (short) 0, echo, (short) 0, (short) helloMessage.length); } apdu.setOutgoing(); apdu.setOutgoingLength((short) echo.length); apdu.sendBytesLong(echo, (short) 0, (short) echo.length); } private void sayEcho2(APDU apdu) { byte buffer[] = apdu.getBuffer(); short bytesRead = apdu.setIncomingAndReceive(); short echoOffset = (short) 0; while (bytesRead > 0) { Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echoBytes, echoOffset, bytesRead); echoOffset += bytesRead; bytesRead = apdu.receiveBytes(ISO7816.OFFSET_CDATA); } apdu.setOutgoing(); apdu.setOutgoingLength((short) (echoOffset + 5)); apdu.sendBytes((short) 0, (short) 5); apdu.sendBytesLong(echoBytes, (short) 0, echoOffset); } private void sayIParams(APDU apdu) { AID aid = JCSystem.lookupAID(TEST_APPLET_AID, (short)0, (byte)TEST_APPLET_AID.length); TestShareable shareable = (TestShareable)JCSystem.getAppletShareableInterfaceObject(aid, (byte)0); shareable.sayIParams(apdu); } public boolean select(boolean b) { return true; } public void deselect(boolean b) { } }