summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEndi Sukma Dewata <edewata@redhat.com>2013-02-20 12:40:28 -0500
committerEndi Sukma Dewata <edewata@redhat.com>2013-02-20 12:40:28 -0500
commit438e3b52394e2936f6e286e0cddaaf4d41125324 (patch)
treef34c2085dd75423d1e06e9adfa64cc7a10bb954c
parentf49c98ca0cbfc0def8f055c2d97c031ff0f4a439 (diff)
downloadpki-438e3b52394e2936f6e286e0cddaaf4d41125324.tar.gz
pki-438e3b52394e2936f6e286e0cddaaf4d41125324.tar.xz
pki-438e3b52394e2936f6e286e0cddaaf4d41125324.zip
WIP
-rw-r--r--.gitignore4
-rw-r--r--base/javacard/.classpath24
-rw-r--r--base/javacard/.project17
-rw-r--r--base/javacard/.settings/org.eclipse.jdt.core.prefs11
-rw-r--r--base/javacard/bin/run.sh1
-rw-r--r--base/javacard/build.xml138
-rw-r--r--base/javacard/conf/TestApplet.opt6
-rw-r--r--base/javacard/conf/jcardsim.cfg4
-rw-r--r--base/javacard/conf/jcwde.app4
-rw-r--r--base/javacard/lib/apduio.jarbin0 -> 48313 bytes
-rw-r--r--base/javacard/lib/apdutool.jarbin0 -> 26302 bytes
-rw-r--r--base/javacard/lib/api.jarbin0 -> 175768 bytes
-rw-r--r--base/javacard/lib/capdump.jarbin0 -> 4369 bytes
-rw-r--r--base/javacard/lib/converter.jarbin0 -> 640317 bytes
-rw-r--r--base/javacard/lib/installer.jarbin0 -> 30035 bytes
-rw-r--r--base/javacard/lib/javacardframework.jarbin0 -> 95149 bytes
-rw-r--r--base/javacard/lib/jcardsim-2.2.1-SNAPSHOT.jarbin0 -> 359482 bytes
-rw-r--r--base/javacard/lib/jcclientsamples.jarbin0 -> 244817 bytes
-rw-r--r--base/javacard/lib/jcrmiclientframework.jarbin0 -> 31335 bytes
-rw-r--r--base/javacard/lib/jcwde.jarbin0 -> 80671 bytes
-rw-r--r--base/javacard/lib/offcardverifier.jarbin0 -> 147387 bytes
-rw-r--r--base/javacard/lib/scriptgen.jarbin0 -> 12382 bytes
-rw-r--r--base/javacard/scripts/helloworld.apdu10
-rw-r--r--base/javacard/src/java/org/dogtagpki/javacard/ProxyApplet.java116
-rw-r--r--base/javacard/src/java/org/dogtagpki/javacard/TestApplet.java113
-rw-r--r--base/javacard/src/java/org/dogtagpki/javacard/TestShareable.java11
-rw-r--r--base/javacard/src/test/org/dogtagpki/javacard/MainTest.java77
27 files changed, 536 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 4b66852c5..756dd1abf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,6 @@
.metadata/
build/
+base/javacard/build/
+base/javacard/docs/
+base/javacard/jcardsim/
+base/javacard/jcdk/
diff --git a/base/javacard/.classpath b/base/javacard/.classpath
new file mode 100644
index 000000000..16a6fb6a7
--- /dev/null
+++ b/base/javacard/.classpath
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src/java"/>
+ <classpathentry kind="src" path="src/test"/>
+ <classpathentry kind="src" path="jcdk/samples/src"/>
+ <classpathentry kind="lib" path="jcdk/lib/api.jar"/>
+ <classpathentry kind="lib" path="jcdk/lib/apduio.jar"/>
+ <classpathentry kind="lib" path="jcdk/lib/apdutool.jar"/>
+ <classpathentry kind="lib" path="jcdk/lib/capdump.jar"/>
+ <classpathentry kind="lib" path="jcdk/lib/converter.jar"/>
+ <classpathentry kind="lib" path="jcdk/lib/installer.jar"/>
+ <classpathentry kind="lib" path="jcdk/lib/javacardframework.jar"/>
+ <classpathentry kind="lib" path="jcdk/ant-tasks/lib/jctasks.jar"/>
+ <classpathentry kind="lib" path="jcdk/lib/jcclientsamples.jar"/>
+ <classpathentry kind="lib" path="jcdk/lib/jcrmiclientframework.jar"/>
+ <classpathentry kind="lib" path="jcdk/lib/jcwde.jar"/>
+ <classpathentry kind="lib" path="jcdk/lib/offcardverifier.jar"/>
+ <classpathentry kind="lib" path="jcdk/lib/scriptgen.jar"/>
+ <classpathentry kind="lib" path="lib/junit4.jar"/>
+ <classpathentry kind="lib" path="/usr/share/java/bcprov.jar"/>
+ <classpathentry kind="lib" path="/home/edewata/CS/jcardsim/target/jcardsim-2.2.1-SNAPSHOT.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="build/classes"/>
+</classpath>
diff --git a/base/javacard/.project b/base/javacard/.project
new file mode 100644
index 000000000..a55dd885b
--- /dev/null
+++ b/base/javacard/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>piv</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/base/javacard/.settings/org.eclipse.jdt.core.prefs b/base/javacard/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..416f4fb69
--- /dev/null
+++ b/base/javacard/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/base/javacard/bin/run.sh b/base/javacard/bin/run.sh
new file mode 100644
index 000000000..e86f7f92e
--- /dev/null
+++ b/base/javacard/bin/run.sh
@@ -0,0 +1 @@
+java -cp lib/jcardsim-2.2.1-all.jar com.licel.jcardsim.utils.APDUScriptTool conf/jcardsim.cfg scripts/helloworld.apdu \ No newline at end of file
diff --git a/base/javacard/build.xml b/base/javacard/build.xml
new file mode 100644
index 000000000..f3c1f6581
--- /dev/null
+++ b/base/javacard/build.xml
@@ -0,0 +1,138 @@
+<project name="piv" basedir="." default="main">
+
+ <property name="lib.dir" value="lib"/>
+ <property name="jcdk.dir" value="jcdk"/>
+
+ <property name="src.dir" value="src/java"/>
+
+ <property name="build.dir" value="build"/>
+ <property name="classes.dir" value="${build.dir}/classes"/>
+
+ <property name="dist.dir" value="${build.dir}/dist"/>
+
+ <property name="test.dir" value="src/test"/>
+ <property name="test.classes.dir" value="${build.dir}/test-classes"/>
+
+ <path id="classpath">
+ <fileset dir="${jcdk.dir}/lib" includes="**/*.jar"/>
+ <fileset dir="${lib.dir}" includes="**/*.jar"/>
+ </path>
+
+ <path id="exportpath">
+ <fileset dir="${jcdk.dir}/api_export_files" includes="**/*.exp"/>
+ </path>
+
+ <path id="test-classpath">
+ <fileset dir="${lib.dir}" includes="**/*.jar"/>
+ <fileset dir="${jcdk.dir}/lib" includes="**/*.jar"/>
+ <path location="${dist.dir}/${ant.project.name}.jar"/>
+ </path>
+
+ <typedef name="appletnameaid"
+ classname="com.sun.javacard.ant.types.AppletNameAID"
+ classpath="${jcdk.dir}/ant-tasks/lib/jctasks.jar" />
+
+ <taskdef name="convert"
+ classname="com.sun.javacard.ant.tasks.ConverterTask"
+ classpath="${jcdk.dir}/ant-tasks/lib/jctasks.jar" />
+
+ <taskdef name="scriptgen"
+ classname="com.sun.javacard.ant.tasks.ScriptgenTask"
+ classpath="${jcdk.dir}/ant-tasks/lib/jctasks.jar" />
+
+ <taskdef name="verifycap"
+ classname="com.sun.javacard.ant.tasks.VerifyCapTask"
+ classpath="${jcdk.dir}/ant-tasks/lib/jctasks.jar" />
+
+ <taskdef name="verifyexport"
+ classname="com.sun.javacard.ant.tasks.VerifyExpTask"
+ classpath="${jcdk.dir}/ant-tasks/lib/jctasks.jar" />
+
+ <target name="clean">
+ <delete dir="${build.dir}"/>
+ </target>
+
+ <target name="compile">
+ <mkdir dir="${classes.dir}"/>
+ <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"
+ source="1.5" target="1.5" includeantruntime="false" />
+ </target>
+
+ <target name="deploy" depends="compile">
+ <convert
+ CAP="true"
+ EXP="true"
+ JCA="true"
+ packagename="org.dogtagpki.javacard"
+ packageaid="0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1"
+ majorminorversion="1.0"
+ classdir="${classes.dir}"
+ exportpath="${jcdk.dir}/api_export_files"
+ outputdirectory="${classes.dir}">
+ <appletnameaid
+ appletname="org.dogtagpki.javacard.TestApplet"
+ aid="0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1:0x1"/>
+ <appletnameaid
+ appletname="org.dogtagpki.javacard.ProxyApplet"
+ aid="0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1:0x2"/>
+ <classpath refid="classpath"/>
+ </convert>
+ <verifyexport>
+ <exportfiles file="${classes.dir}/org/dogtagpki/javacard/javacard/javacard.exp"/>
+ <classpath refid="classpath"/>
+ </verifyexport>
+ <verifycap
+ capfile="${classes.dir}/org/dogtagpki/javacard/javacard/javacard.cap">
+ <exportfiles dir="${jcdk.dir}/api_export_files">
+ <include name="**/*.exp"/>
+ </exportfiles>
+ <exportfiles dir="${classes.dir}">
+ <include name="**/*.exp"/>
+ </exportfiles>
+ <classpath refid="classpath"/>
+ </verifycap>
+ <scriptgen
+ capfile="${classes.dir}/org/dogtagpki/javacard/javacard/javacard.cap"
+ outfile="${classes.dir}/org/dogtagpki/javacard/javacard/javacard.scr">
+ <classpath refid="classpath" />
+ </scriptgen>
+ </target>
+
+ <target name="run">
+ <scriptgen
+ capfile="${classes.dir}/org/dogtagpki/javacard/javacard/javacard.cap"
+ outfile="${classes.dir}/org/dogtagpki/javacard/javacard/javacard.scr">
+ <classpath refid="classpath" />
+ </scriptgen>
+ </target>
+
+ <target name="build" depends="compile">
+ <mkdir dir="${dist.dir}"/>
+ <jar destfile="${dist.dir}/${ant.project.name}.jar" basedir="${classes.dir}"/>
+ </target>
+
+ <target name="test" depends="build">
+ <mkdir dir="${test.classes.dir}"/>
+ <javac srcdir="${test.dir}" destdir="${test.classes.dir}" classpathref="test-classpath"
+ includeantruntime="false" />
+ <junit>
+ <classpath>
+ <path refid="test-classpath"/>
+ <pathelement path="${test.classes.dir}"/>
+ <fileset dir="${jcdk.dir}/lib" includes="**/*.jar"/>
+ </classpath>
+ <batchtest fork="yes">
+ <fileset dir="${test.dir}">
+ <include name="**/*Test*.java"/>
+ <exclude name="**/AllTests.java"/>
+ </fileset>
+ <formatter type="plain" usefile="false"/>
+ </batchtest>
+ </junit>
+ </target>
+
+ <target name="clean-build" depends="clean,build"/>
+
+ <target name="main" depends="clean,test"/>
+
+</project> \ No newline at end of file
diff --git a/base/javacard/conf/TestApplet.opt b/base/javacard/conf/TestApplet.opt
new file mode 100644
index 000000000..c3541e823
--- /dev/null
+++ b/base/javacard/conf/TestApplet.opt
@@ -0,0 +1,6 @@
+-out EXP JCA CAP
+-classdir build\classes
+-exportpath jcdk\api_export_files
+-applet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1:0x1 org.dogtagpki.javacard.TestApplet
+org.dogtagpki.javacard
+0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1 1.0
diff --git a/base/javacard/conf/jcardsim.cfg b/base/javacard/conf/jcardsim.cfg
new file mode 100644
index 000000000..c1d1777bc
--- /dev/null
+++ b/base/javacard/conf/jcardsim.cfg
@@ -0,0 +1,4 @@
+com.licel.jcardsim.smartcardio.applet.0.AID=A00000006203010C0101
+com.licel.jcardsim.smartcardio.applet.0.Class=org.dogtagpki.javacard.TestApplet
+com.licel.jcardsim.smartcardio.applet.1.AID=A00000006203010C0102
+com.licel.jcardsim.smartcardio.applet.1.Class=org.dogtagpki.javacard.ProxyApplet
diff --git a/base/javacard/conf/jcwde.app b/base/javacard/conf/jcwde.app
new file mode 100644
index 000000000..1001d9e81
--- /dev/null
+++ b/base/javacard/conf/jcwde.app
@@ -0,0 +1,4 @@
+// applet AID
+com.sun.javacard.installer.InstallerApplet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0x8:0x1
+org.dogtagpki.javacard.TestApplet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1:0x1
+org.dogtagpki.javacard.ProxyApplet 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x1:0x2
diff --git a/base/javacard/lib/apduio.jar b/base/javacard/lib/apduio.jar
new file mode 100644
index 000000000..ab57e262d
--- /dev/null
+++ b/base/javacard/lib/apduio.jar
Binary files differ
diff --git a/base/javacard/lib/apdutool.jar b/base/javacard/lib/apdutool.jar
new file mode 100644
index 000000000..c4ad9f297
--- /dev/null
+++ b/base/javacard/lib/apdutool.jar
Binary files differ
diff --git a/base/javacard/lib/api.jar b/base/javacard/lib/api.jar
new file mode 100644
index 000000000..98e07b2c3
--- /dev/null
+++ b/base/javacard/lib/api.jar
Binary files differ
diff --git a/base/javacard/lib/capdump.jar b/base/javacard/lib/capdump.jar
new file mode 100644
index 000000000..00f38c5c5
--- /dev/null
+++ b/base/javacard/lib/capdump.jar
Binary files differ
diff --git a/base/javacard/lib/converter.jar b/base/javacard/lib/converter.jar
new file mode 100644
index 000000000..3728ebe45
--- /dev/null
+++ b/base/javacard/lib/converter.jar
Binary files differ
diff --git a/base/javacard/lib/installer.jar b/base/javacard/lib/installer.jar
new file mode 100644
index 000000000..43004d523
--- /dev/null
+++ b/base/javacard/lib/installer.jar
Binary files differ
diff --git a/base/javacard/lib/javacardframework.jar b/base/javacard/lib/javacardframework.jar
new file mode 100644
index 000000000..35762c41f
--- /dev/null
+++ b/base/javacard/lib/javacardframework.jar
Binary files differ
diff --git a/base/javacard/lib/jcardsim-2.2.1-SNAPSHOT.jar b/base/javacard/lib/jcardsim-2.2.1-SNAPSHOT.jar
new file mode 100644
index 000000000..7d9e54231
--- /dev/null
+++ b/base/javacard/lib/jcardsim-2.2.1-SNAPSHOT.jar
Binary files differ
diff --git a/base/javacard/lib/jcclientsamples.jar b/base/javacard/lib/jcclientsamples.jar
new file mode 100644
index 000000000..5320dc1ff
--- /dev/null
+++ b/base/javacard/lib/jcclientsamples.jar
Binary files differ
diff --git a/base/javacard/lib/jcrmiclientframework.jar b/base/javacard/lib/jcrmiclientframework.jar
new file mode 100644
index 000000000..c0fdaad1a
--- /dev/null
+++ b/base/javacard/lib/jcrmiclientframework.jar
Binary files differ
diff --git a/base/javacard/lib/jcwde.jar b/base/javacard/lib/jcwde.jar
new file mode 100644
index 000000000..1f6d0177e
--- /dev/null
+++ b/base/javacard/lib/jcwde.jar
Binary files differ
diff --git a/base/javacard/lib/offcardverifier.jar b/base/javacard/lib/offcardverifier.jar
new file mode 100644
index 000000000..e6b00a9d1
--- /dev/null
+++ b/base/javacard/lib/offcardverifier.jar
Binary files differ
diff --git a/base/javacard/lib/scriptgen.jar b/base/javacard/lib/scriptgen.jar
new file mode 100644
index 000000000..e1b50c564
--- /dev/null
+++ b/base/javacard/lib/scriptgen.jar
Binary files differ
diff --git a/base/javacard/scripts/helloworld.apdu b/base/javacard/scripts/helloworld.apdu
new file mode 100644
index 000000000..050bc47a0
--- /dev/null
+++ b/base/javacard/scripts/helloworld.apdu
@@ -0,0 +1,10 @@
+// CREATE APPLET CMD
+0x80 0xb8 0x00 0x00 0xb 0x9 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x8 0x09 0x00 0x7f;
+// SELECT APPLET CMD
+0x00 0xa4 0x00 0x00 0x09 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x8 0x09 0x2;
+// TEST NOP
+0x01 0x02 0x00 0x00 0x00 0x2;
+// test hello world from card
+0x01 0x01 0x00 0x00 0x00 0x0d;
+// test echo
+0x01 0x01 0x01 0x00 0x0d 0x48 0x65 0x6c 0x6c 0x6f 0x20 0x77 0x6f 0x72 0x6c 0x64 0x20 0x21 0x0d; \ No newline at end of file
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) {
+ }
+}
diff --git a/base/javacard/src/java/org/dogtagpki/javacard/TestApplet.java b/base/javacard/src/java/org/dogtagpki/javacard/TestApplet.java
new file mode 100644
index 000000000..d1c7d4d89
--- /dev/null
+++ b/base/javacard/src/java/org/dogtagpki/javacard/TestApplet.java
@@ -0,0 +1,113 @@
+package org.dogtagpki.javacard;
+
+import javacard.framework.*;
+
+/**
+ * @author Endi Sukma Dewata
+ */
+public class TestApplet extends Applet implements MultiSelectable, TestShareable {
+
+ 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[] {
+ 'T', 'e', 's', 't',
+ 'A', 'p', 'p', 'l', 'e', 't'
+ };
+
+ private byte[] echoBytes;
+ private byte[] initParamsBytes;
+ private static final short LENGTH_ECHO_BYTES = 256;
+
+ protected TestApplet(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 TestApplet(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);
+ }
+
+ public void sayIParams(APDU apdu) {
+ apdu.setOutgoing();
+ apdu.setOutgoingLength((short)initParamsBytes.length);
+ apdu.sendBytesLong(initParamsBytes, (short) 0, (short)initParamsBytes.length);
+ }
+
+ public boolean select(boolean b) {
+ return true;
+ }
+
+ public void deselect(boolean b) {
+ }
+}
diff --git a/base/javacard/src/java/org/dogtagpki/javacard/TestShareable.java b/base/javacard/src/java/org/dogtagpki/javacard/TestShareable.java
new file mode 100644
index 000000000..e36e7d8f4
--- /dev/null
+++ b/base/javacard/src/java/org/dogtagpki/javacard/TestShareable.java
@@ -0,0 +1,11 @@
+package org.dogtagpki.javacard;
+
+import javacard.framework.APDU;
+import javacard.framework.Shareable;
+
+/**
+ * @author Endi Sukma Dewata
+ */
+public interface TestShareable extends Shareable {
+ public void sayIParams(APDU apdu);
+}
diff --git a/base/javacard/src/test/org/dogtagpki/javacard/MainTest.java b/base/javacard/src/test/org/dogtagpki/javacard/MainTest.java
new file mode 100644
index 000000000..fa2875a90
--- /dev/null
+++ b/base/javacard/src/test/org/dogtagpki/javacard/MainTest.java
@@ -0,0 +1,77 @@
+package org.dogtagpki.javacard;
+
+import com.licel.jcardsim.base.Simulator;
+import javacard.framework.AID;
+import org.bouncycastle.util.encoders.Hex;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.smartcardio.*;
+import java.io.FileReader;
+import java.util.Properties;
+
+/**
+ * @author Endi Sukma Dewata
+ */
+public class MainTest {
+
+ @Test
+ public void testMainApplet() throws Exception {
+
+ Properties props = new Properties();
+ props.load(new FileReader("conf/jcardsim.cfg"));
+
+ String s = (String)props.get("com.licel.jcardsim.smartcardio.applet.0.AID");
+ byte[] aidBytes = Hex.decode(s);
+ AID appletAID = new AID(aidBytes, (short) 0, (byte) aidBytes.length);
+
+ Simulator simulator = new Simulator();
+
+ simulator.installApplet(appletAID, TestApplet.class);
+ simulator.selectApplet(appletAID);
+
+ // test NOP
+ ResponseAPDU response = simulator.transmitCommand(new CommandAPDU(0x01, 0x02, 0x00, 0x00));
+ Assert.assertEquals(0x9000, response.getSW());
+
+ // test hello world from card
+ response = simulator.transmitCommand(new CommandAPDU(0x01, 0x01, 0x00, 0x00));
+ Assert.assertEquals(0x9000, response.getSW());
+ Assert.assertEquals("TestApplet", new String(response.getData()));
+
+ // test echo
+ response = simulator.transmitCommand(new CommandAPDU(0x01, 0x01, 0x01, 0x00, ("Hello javacard world !").getBytes()));
+ Assert.assertEquals(0x9000, response.getSW());
+ Assert.assertEquals("Hello javacard world !", new String(response.getData()));
+ }
+
+ @Test
+ public void testProxyApplet() throws Exception {
+
+ Properties props = new Properties();
+ props.load(new FileReader("conf/jcardsim.cfg"));
+
+ String s = (String)props.get("com.licel.jcardsim.smartcardio.applet.1.AID");
+ byte[] aidBytes = Hex.decode(s);
+ AID appletAID = new AID(aidBytes, (short) 0, (byte) aidBytes.length);
+
+ Simulator simulator = new Simulator();
+
+ simulator.installApplet(appletAID, ProxyApplet.class);
+ simulator.selectApplet(appletAID);
+
+ // test NOP
+ ResponseAPDU response = simulator.transmitCommand(new CommandAPDU(0x01, 0x02, 0x00, 0x00));
+ Assert.assertEquals(0x9000, response.getSW());
+
+ // test hello world from card
+ response = simulator.transmitCommand(new CommandAPDU(0x01, 0x01, 0x00, 0x00));
+ Assert.assertEquals(0x9000, response.getSW());
+ Assert.assertEquals("ProxyApplet", new String(response.getData()));
+
+ // test echo
+ response = simulator.transmitCommand(new CommandAPDU(0x01, 0x01, 0x01, 0x00, ("Hello javacard world !").getBytes()));
+ Assert.assertEquals(0x9000, response.getSW());
+ Assert.assertEquals("Hello javacard world !", new String(response.getData()));
+ }
+}