From 438e3b52394e2936f6e286e0cddaaf4d41125324 Mon Sep 17 00:00:00 2001 From: Endi Sukma Dewata Date: Wed, 20 Feb 2013 12:40:28 -0500 Subject: WIP --- .../java/org/dogtagpki/javacard/ProxyApplet.java | 116 +++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 base/javacard/src/java/org/dogtagpki/javacard/ProxyApplet.java (limited to 'base/javacard/src/java/org/dogtagpki/javacard/ProxyApplet.java') diff --git a/base/javacard/src/java/org/dogtagpki/javacard/ProxyApplet.java b/base/javacard/src/java/org/dogtagpki/javacard/ProxyApplet.java new file mode 100644 index 000000000..fd6c9d405 --- /dev/null +++ b/base/javacard/src/java/org/dogtagpki/javacard/ProxyApplet.java @@ -0,0 +1,116 @@ +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) { + } +} -- cgit