diff --git a/provisioning_tool/Android.bp b/ProvisioningTool/Android.bp similarity index 98% rename from provisioning_tool/Android.bp rename to ProvisioningTool/Android.bp index 579d2ff4..ad1ee2d1 100644 --- a/provisioning_tool/Android.bp +++ b/ProvisioningTool/Android.bp @@ -19,7 +19,7 @@ cc_binary { vendor: true, relative_install_path: "hw", srcs: [ - "provision_tool.cpp", + "ProvisionTool.cpp", ], shared_libs: [ "libdl", diff --git a/provisioning_tool/Provision.cpp b/ProvisioningTool/Provision.cpp similarity index 100% rename from provisioning_tool/Provision.cpp rename to ProvisioningTool/Provision.cpp diff --git a/provisioning_tool/Provision.h b/ProvisioningTool/Provision.h similarity index 100% rename from provisioning_tool/Provision.h rename to ProvisioningTool/Provision.h diff --git a/provisioning_tool/provision_tool.cpp b/ProvisioningTool/ProvisionTool.cpp similarity index 100% rename from provisioning_tool/provision_tool.cpp rename to ProvisioningTool/ProvisionTool.cpp diff --git a/provisioning_tool/README.md b/ProvisioningTool/README.md similarity index 65% rename from provisioning_tool/README.md rename to ProvisioningTool/README.md index 9f0dfbb4..0eeb4f8d 100644 --- a/provisioning_tool/README.md +++ b/ProvisioningTool/README.md @@ -1,14 +1,19 @@ # Provisioning tool This directory contains provisioning tool which helps in provisioning the secure element by using the APIs exposed by Provision library. -This tool takes the input parameters from json file. A sample -json file is located in this directory with name [sample_json.txt](https://github.com/BKSSMVenkateswarlu/JavaCardKeymaster/blob/master/provisioning_tool/sample_json.txt) for -your reference. +This tool takes the input parameters from json file. #### Build This tool can be built along with aosp build. It has dependency on -[libjc_common](https://github.com/BKSSMVenkateswarlu/JavaCardKeymaster/blob/master/HAL/keymaster/Android.bp) and -libjc_provision. +[libjc_common](../HAL/keymaster/Android.bp) and +[libjc_provision](Android.bp). + +#### Sample resources for quick testing +A sample json file is located in this directory with name [sample_json.txt](sample_json.txt) +for your reference. Also the required certificates and keys can be found +in [test_resources](test_resources) directory. Copy the certificates and the key into the +emulator/device filesystem in their respective paths mentioned in the +sample_json.txt. #### Usage
diff --git a/provisioning_tool/sample_json.txt b/ProvisioningTool/sample_json.txt
similarity index 100%
rename from provisioning_tool/sample_json.txt
rename to ProvisioningTool/sample_json.txt
diff --git a/ProvisioningTool/test_resources/batch_cert.der b/ProvisioningTool/test_resources/batch_cert.der
new file mode 100644
index 00000000..355bc984
Binary files /dev/null and b/ProvisioningTool/test_resources/batch_cert.der differ
diff --git a/ProvisioningTool/test_resources/batch_key.der b/ProvisioningTool/test_resources/batch_key.der
new file mode 100644
index 00000000..f4902073
Binary files /dev/null and b/ProvisioningTool/test_resources/batch_key.der differ
diff --git a/ProvisioningTool/test_resources/ca_cert.der b/ProvisioningTool/test_resources/ca_cert.der
new file mode 100644
index 00000000..f574a4c5
Binary files /dev/null and b/ProvisioningTool/test_resources/ca_cert.der differ
diff --git a/ProvisioningTool/test_resources/ca_key.der b/ProvisioningTool/test_resources/ca_key.der
new file mode 100644
index 00000000..e687b07f
Binary files /dev/null and b/ProvisioningTool/test_resources/ca_key.der differ
diff --git a/ProvisioningTool/test_resources/intermediate_cert.der b/ProvisioningTool/test_resources/intermediate_cert.der
new file mode 100644
index 00000000..615f423e
Binary files /dev/null and b/ProvisioningTool/test_resources/intermediate_cert.der differ
diff --git a/ProvisioningTool/test_resources/intermediate_key.der b/ProvisioningTool/test_resources/intermediate_key.der
new file mode 100644
index 00000000..888e4f38
Binary files /dev/null and b/ProvisioningTool/test_resources/intermediate_key.der differ
diff --git a/TestingTools/JCProxy/.project b/TestingTools/JCProxy/.project
new file mode 100644
index 00000000..dbfe8daa
--- /dev/null
+++ b/TestingTools/JCProxy/.project
@@ -0,0 +1,17 @@
+
+
+	JCProxy
+	
+	
+	
+	
+		
+			org.eclipse.jdt.core.javabuilder
+			
+			
+		
+	
+	
+		org.eclipse.jdt.core.javanature
+	
+
diff --git a/TestingTools/JCProxy/lib/apduio-RELEASE71.jar b/TestingTools/JCProxy/lib/apduio-RELEASE71.jar
new file mode 100644
index 00000000..6560f6e8
Binary files /dev/null and b/TestingTools/JCProxy/lib/apduio-RELEASE71.jar differ
diff --git a/TestingTools/JCProxy/lib/jcardsim-3.0.5-SNAPSHOT.jar b/TestingTools/JCProxy/lib/jcardsim-3.0.5-SNAPSHOT.jar
new file mode 100644
index 00000000..d756d67b
Binary files /dev/null and b/TestingTools/JCProxy/lib/jcardsim-3.0.5-SNAPSHOT.jar differ
diff --git a/TestingTools/JCProxy/src/com/android/javacard/jcproxy/JCProxyMain.java b/TestingTools/JCProxy/src/com/android/javacard/jcproxy/JCProxyMain.java
new file mode 100644
index 00000000..2de1feba
--- /dev/null
+++ b/TestingTools/JCProxy/src/com/android/javacard/jcproxy/JCProxyMain.java
@@ -0,0 +1,107 @@
+package com.android.javacard.jcproxy;
+
+import java.io.*;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+
+import com.sun.javacard.apduio.CadTransportException;
+
+/**
+ * This program demonstrates a simple TCP/IP socket server.
+ *
+ * @author www.codejava.net
+ */
+public class JCProxyMain {
+
+  public static void main(String[] args) {
+    if (args.length < 1) {
+      System.out.println("Port no is expected as argument.");
+      return;
+    }
+
+    int port = Integer.parseInt(args[0]);
+    Simulator simulator = new JCardSimulator();
+
+    try (ServerSocket serverSocket = new ServerSocket(port)) {
+      simulator.initaliseSimulator();
+      if (!simulator.setupKeymasterOnSimulator()) {
+        System.out.println("Failed to setup Java card keymaster simulator.");
+        System.exit(-1);
+      }
+      byte[] outData;
+
+      while (true) {
+        try {
+          Socket socket = serverSocket.accept();
+          System.out.println("\n\n\n\n\n");
+          System.out.println("------------------------New client connected on "
+                  + socket.getPort() + "--------------------");
+          OutputStream output = null;
+          InputStream isReader = null;
+          try {
+            socket.setReceiveBufferSize(1024 * 5);
+            output = socket.getOutputStream();
+            isReader = socket.getInputStream();
+
+            byte[] inBytes = new byte[65536];
+            int readLen = 0, index = 0;
+            System.out.println("Socket input buffer size: "
+                    + socket.getReceiveBufferSize());
+            while ((readLen = isReader.read(inBytes, index, 1024 * 5)) > 0) {
+              if (readLen > 0) {
+                System.out.println("Bytes read from index (" + index
+                        + ") socket: " + readLen + " Estimate read: "
+                        + isReader.available());
+                byte[] outBytes;
+
+                try {
+                  outBytes = simulator.executeApdu(
+                          Arrays.copyOfRange(inBytes, 0, index + readLen));
+                  outData = simulator.decodeDataOut();
+                  System.out.println(
+                          "Return Data " + Utils.byteArrayToHexString(outData));
+                  byte[] finalOutData = new byte[outData.length
+                          + outBytes.length];
+                  System.arraycopy(outData, 0, finalOutData, 0, outData.length);
+                  System.arraycopy(outBytes, 0, finalOutData, outData.length,
+                          outBytes.length);
+                  output.write(finalOutData);
+                  output.flush();
+                  index = 0;
+                } catch (IllegalArgumentException e) {
+                  e.printStackTrace();
+                  index = readLen;
+                }
+              }
+            }
+          } catch (IOException e) {
+            e.printStackTrace();
+          } catch (Exception e) {
+            e.printStackTrace();
+          } finally {
+            if (output != null)
+              output.close();
+            if (isReader != null)
+              isReader.close();
+            socket.close();
+          }
+        } catch (IOException e) {
+          break;
+        } catch (Exception e) {
+          break;
+        }
+        System.out.println("Client disconnected.");
+      }
+      simulator.disconnectSimulator();
+    } catch (IOException ex) {
+      System.out.println("Server exception: " + ex.getMessage());
+      ex.printStackTrace();
+    } catch (CadTransportException e1) {
+      e1.printStackTrace();
+    } catch (Exception e1) {
+      e1.printStackTrace();
+    }
+  }
+}
diff --git a/TestingTools/JCProxy/src/com/android/javacard/jcproxy/JCardSimulator.java b/TestingTools/JCProxy/src/com/android/javacard/jcproxy/JCardSimulator.java
new file mode 100644
index 00000000..7af495f3
--- /dev/null
+++ b/TestingTools/JCProxy/src/com/android/javacard/jcproxy/JCardSimulator.java
@@ -0,0 +1,61 @@
+package com.android.javacard.jcproxy;
+
+import javax.smartcardio.CommandAPDU;
+import javax.smartcardio.ResponseAPDU;
+
+import com.android.javacard.keymaster.KMJCardSimApplet;
+import com.licel.jcardsim.smartcardio.CardSimulator;
+import com.licel.jcardsim.utils.AIDUtil;
+
+import javacard.framework.AID;
+
+public class JCardSimulator implements Simulator {
+
+  private CardSimulator simulator;
+  ResponseAPDU response;
+
+  public JCardSimulator() {
+    simulator = new CardSimulator();
+  }
+
+  @Override
+  public void initaliseSimulator() throws Exception {
+  }
+
+  @Override
+  public void disconnectSimulator() throws Exception {
+    AID appletAID1 = AIDUtil.create("A000000062");
+    // Delete i.e. uninstall applet
+    simulator.deleteApplet(appletAID1);
+  }
+
+  @Override
+  public boolean setupKeymasterOnSimulator() throws Exception {
+    AID appletAID1 = AIDUtil.create("A000000062");
+    simulator.installApplet(appletAID1, KMJCardSimApplet.class);
+    // Select applet
+    simulator.selectApplet(appletAID1);
+    return true;
+  }
+
+  private final byte[] intToByteArray(int value) {
+    return new byte[] {
+            (byte) (value >>> 8), (byte) value };
+  }
+
+  @Override
+  public byte[] executeApdu(byte[] apdu) throws Exception {
+    System.out.println("Executing APDU = " + Utils.byteArrayToHexString(apdu));
+    CommandAPDU apduCmd = new CommandAPDU(apdu);
+    response = simulator.transmitCommand(apduCmd);
+    System.out.println("Status = "
+            + Utils.byteArrayToHexString(intToByteArray(response.getSW())));
+    return intToByteArray(response.getSW());
+  }
+
+  @Override
+  public byte[] decodeDataOut() {
+    return response.getData();
+  }
+
+}
diff --git a/TestingTools/JCProxy/src/com/android/javacard/jcproxy/Simulator.java b/TestingTools/JCProxy/src/com/android/javacard/jcproxy/Simulator.java
new file mode 100644
index 00000000..6c4f9bbc
--- /dev/null
+++ b/TestingTools/JCProxy/src/com/android/javacard/jcproxy/Simulator.java
@@ -0,0 +1,15 @@
+package com.android.javacard.jcproxy;
+
+public interface Simulator {
+  byte[] STATUS_OK = Utils.hexStringToByteArray("9000");
+
+  void initaliseSimulator() throws Exception;
+
+  void disconnectSimulator() throws Exception;
+
+  public boolean setupKeymasterOnSimulator() throws Exception;
+
+  byte[] executeApdu(byte[] apdu) throws Exception;
+
+  byte[] decodeDataOut();
+}
diff --git a/TestingTools/JCProxy/src/com/android/javacard/jcproxy/Utils.java b/TestingTools/JCProxy/src/com/android/javacard/jcproxy/Utils.java
new file mode 100644
index 00000000..50470f6b
--- /dev/null
+++ b/TestingTools/JCProxy/src/com/android/javacard/jcproxy/Utils.java
@@ -0,0 +1,28 @@
+package com.android.javacard.jcproxy;
+
+public class Utils {
+
+  public static byte[] hexStringToByteArray(String s) {
+    int len = s.length();
+    if (len % 2 != 0)
+      throw new IllegalArgumentException("Expecting each byte of 2 char.");
+    byte[] data = new byte[len / 2];
+    for (int i = 0; i < len; i += 2) {
+      data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+              + Character.digit(s.charAt(i + 1), 16));
+    }
+    return data;
+  }
+
+  private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
+
+  public static String byteArrayToHexString(byte[] bytes) {
+    char[] hexChars = new char[bytes.length * 2];
+    for (int j = 0; j < bytes.length; j++) {
+      int v = bytes[j] & 0xFF;
+      hexChars[j * 2] = HEX_ARRAY[v >>> 4];
+      hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
+    }
+    return new String(hexChars);
+  }
+}
diff --git a/TestingTools/README.md b/TestingTools/README.md
new file mode 100644
index 00000000..adc3da27
--- /dev/null
+++ b/TestingTools/README.md
@@ -0,0 +1,11 @@
+# TestingTools
+[JCProxy](JCProxy) is a testing tool, which provides a way to communicate with 
+JCardSimulator from android emulator/device.
+It basically opens a socket connection on the port (port mentioned in program arguments)
+and listens for the incomming data on this port. This tool uses apduio and JCarsim jars
+to validate and transmit the APDUs to the Keymaster Applet.
+
+###Build
+Import JCProxy server application either in Eclipse or IntelliJ. Add the provided jars inside
+[lib](JCProxy/lib) directory to the project and also add [Keymaster Applet](../Applet) as
+dependent project. Add port number (Ex: 8080) as program arguments.