package com.licel.jcardsim.base; import com.licel.jcardsim.samples.Sha1Applet; import javacard.framework.AID; import junit.framework.TestCase; import org.bouncycastle.util.encoders.Hex; import javax.smartcardio.ResponseAPDU; import java.nio.ByteBuffer; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; public class ExtendedLengthTest extends TestCase { private static final byte CLA = (byte) 0x80; private static final byte INS_DIGEST = 0; private static final byte INS_ECHO = 2; private static final byte INS_LEN = 4; private static final byte P1 = (byte) 0; private static final byte P2 = (byte) 0; private static final byte DUMMY = (byte) 0x41; private static final byte[] TEST_APPLET_AID_BYTES = Hex.decode("0102030405cafe01"); public ExtendedLengthTest(String testName) { super(testName); } private Simulator prepareSimulator() { Simulator instance = new Simulator(); AID aid = new AID(TEST_APPLET_AID_BYTES, (short) 0, (byte) TEST_APPLET_AID_BYTES.length); instance.installApplet(aid, Sha1Applet.class); instance.selectApplet(aid); return instance; } public void testRegularApduDigest() throws NoSuchAlgorithmException { MessageDigest sha1 = MessageDigest.getInstance("SHA1"); byte[] expectedOutput = sha1.digest(new byte[]{DUMMY}); Simulator instance = prepareSimulator(); byte[] apdu = new byte[]{CLA, INS_DIGEST, P1, P2, 1, DUMMY}; byte[] result = instance.transmitCommand(apdu); ResponseAPDU responseApdu = new ResponseAPDU(result); assertEquals(0x9000, responseApdu.getSW()); assertEquals(Arrays.toString(expectedOutput), Arrays.toString(responseApdu.getData())); } public void testRegularApduLcLe() { byte lc = 1; byte le = (byte) 0xA0; byte[] expectedOutput = new byte[]{0, lc, 0, le}; Simulator instance = prepareSimulator(); byte[] apdu = new byte[]{CLA, INS_LEN, P1, P2, lc, 0, le}; byte[] result = instance.transmitCommand(apdu); ResponseAPDU responseApdu = new ResponseAPDU(result); assertEquals(0x9000, responseApdu.getSW()); assertEquals(Arrays.toString(expectedOutput), Arrays.toString(responseApdu.getData())); } public void testRegularApduCase2Le() { byte le = (byte) 0x4; byte[] expectedOutput = new byte[]{0, 0, 0, le}; Simulator instance = prepareSimulator(); byte[] apdu = new byte[]{CLA, INS_LEN, P1, P2, le}; byte[] result = instance.transmitCommand(apdu); ResponseAPDU responseApdu = new ResponseAPDU(result); assertEquals(0x9000, responseApdu.getSW()); assertEquals(Arrays.toString(expectedOutput), Arrays.toString(responseApdu.getData())); } public void testRegularApduEcho() throws NoSuchAlgorithmException { byte[] expectedOutput = new byte[]{DUMMY}; Simulator instance = prepareSimulator(); byte[] apdu = new byte[]{CLA, INS_ECHO, 0, 0, 1, DUMMY}; byte[] result = instance.transmitCommand(apdu); ResponseAPDU responseApdu = new ResponseAPDU(result); assertEquals(0x9000, responseApdu.getSW()); assertEquals(Arrays.toString(expectedOutput), Arrays.toString(responseApdu.getData())); } public void testExtendedApduDigestWith1Byte() throws NoSuchAlgorithmException { MessageDigest sha1 = MessageDigest.getInstance("SHA1"); byte[] input = new byte[]{DUMMY}; byte[] expectedOutput = sha1.digest(input); Simulator instance = prepareSimulator(); byte[] apdu = new byte[]{CLA, INS_DIGEST, 0, 0, 0, 0, 1, DUMMY}; byte[] result = instance.transmitCommand(apdu); ResponseAPDU responseApdu = new ResponseAPDU(result); assertEquals(0x9000, responseApdu.getSW()); assertEquals(Arrays.toString(expectedOutput), Arrays.toString(responseApdu.getData())); } public void testExtendedApduCase2Le4() { byte le = (byte) 0x4; byte[] expectedOutput = new byte[]{0, 0, 0, le}; Simulator instance = prepareSimulator(); byte[] apdu = new byte[]{CLA, INS_LEN, P1, P2, 0, 0, le}; byte[] result = instance.transmitCommand(apdu); ResponseAPDU responseApdu = new ResponseAPDU(result); assertEquals(0x9000, responseApdu.getSW()); assertEquals(Arrays.toString(expectedOutput), Arrays.toString(responseApdu.getData())); } public void testExtendedApduCase2Le() { byte[] expectedOutput = new byte[]{0, 0, 1, 2}; Simulator instance = prepareSimulator(); byte[] apdu = new byte[]{CLA, INS_LEN, P1, P2, 0, 1, 2}; byte[] result = instance.transmitCommand(apdu); ResponseAPDU responseApdu = new ResponseAPDU(result); assertEquals(0x9000, responseApdu.getSW()); assertEquals(Arrays.toString(expectedOutput), Arrays.toString(responseApdu.getData())); } public void testExtendedApduLcLe() { byte[] expectedOutput = {0x0, 0x1, 0x1F, (byte) 0xCA}; Simulator instance = prepareSimulator(); byte[] apdu = new byte[]{CLA, INS_LEN, P1, P2, 0, 0, 1, DUMMY, 0x1F, (byte) 0xCA}; byte[] result = instance.transmitCommand(apdu); ResponseAPDU responseApdu = new ResponseAPDU(result); assertEquals(0x9000, responseApdu.getSW()); assertEquals(Arrays.toString(expectedOutput), Arrays.toString(responseApdu.getData())); } public void testExtendedApduEchoWith1Byte() throws NoSuchAlgorithmException { byte[] expectedOutput = {0x41}; Simulator instance = prepareSimulator(); byte[] apdu = new byte[]{CLA, INS_ECHO, 0, 0, 0, 0, 1, DUMMY}; byte[] result = instance.transmitCommand(apdu); ResponseAPDU responseApdu = new ResponseAPDU(result); assertEquals(0x9000, responseApdu.getSW()); assertEquals(Arrays.toString(expectedOutput), Arrays.toString(responseApdu.getData())); } public void testExtendedApduDigest() throws NoSuchAlgorithmException { MessageDigest sha1 = MessageDigest.getInstance("SHA1"); byte[] input = new byte[Short.MAX_VALUE]; Arrays.fill(input, DUMMY); byte[] expectedOutput = sha1.digest(input); Simulator instance = prepareSimulator(); ByteBuffer inputApdu = ByteBuffer.wrap(new byte[input.length + 7]); inputApdu.put(CLA); inputApdu.put(INS_DIGEST); inputApdu.put(P1); inputApdu.put(P2); inputApdu.put((byte) 0).putShort((short) input.length); // Lc inputApdu.put(input); byte[] result = instance.transmitCommand(inputApdu.array()); ResponseAPDU responseApdu = new ResponseAPDU(result); assertEquals(0x9000, responseApdu.getSW()); assertEquals(Arrays.toString(expectedOutput), Arrays.toString(responseApdu.getData())); } public void testExtendedApduEcho() { byte[] input = new byte[Short.MAX_VALUE - 2]; Arrays.fill(input, (byte) 0x41); Simulator instance = prepareSimulator(); ByteBuffer inputApdu = ByteBuffer.wrap(new byte[input.length + 7]); inputApdu.put(CLA); inputApdu.put(INS_ECHO); inputApdu.put(P1); inputApdu.put(P2); inputApdu.put((byte) 0).putShort((short) input.length); // Lc inputApdu.put(input); byte[] result = instance.transmitCommand(inputApdu.array()); ResponseAPDU responseApdu = new ResponseAPDU(result); assertEquals(0x9000, responseApdu.getSW()); assertEquals(Arrays.toString(input), Arrays.toString(responseApdu.getData())); } }