diff --git a/app/src/main/java/im/status/applet_installer_test/appletinstaller/APDUWrapper.java b/app/src/main/java/im/status/applet_installer_test/appletinstaller/APDUWrapper.java new file mode 100644 index 0000000..86b42b6 --- /dev/null +++ b/app/src/main/java/im/status/applet_installer_test/appletinstaller/APDUWrapper.java @@ -0,0 +1,43 @@ +package im.status.applet_installer_test.appletinstaller; + + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.NoSuchAlgorithmException; + +import javax.crypto.NoSuchPaddingException; + +public class APDUWrapper { + private byte[] macKeyData; + + public APDUWrapper(byte[] macKeyData) { + this.macKeyData = macKeyData; + } + + public APDUCommand wrap(APDUCommand cmd) { + try { + int cla = (cmd.getCla() | 0x04) & 0xff; + byte[] data = cmd.getData(); + + ByteArrayOutputStream macData = new ByteArrayOutputStream(); + macData.write(cla); + macData.write(cmd.getIns()); + macData.write(cmd.getP1()); + macData.write(cmd.getP2()); + macData.write(data.length + 8); + macData.write(data); + + byte[] mac = Crypto.macFull3des(this.macKeyData, Crypto.appendDESPadding(macData.toByteArray()), Crypto.NullBytes8); + byte[] newData = new byte[data.length + mac.length]; + System.arraycopy(data, 0, newData, 0, data.length ); + System.arraycopy(mac, 0, newData, data.length, mac.length ); + + APDUCommand wrapped = new APDUCommand(cla, cmd.getIns(), cmd.getP1(), cmd.getP2(), newData); + + return wrapped; + } catch (IOException e) { + throw new RuntimeException("error wrapping APDU command.", e); + } + } +} diff --git a/app/src/test/java/im/status/applet_installer_test/appletinstaller/APDUWrapperTest.java b/app/src/test/java/im/status/applet_installer_test/appletinstaller/APDUWrapperTest.java new file mode 100644 index 0000000..20f4f2f --- /dev/null +++ b/app/src/test/java/im/status/applet_installer_test/appletinstaller/APDUWrapperTest.java @@ -0,0 +1,22 @@ +package im.status.applet_installer_test.appletinstaller; + +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.*; + +public class APDUWrapperTest { + @Test + public void wrap() throws IOException { + byte[] macKeyData = HexUtils.hexStringToByteArray("904BA06BCE3037710556BE4057D1493C"); + byte[] data = HexUtils.hexStringToByteArray("7af26ab1ba32b84f"); + + APDUCommand cmd = new APDUCommand(0x84, 0x82, 0x01, 0x00, data); + APDUWrapper w = new APDUWrapper(macKeyData); + APDUCommand wrapped = w.wrap(cmd); + byte[] result = wrapped.serialize(); + String expected = "84820100107AF26AB1BA32B84FFE949381C7BC316C00"; + assertEquals(expected, HexUtils.byteArrayToHexString(result)); + } +} \ No newline at end of file