aboutsummaryrefslogtreecommitdiff
path: root/src/cz/crcs/ectester/applet/AppletBase.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cz/crcs/ectester/applet/AppletBase.java')
-rw-r--r--src/cz/crcs/ectester/applet/AppletBase.java1026
1 files changed, 0 insertions, 1026 deletions
diff --git a/src/cz/crcs/ectester/applet/AppletBase.java b/src/cz/crcs/ectester/applet/AppletBase.java
deleted file mode 100644
index 9a8a479..0000000
--- a/src/cz/crcs/ectester/applet/AppletBase.java
+++ /dev/null
@@ -1,1026 +0,0 @@
-package cz.crcs.ectester.applet;
-
-import javacard.framework.*;
-import javacard.security.*;
-
-/**
- * Applet base class, that handles instructions, given
- * either basic or extended length APDUs.
- *
- * @author Petr Svenda petr@svenda.com
- * @author Jan Jancar johny@neuromancer.sk
- */
-public abstract class AppletBase extends Applet {
-
- // MAIN INSTRUCTION CLASS
- public static final byte CLA_ECTESTERAPPLET = (byte) 0xB0;
-
- // INSTRUCTIONS
- public static final byte INS_ALLOCATE = (byte) 0x5a;
- public static final byte INS_CLEAR = (byte) 0x5b;
- public static final byte INS_SET = (byte) 0x5c;
- public static final byte INS_TRANSFORM = (byte) 0x5d;
- public static final byte INS_GENERATE = (byte) 0x5e;
- public static final byte INS_EXPORT = (byte) 0x5f;
- public static final byte INS_ECDH = (byte) 0x70;
- public static final byte INS_ECDH_DIRECT = (byte) 0x71;
- public static final byte INS_ECDSA = (byte) 0x72;
- public static final byte INS_ECDSA_SIGN = (byte) 0x73;
- public static final byte INS_ECDSA_VERIFY = (byte) 0x74;
- public static final byte INS_CLEANUP = (byte) 0x75;
- public static final byte INS_ALLOCATE_KA = (byte) 0x76;
- public static final byte INS_ALLOCATE_SIG = (byte) 0x77;
- public static final byte INS_GET_INFO = (byte) 0x78;
- public static final byte INS_SET_DRY_RUN_MODE = (byte) 0x79;
- public static final byte INS_BUFFER = (byte) 0x7a;
- public static final byte INS_PERFORM = (byte) 0x7b;
-
- // PARAMETERS for P1 and P2
- public static final byte KEYPAIR_LOCAL = (byte) 0x01;
- public static final byte KEYPAIR_REMOTE = (byte) 0x02;
- public static final byte KEYPAIR_BOTH = KEYPAIR_LOCAL | KEYPAIR_REMOTE;
- public static final byte BUILD_KEYPAIR = (byte) 0x01;
- public static final byte BUILD_KEYBUILDER = (byte) 0x02;
- public static final byte EXPORT_TRUE = (byte) 0xff;
- public static final byte EXPORT_FALSE = (byte) 0x00;
- public static final byte MODE_NORMAL = (byte) 0xaa;
- public static final byte MODE_DRY_RUN = (byte) 0xbb;
-
- // STATUS WORDS
- public static final short SW_SIG_VERIFY_FAIL = (short) 0x0ee1;
- public static final short SW_DH_DHC_MISMATCH = (short) 0x0ee2;
- public static final short SW_KEYPAIR_NULL = (short) 0x0ee3;
- public static final short SW_KA_NULL = (short) 0x0ee4;
- public static final short SW_SIGNATURE_NULL = (short) 0x0ee5;
- public static final short SW_OBJECT_NULL = (short) 0x0ee6;
- public static final short SW_CANNOT_FIT = (short) 0x0ee7;
- public static final short SW_Exception = (short) 0xff01;
- public static final short SW_ArrayIndexOutOfBoundsException = (short) 0xff02;
- public static final short SW_ArithmeticException = (short) 0xff03;
- public static final short SW_ArrayStoreException = (short) 0xff04;
- public static final short SW_NullPointerException = (short) 0xff05;
- public static final short SW_NegativeArraySizeException = (short) 0xff06;
- public static final short SW_CryptoException_prefix = (short) 0xf100;
- public static final short SW_SystemException_prefix = (short) 0xf200;
- public static final short SW_PINException_prefix = (short) 0xf300;
- public static final short SW_TransactionException_prefix = (short) 0xf400;
- public static final short SW_CardRuntimeException_prefix = (short) 0xf500;
-
- //
- public static final short BASE_221 = (short) 0x0221;
- public static final short BASE_222 = (short) 0x0222;
-
- //
- public static final short CDATA_BASIC = (short) 5;
- public static final short CDATA_EXTENDED = (short) 7;
-
- //
- public static final byte[] VERSION = {'v', '0', '.', '3', '.', '3'};
-
- public static final short ARRAY_LENGTH = 0x100;
- public static final short APDU_MAX_LENGTH = 1024;//512
-
- // TEMPORARRY ARRAY IN RAM
- byte[] ramArray = null;
- byte[] ramArray2 = null;
- byte[] apduArray = null;
- short apduEnd = 0;
- short cdata = 0;
-
- RandomData randomData = null;
-
- ECKeyTester keyTester = null;
- ECKeyGenerator keyGenerator = null;
- KeyPair localKeypair = null;
- KeyPair remoteKeypair = null;
-
- protected AppletBase(byte[] buffer, short offset, byte length) {
- if (length > 9) {
- /*
- short dataOffset = offset;
- // shift to privilege offset
- dataOffset += (short) (1 + buffer[offset]);
- // finally shift to Application specific offset
- dataOffset += (short) (1 + buffer[dataOffset]);
- // go to proprietary data
- dataOffset++;
- */
- short resetMemory = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
- short deselectMemory = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
- short bigMem;
- short smallMem;
- byte bigMemType;
- byte smallMemType;
- if (resetMemory >= deselectMemory) {
- bigMem = resetMemory;
- smallMem = deselectMemory;
- bigMemType = JCSystem.CLEAR_ON_RESET;
- smallMemType = JCSystem.CLEAR_ON_DESELECT;
- } else {
- bigMem = deselectMemory;
- smallMem = resetMemory;
- bigMemType = JCSystem.CLEAR_ON_DESELECT;
- smallMemType = JCSystem.CLEAR_ON_RESET;
- }
- short[] lensBig = new short[]{APDU_MAX_LENGTH + 2 * ARRAY_LENGTH, APDU_MAX_LENGTH + ARRAY_LENGTH, APDU_MAX_LENGTH,};
- short[] lensSmall = new short[]{0, ARRAY_LENGTH, 2 * ARRAY_LENGTH};
- byte[] allocsBig = new byte[]{0x07, 0x03, 0x01};
- boolean done = false;
- for (short i = 0; i < 3; ++i) {
- if (lensBig[i] <= bigMem && lensSmall[i] <= smallMem) {
- byte allocI = 1;
- while (allocI < 0x08) {
- byte type = ((allocI & allocsBig[i]) != 0) ? bigMemType : smallMemType;
- switch (allocI) {
- case 0x01:
- apduArray = JCSystem.makeTransientByteArray(APDU_MAX_LENGTH, type);
- break;
- case 0x02:
- ramArray = JCSystem.makeTransientByteArray(ARRAY_LENGTH, type);
- break;
- case 0x04:
- ramArray2 = JCSystem.makeTransientByteArray(ARRAY_LENGTH, type);
- break;
- }
- allocI = (byte) (allocI << 1);
- }
- done = true;
- break;
- }
- }
- if (!done) {
- ISOException.throwIt((short) 0x6a84);
- }
-
- randomData = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
- EC_Consts.randomData = randomData;
-
- keyGenerator = new ECKeyGenerator();
- keyTester = new ECKeyTester();
- }
- }
-
- public void process(APDU apdu) throws ISOException {
- // get the APDU buffer
- byte[] apduBuffer = apdu.getBuffer();
- byte cla = apduBuffer[ISO7816.OFFSET_CLA];
- byte ins = apduBuffer[ISO7816.OFFSET_INS];
-
- // ignore the applet select command dispatched to the process
- if (selectingApplet()) {
- return;
- }
-
- if (cla == CLA_ECTESTERAPPLET) {
- try {
- if (ins == INS_BUFFER) {
- short read = readAPDU(apdu, true);
- if (read == -1) {
- ISOException.throwIt(SW_CANNOT_FIT);
- return;
- }
- apduEnd += read;
- apdu.setOutgoingAndSend((short) 0, (short) 0);
- return;
- } else {
- apduEnd = 0;
- if (ins == INS_PERFORM) {
- ins = apduArray[ISO7816.OFFSET_INS];
- apdu.setIncomingAndReceive();
- } else {
- if (readAPDU(apdu, false) == -1) {
- ISOException.throwIt(SW_CANNOT_FIT);
- return;
- }
- }
- }
-
- short length = 0;
- switch (ins) {
- case INS_ALLOCATE_KA:
- length = insAllocateKA(apdu);
- break;
- case INS_ALLOCATE_SIG:
- length = insAllocateSig(apdu);
- break;
- case INS_ALLOCATE:
- length = insAllocate(apdu);
- break;
- case INS_CLEAR:
- length = insClear(apdu);
- break;
- case INS_SET:
- length = insSet(apdu);
- break;
- case INS_TRANSFORM:
- length = insTransform(apdu);
- break;
- case INS_GENERATE:
- length = insGenerate(apdu);
- break;
- case INS_EXPORT:
- length = insExport(apdu);
- break;
- case INS_ECDH:
- length = insECDH(apdu);
- break;
- case INS_ECDH_DIRECT:
- length = insECDH_direct(apdu);
- break;
- case INS_ECDSA:
- length = insECDSA(apdu);
- break;
- case INS_ECDSA_SIGN:
- length = insECDSA_sign(apdu);
- break;
- case INS_ECDSA_VERIFY:
- length = insECDSA_verify(apdu);
- break;
- case INS_CLEANUP:
- length = insCleanup(apdu);
- break;
- case INS_GET_INFO:
- length = insGetInfo(apdu);
- break;
- case INS_SET_DRY_RUN_MODE:
- length = insSetDryRunMode(apdu);
- break;
- default:
- // The INS code is not supported by the dispatcher
- ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
- break;
- }
- apdu.setOutgoingAndSend((short) 0, length);
-
- } catch (ISOException e) {
- throw e; // Our exception from code, just re-emit
- } catch (ArrayIndexOutOfBoundsException e) {
- ISOException.throwIt(SW_ArrayIndexOutOfBoundsException);
- } catch (ArithmeticException e) {
- ISOException.throwIt(SW_ArithmeticException);
- } catch (ArrayStoreException e) {
- ISOException.throwIt(SW_ArrayStoreException);
- } catch (NullPointerException e) {
- ISOException.throwIt(SW_NullPointerException);
- } catch (NegativeArraySizeException e) {
- ISOException.throwIt(SW_NegativeArraySizeException);
- } catch (CryptoException e) {
- ISOException.throwIt((short) (SW_CryptoException_prefix | e.getReason()));
- } catch (SystemException e) {
- ISOException.throwIt((short) (SW_SystemException_prefix | e.getReason()));
- } catch (PINException e) {
- ISOException.throwIt((short) (SW_PINException_prefix | e.getReason()));
- } catch (TransactionException e) {
- ISOException.throwIt((short) (SW_TransactionException_prefix | e.getReason()));
- } catch (CardRuntimeException e) {
- ISOException.throwIt((short) (SW_CardRuntimeException_prefix | e.getReason()));
- } catch (Exception e) {
- ISOException.throwIt(SW_Exception);
- }
-
- } else ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
- }
-
- private short readAPDU(APDU apdu, boolean skipHeader) {
- byte[] apduBuffer = apdu.getBuffer();
-
- /* How much stuff is in apduBuffer */
- short read = apdu.setIncomingAndReceive();
- short cdataOffset = getOffsetCdata(apdu);
- read += cdataOffset;
-
- /* Where to start reading from? */
- short offset = 0;
- if (skipHeader) {
- offset = cdataOffset;
- cdata = CDATA_EXTENDED;
- } else {
- cdata = CDATA_BASIC;
- }
-
- /* How much stuff was really sent in this APDU? */
- short total = (short) (getIncomingLength(apdu) + cdataOffset);
- short todo = (short) (total - offset);
- /* Can we fit? */
- if (todo > (short) (apduArray.length - apduEnd)) {
- return -1;
- }
-
- /* How much stuff was copied over. */
- short written = 0;
- while (written < todo) {
- Util.arrayCopyNonAtomic(apduBuffer, offset, apduArray, (short) (apduEnd + written), (short) (read - offset));
- written += (short) (read - offset);
- offset = 0;
- read = apdu.receiveBytes((short) 0);
- }
- return written;
- }
-
- abstract short getOffsetCdata(APDU apdu);
-
- abstract short getIncomingLength(APDU apdu);
-
- abstract short getBase();
-
- /**
- * Allocates KeyAgreement object, returns allocate SW.
- *
- * @param apdu DATA = byte KeyAgreementType
- * @return length of response
- */
- private short insAllocateKA(APDU apdu) {
- byte kaType = apduArray[cdata];
- short sw = keyTester.allocateKA(kaType);
- Util.setShort(apdu.getBuffer(), (short) 0, sw);
- return 2;
- }
-
- /**
- * Allocates a Signature object, returns allocate SW.
- *
- * @param apdu DATA = byte SignatureType
- * @return length of response
- */
- private short insAllocateSig(APDU apdu) {
- byte sigType = apduArray[cdata];
- short sw = keyTester.allocateSig(sigType);
- Util.setShort(apdu.getBuffer(), (short) 0, sw);
- return 2;
- }
-
- /**
- * Allocates local and remote keyPairs.
- * returns allocate SWs
- *
- * @param apdu P1 = byte keyPair (KEYPAIR_* | ...)
- * P2 = byte build
- * DATA = short keyLength
- * byte keyClass
- * @return length of response
- */
- private short insAllocate(APDU apdu) {
- byte keyPair = apduArray[ISO7816.OFFSET_P1];
- byte build = apduArray[ISO7816.OFFSET_P2];
- short keyLength = Util.getShort(apduArray, cdata);
- byte keyClass = apduArray[(short) (cdata + 2)];
-
- return allocate(keyPair, build, keyLength, keyClass, apdu.getBuffer(), (short) 0);
- }
-
- /**
- * Clears local and remote keyPair's keys {@code .clearKey()}.
- * returns clearKey SWs
- *
- * @param apdu P1 = byte keyPair (KEYPAIR_* | ...)
- * P2 =
- * @return length of response
- */
- private short insClear(APDU apdu) {
- byte keyPair = apduArray[ISO7816.OFFSET_P1];
-
- short len = 0;
- if ((keyPair & KEYPAIR_LOCAL) != 0) {
- len += clear(localKeypair, apdu.getBuffer(), (short) 0);
- }
- if ((keyPair & KEYPAIR_REMOTE) != 0) {
- len += clear(remoteKeypair, apdu.getBuffer(), len);
- }
-
- return len;
- }
-
- /**
- * Sets curve parameters on local and remote keyPairs.
- * returns setCurve SWs
- *
- * @param apdu P1 = byte keyPair (KEYPAIR_* | ...)
- * P2 = byte curve (EC_Consts.CURVE_*)
- * DATA = short params (EC_Consts.PARAMETER_* | ...)
- * <p>
- * if curveID = CURVE_EXTERNAL:
- * [short paramLength, byte[] param],
- * for all params in params,
- * in order: field,a,b,g,r,k,w,s
- * @return length of response
- */
- private short insSet(APDU apdu) {
- byte keyPair = apduArray[ISO7816.OFFSET_P1];
- byte curve = apduArray[ISO7816.OFFSET_P2];
- short params = Util.getShort(apduArray, cdata);
-
- short len = 0;
-
- if ((keyPair & KEYPAIR_LOCAL) != 0) {
- len += set(localKeypair, curve, params, apduArray, (short) (cdata + 2), apdu.getBuffer(), (short) 0);
- }
- if ((keyPair & KEYPAIR_REMOTE) != 0) {
- len += set(remoteKeypair, curve, params, apduArray, (short) (cdata + 2), apdu.getBuffer(), len);
- }
-
- return len;
- }
-
- /**
- * Transforms curve paramaters of local and remote keyPairs.
- * returns transformCurve SWs
- *
- * @param apdu P1 = byte keyPair (KEYPAIR_* | ...)
- * P2 = byte key (EC_Consts.KEY_* | ...)
- * DATA = short params (EC_Consts.PARAMETER_* | ...)
- * short transformation (EC_Consts.TRANSFORMATION_* || ...)
- * @return length of response
- */
- private short insTransform(APDU apdu) {
- byte keyPair = apduArray[ISO7816.OFFSET_P1];
- byte key = apduArray[ISO7816.OFFSET_P2];
- short params = Util.getShort(apduArray, cdata);
- short transformation = Util.getShort(apduArray, (short) (cdata + 2));
-
- short len = 0;
- if ((keyPair & KEYPAIR_LOCAL) != 0) {
- len += transform(localKeypair, key, params, transformation, apdu.getBuffer(), (short) 0);
- }
-
- if ((keyPair & KEYPAIR_REMOTE) != 0) {
- len += transform(remoteKeypair, key, params, transformation, apdu.getBuffer(), len);
- }
-
- return len;
- }
-
- /**
- * Generates the local and remote keyPairs.
- * returns generate SWs
- *
- * @param apdu P1 = byte keyPair (KEYPAIR_* | ...)
- * P2 =
- * @return length of response
- */
- private short insGenerate(APDU apdu) {
- byte keyPair = apduArray[ISO7816.OFFSET_P1];
-
- short len = 0;
- if ((keyPair & KEYPAIR_LOCAL) != 0) {
- len += generate(localKeypair, apdu.getBuffer(), (short) 0);
- }
- if ((keyPair & KEYPAIR_REMOTE) != 0) {
- len += generate(remoteKeypair, apdu.getBuffer(), len);
- }
-
- return len;
- }
-
- /**
- * Exports selected key and domain parameters from the selected keyPair and key.
- *
- * @param apdu P1 = byte keyPair (KEYPAIR_* | ...)
- * P2 = byte key (EC_Consts.KEY_* | ...)
- * DATA = short params
- * @return length of response
- */
- private short insExport(APDU apdu) {
- byte keyPair = apduArray[ISO7816.OFFSET_P1];
- byte key = apduArray[ISO7816.OFFSET_P2];
- short params = Util.getShort(apduArray, cdata);
-
- short swOffset = 0;
- short len = (short) (keyPair == KEYPAIR_BOTH ? 4 : 2);
-
- if ((keyPair & KEYPAIR_LOCAL) != 0) {
- len += export(localKeypair, key, params, apdu.getBuffer(), swOffset, len);
- swOffset += 2;
- }
- if ((keyPair & KEYPAIR_REMOTE) != 0) {
- len += export(remoteKeypair, key, params, apdu.getBuffer(), swOffset, len);
- }
-
- return len;
- }
-
- /**
- * Performs ECDH, between the pubkey specified in P1(local/remote) and the privkey specified in P2(local/remote).
- * returns deriveSecret SW, {@code if(export == EXPORT_TRUE)} => short secretlen, byte[] secret
- *
- * @param apdu P1 = byte pubkey (KEYPAIR_*)
- * P2 = byte privkey (KEYPAIR_*)
- * DATA = byte export (EXPORT_TRUE || EXPORT_FALSE)
- * short transformation (EC_Consts.TRANSFORMATION_* | ...)
- * byte type (EC_Consts.KA_* | ...)
- * @return length of response
- */
- private short insECDH(APDU apdu) {
- byte pubkey = apduArray[ISO7816.OFFSET_P1];
- byte privkey = apduArray[ISO7816.OFFSET_P2];
- byte export = apduArray[cdata];
- short transformation = Util.getShort(apduArray, (short) (cdata + 1));
- byte type = apduArray[(short) (cdata + 3)];
-
- return ecdh(pubkey, privkey, export, transformation, type, apdu.getBuffer(), (short) 0);
- }
-
- /**
- * Performs ECDH, directly between the privkey specified in P1(local/remote) and the raw data
- *
- * @param apdu P1 = byte privkey (KEYPAIR_*)
- * P2 = byte export (EXPORT_TRUE || EXPORT_FALSE)
- * DATA = short transformation (EC_Consts.TRANSFORMATION_* | ...)
- * byte type (EC_Consts.KA_* | ...)
- * short length
- * byte[] pubkey
- * @return length of response
- */
- private short insECDH_direct(APDU apdu) {
- byte privkey = apduArray[ISO7816.OFFSET_P1];
- byte export = apduArray[ISO7816.OFFSET_P2];
- short transformation = Util.getShort(apduArray, cdata);
- byte type = apduArray[(short) (cdata + 2)];
- short length = Util.getShort(apduArray, (short) (cdata + 3));
-
- return ecdh_direct(privkey, export, transformation, type, (short) (cdata + 5), length, apdu.getBuffer(), (short) 0);
- }
-
- /**
- * Performs ECDSA signature and verification on data provided or random, using the keyPair in P1(local/remote).
- * returns ecdsa SW, {@code if(export == EXPORT_TRUE)} => short signature_length, byte[] signature
- *
- * @param apdu P1 = byte keyPair (KEYPAIR_*)
- * P2 = byte export (EXPORT_TRUE || EXPORT_FALSE)
- * DATA = byte sigType
- * short dataLength (00 = random data generated, !00 = data length)
- * byte[] data
- * @return length of response
- */
- private short insECDSA(APDU apdu) {
- byte keyPair = apduArray[ISO7816.OFFSET_P1];
- byte export = apduArray[ISO7816.OFFSET_P2];
- byte sigType = apduArray[cdata];
-
- short len = 0;
- if ((keyPair & KEYPAIR_LOCAL) != 0) {
- len += ecdsa(localKeypair, sigType, export, apduArray, (short) (cdata + 1), apdu.getBuffer(), (short) 0);
- }
- if ((keyPair & KEYPAIR_REMOTE) != 0) {
- len += ecdsa(remoteKeypair, sigType, export, apduArray, (short) (cdata + 1), apdu.getBuffer(), len);
- }
-
- return len;
- }
-
- /**
- * @param apdu P1 = byte keyPair (KEYPAIR_*)
- * P2 = byte export (EXPORT_TRUE || EXPORT_FALSE)
- * DATA = byte sigType
- * short dataLength (00 = random data generated, !00 = data length)
- * byte[] data
- * @return length of response
- */
- private short insECDSA_sign(APDU apdu) {
- byte keyPair = apduArray[ISO7816.OFFSET_P1];
- byte export = apduArray[ISO7816.OFFSET_P2];
- byte sigType = apduArray[cdata];
-
- short len = 0;
- if ((keyPair & KEYPAIR_LOCAL) != 0) {
- len += ecdsa_sign(localKeypair, sigType, export, apduArray, (short) (cdata + 1), apdu.getBuffer(), (short) 0);
- }
- if ((keyPair & KEYPAIR_REMOTE) != 0) {
- len += ecdsa_sign(remoteKeypair, sigType, export, apduArray, (short) (cdata + 1), apdu.getBuffer(), len);
- }
- return len;
- }
-
- /**
- * @param apdu P1 = byte keyPair (KEYPAIR_*)
- * P2 = byte sigType
- * DATA = short dataLength (00 = random data generated, !00 = data length)
- * byte[] data
- * short sigLength
- * byte[] signature
- * @return length of response
- */
- private short insECDSA_verify(APDU apdu) {
- byte keyPair = apduArray[ISO7816.OFFSET_P1];
- byte sigType = apduArray[ISO7816.OFFSET_P2];
-
- short len = 0;
- if ((keyPair & KEYPAIR_LOCAL) != 0) {
- len += ecdsa_verify(localKeypair, sigType, apduArray, cdata, apdu.getBuffer(), (short) 0);
- }
- if ((keyPair & KEYPAIR_REMOTE) != 0) {
- len += ecdsa_verify(remoteKeypair, sigType, apduArray, cdata, apdu.getBuffer(), len);
- }
- return len;
- }
-
-
- /**
- * Performs card memory cleanup via JCSystem.requestObjectDeletion()
- *
- * @param apdu no data
- * @return length of response
- */
- private short insCleanup(APDU apdu) {
- byte[] apdubuf = apdu.getBuffer();
-
- return cleanup(apdubuf, (short) 0);
- }
-
- /**
- * Gathers info about the applet and the card environment.
- *
- * @param apdu no data
- * @return length of response
- */
- private short insGetInfo(APDU apdu) {
- byte[] apdubuf = apdu.getBuffer();
-
- return getInfo(apdubuf, (short) 0);
- }
-
- /**
- * Set the dry run mode of the applet.
- *
- * @param apdu P1 = byte mode (MODE_* || ...)
- * @return length of response
- */
- private short insSetDryRunMode(APDU apdu) {
- byte[] apdubuf = apdu.getBuffer();
- byte mode = apduArray[ISO7816.OFFSET_P1];
-
- short len = 0;
- if (mode == MODE_NORMAL) {
- len = setDryRunMode(apdubuf, false, (short) 0);
- }
- if (mode == MODE_DRY_RUN) {
- len = setDryRunMode(apdubuf, true, (short) 0);
- }
- return len;
- }
-
- /**
- * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...)
- * @param build whether to use KeyBuilder or Keypair alloc
- * @param keyLength key length to set
- * @param keyClass key class to allocate
- * @param outBuffer buffer to write sw to
- * @param outOffset offset into buffer
- * @return length of data written to the buffer
- */
- private short allocate(byte keyPair, byte build, short keyLength, byte keyClass, byte[] outBuffer, short outOffset) {
- short length = 0;
- if ((keyPair & KEYPAIR_LOCAL) != 0) {
- if ((build & BUILD_KEYPAIR) != 0) {
- localKeypair = keyGenerator.allocatePair(keyClass, keyLength);
- if (keyGenerator.getSW() != ISO7816.SW_NO_ERROR && (build & BUILD_KEYBUILDER) != 0) {
- localKeypair = keyGenerator.constructPair(keyClass, keyLength);
- }
- } else if ((build & BUILD_KEYBUILDER) != 0) {
- localKeypair = keyGenerator.constructPair(keyClass, keyLength);
- }
- Util.setShort(outBuffer, outOffset, keyGenerator.getSW());
- length += 2;
- }
-
- if ((keyPair & KEYPAIR_REMOTE) != 0) {
- if ((build & BUILD_KEYPAIR) != 0) {
- remoteKeypair = keyGenerator.allocatePair(keyClass, keyLength);
- if (keyGenerator.getSW() != ISO7816.SW_NO_ERROR && (build & BUILD_KEYBUILDER) != 0) {
- remoteKeypair = keyGenerator.constructPair(keyClass, keyLength);
- }
- } else if ((build & BUILD_KEYBUILDER) != 0) {
- remoteKeypair = keyGenerator.constructPair(keyClass, keyLength);
- }
- Util.setShort(outBuffer, (short) (outOffset + length), keyGenerator.getSW());
- length += 2;
- }
-
- return length;
- }
-
- /**
- * @param keyPair KeyPair to clear
- * @param outBuffer buffer to write sw to
- * @param outOffset offset into buffer
- * @return length of data written to the buffer
- */
- private short clear(KeyPair keyPair, byte[] outBuffer, short outOffset) {
- short sw = keyGenerator.clearPair(keyPair, EC_Consts.KEY_BOTH);
- Util.setShort(outBuffer, outOffset, sw);
-
- return 2;
- }
-
- /**
- * @param keyPair KeyPair to set params on
- * @param curve curve to set (EC_Consts.CURVE_*)
- * @param params parameters to set (EC_Consts.PARAMETER_* | ...)
- * @param inBuffer buffer to read params from
- * @param inOffset input offset in buffer
- * @param outBuffer buffer to write sw to
- * @param outOffset output offset in buffer
- * @return length of data written to the buffer
- */
- private short set(KeyPair keyPair, byte curve, short params, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) {
- short sw = ISO7816.SW_NO_ERROR;
-
- switch (curve) {
- case EC_Consts.CURVE_default:
- //default, dont set anything
- break;
- case EC_Consts.CURVE_external:
- //external
- sw = keyGenerator.setExternalCurve(keyPair, params, inBuffer, inOffset);
- break;
- default:
- //custom
- sw = keyGenerator.setCurve(keyPair, curve, params, ramArray, (short) 0);
- break;
- }
-
- Util.setShort(outBuffer, outOffset, sw);
- return 2;
- }
-
- /**
- * @param keyPair KeyPair to transform
- * @param key key to transform (EC_Consts.KEY_* | ...)
- * @param params parameters to transform (EC_Consts.PARAMETER_* | ...)
- * @param transformation transformation type (EC_Consts.TRANSFORMATION_*)
- * @param outBuffer buffer to output sw to
- * @param outOffset output offset in buffer
- * @return length of data written to the buffer
- */
- private short transform(KeyPair keyPair, byte key, short params, short transformation, byte[] outBuffer, short outOffset) {
- short sw = keyGenerator.transformCurve(keyPair, key, params, transformation, ramArray, (short) 0);
- Util.setShort(outBuffer, outOffset, sw);
- return 2;
- }
-
- /**
- * @param keyPair KeyPair to generate
- * @param outBuffer buffer to output sw to
- * @param outOffset output offset in buffer
- * @return length of data written to the buffer
- */
- private short generate(KeyPair keyPair, byte[] outBuffer, short outOffset) {
- short sw = keyGenerator.generatePair(keyPair);
- Util.setShort(outBuffer, outOffset, sw);
-
- return 2;
- }
-
- /**
- * @param keyPair KeyPair to export from
- * @param key which key to export from (EC_Consts.KEY_PUBLIC | EC_Consts.KEY_PRIVATE)
- * @param params which params to export (EC_Consts.PARAMETER_* | ...)
- * @param outBuffer buffer to export params to
- * @param swOffset offset to output sw to buffer
- * @param outOffset output offset in buffer
- * @return length of data written to the buffer
- */
- private short export(KeyPair keyPair, byte key, short params, byte[] outBuffer, short swOffset, short outOffset) {
- short length = 0;
-
- short sw = ISO7816.SW_NO_ERROR;
- if ((key & EC_Consts.KEY_PUBLIC) != 0) {
- //export params from public
- length += keyGenerator.exportParameters(keyPair, EC_Consts.KEY_PUBLIC, params, outBuffer, outOffset);
- sw = keyGenerator.getSW();
- }
- if ((key & EC_Consts.KEY_PRIVATE) != 0 && sw == ISO7816.SW_NO_ERROR) {
- //export params from private
- length += keyGenerator.exportParameters(keyPair, EC_Consts.KEY_PRIVATE, params, outBuffer, (short) (outOffset + length));
- sw = keyGenerator.getSW();
- }
- Util.setShort(outBuffer, swOffset, sw);
-
- return length;
- }
-
- /**
- * @param pubkey keyPair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE)
- * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE)
- * @param export whether to export ECDH secret
- * @param transformation whether to transform the pubkey before ECDH
- * @param type KeyAgreement type to test
- * @param outBuffer buffer to write sw to, and export ECDH secret {@code if(export == EXPORT_TRUE)}
- * @param outOffset output offset in buffer
- * @return length of data written to the buffer
- */
- private short ecdh(byte pubkey, byte privkey, byte export, short transformation, byte type, byte[] outBuffer, short outOffset) {
- short length = 0;
-
- KeyPair pub = ((pubkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair;
- KeyPair priv = ((privkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair;
-
- short secretLength = 0;
- if (keyTester.getKaType() == type) {
- secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, transformation);
- } else {
- short allocateSW = keyTester.allocateKA(type);
- if (allocateSW == ISO7816.SW_NO_ERROR) {
- secretLength = keyTester.testKA(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, transformation);
- }
- }
- Util.setShort(outBuffer, outOffset, keyTester.getSW());
- length += 2;
-
- if ((export == EXPORT_TRUE)) {
- Util.setShort(outBuffer, (short) (outOffset + length), secretLength);
- length += 2;
- Util.arrayCopyNonAtomic(ramArray2, (short) 0, outBuffer, (short) (outOffset + length), secretLength);
- length += secretLength;
- }
-
- return length;
- }
-
- private short ecdh_direct(byte privkey, byte export, short transformation, byte type, short keyOffset, short keyLength, byte[] outBuffer, short outOffset) {
- short length = 0;
-
- KeyPair priv = ((privkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair;
-
- short secretLength = 0;
- if (keyTester.getKaType() == type) {
- secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, transformation);
- } else {
- short allocateSW = keyTester.allocateKA(type);
- if (allocateSW == ISO7816.SW_NO_ERROR) {
- secretLength = keyTester.testKA_direct(priv, apduArray, keyOffset, keyLength, ramArray2, (short) 0, transformation);
- }
- }
-
- Util.setShort(outBuffer, outOffset, keyTester.getSW());
- length += 2;
-
- if ((export == EXPORT_TRUE)) {
- Util.setShort(outBuffer, (short) (outOffset + length), secretLength);
- length += 2;
- Util.arrayCopyNonAtomic(ramArray2, (short) 0, outBuffer, (short) (outOffset + length), secretLength);
- length += secretLength;
- }
- return length;
- }
-
- /**
- * @param sign keyPair to use for signing and verification
- * @param sigType Signature type to use
- * @param export whether to export ECDSA signature
- * @param inBuffer buffer to read dataLength and data to sign from
- * @param inOffset input offset in buffer
- * @param outBuffer buffer to write sw to, and export ECDSA signature {@code if(export == EXPORT_TRUE)}
- * @param outOffset output offset in buffer
- * @return length of data written to the buffer
- */
- private short ecdsa(KeyPair sign, byte sigType, byte export, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) {
- short length = 0;
-
- short dataLength = Util.getShort(inBuffer, inOffset);
- if (dataLength == 0) { //no data to sign
- //generate random
- dataLength = 64;
- randomData.generateData(ramArray, (short) 0, dataLength);
- } else {
- Util.arrayCopyNonAtomic(inBuffer, (short) (inOffset + 2), ramArray, (short) 0, dataLength);
- }
-
- short signatureLength = 0;
- if (keyTester.getSigType() == sigType) {
- signatureLength = keyTester.testECDSA((ECPrivateKey) sign.getPrivate(), (ECPublicKey) sign.getPublic(), ramArray, (short) 0, dataLength, ramArray2, (short) 0);
- } else {
- short allocateSW = keyTester.allocateSig(sigType);
- if (allocateSW == ISO7816.SW_NO_ERROR) {
- signatureLength = keyTester.testECDSA((ECPrivateKey) sign.getPrivate(), (ECPublicKey) sign.getPublic(), ramArray, (short) 0, dataLength, ramArray2, (short) 0);
- }
- }
- Util.setShort(outBuffer, outOffset, keyTester.getSW());
- length += 2;
-
- if (export == EXPORT_TRUE) {
- Util.setShort(outBuffer, (short) (outOffset + length), signatureLength);
- length += 2;
-
- Util.arrayCopyNonAtomic(ramArray2, (short) 0, outBuffer, (short) (outOffset + length), signatureLength);
- length += signatureLength;
- }
-
- return length;
- }
-
- private short ecdsa_sign(KeyPair sign, byte sigType, byte export, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) {
- short length = 0;
-
- short dataLength = Util.getShort(inBuffer, inOffset);
- if (dataLength == 0) { //no data to sign
- //generate random
- dataLength = 64;
- randomData.generateData(ramArray, (short) 0, dataLength);
- } else {
- Util.arrayCopyNonAtomic(inBuffer, (short) (inOffset + 2), ramArray, (short) 0, dataLength);
- }
-
- short signatureLength = 0;
- if (keyTester.getSigType() == sigType) {
- signatureLength = keyTester.testECDSA_sign((ECPrivateKey) sign.getPrivate(), ramArray, (short) 0, dataLength, ramArray2, (short) 0);
- } else {
- short allocateSW = keyTester.allocateSig(sigType);
- if (allocateSW == ISO7816.SW_NO_ERROR) {
- signatureLength = keyTester.testECDSA_sign((ECPrivateKey) sign.getPrivate(), ramArray, (short) 0, dataLength, ramArray2, (short) 0);
- }
- }
- Util.setShort(outBuffer, outOffset, keyTester.getSW());
- length += 2;
-
- if (export == EXPORT_TRUE) {
- Util.setShort(outBuffer, (short) (outOffset + length), signatureLength);
- length += 2;
-
- Util.arrayCopyNonAtomic(ramArray2, (short) 0, outBuffer, (short) (outOffset + length), signatureLength);
- length += signatureLength;
- }
-
- return length;
- }
-
- private short ecdsa_verify(KeyPair verify, byte sigType, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) {
- short length = 0;
-
- short dataLength = Util.getShort(inBuffer, inOffset);
- short dataOffset = (short) (inOffset + 2);
- short sigLength = Util.getShort(inBuffer, (short) (dataOffset + dataLength));
- short sigOffset = (short) (dataOffset + dataLength + 2);
-
- if (keyTester.getSigType() == sigType) {
- keyTester.testECDSA_verify((ECPublicKey) verify.getPublic(), inBuffer, dataOffset, dataLength, inBuffer, sigOffset, sigLength);
- } else {
- short allocateSW = keyTester.allocateSig(sigType);
- if (allocateSW == ISO7816.SW_NO_ERROR) {
- keyTester.testECDSA_verify((ECPublicKey) verify.getPublic(), inBuffer, dataOffset, dataLength, inBuffer, sigOffset, sigLength);
- }
- }
- Util.setShort(outBuffer, outOffset, keyTester.getSW());
- length += 2;
-
- return length;
- }
-
- /**
- * @param buffer buffer to write sw to
- * @param offset output offset in buffer
- * @return length of data written to the buffer
- */
- private short cleanup(byte[] buffer, short offset) {
- short sw = ISO7816.SW_NO_ERROR;
- try {
- if (JCSystem.isObjectDeletionSupported())
- JCSystem.requestObjectDeletion();
- } catch (CardRuntimeException crex) {
- sw = crex.getReason();
- }
-
- Util.setShort(buffer, offset, sw);
- return 2;
- }
-
- /**
- * @param buffer buffer to write sw to
- * @param offset output offset in buffer
- * @return length of data written to the buffer
- */
- private short getInfo(byte[] buffer, short offset) {
- short length = 0;
- Util.setShort(buffer, (short) (offset + length), ISO7816.SW_NO_ERROR);
- length += 2;
- Util.setShort(buffer, (short) (offset + length), (short) VERSION.length);
- length += 2;
- Util.arrayCopyNonAtomic(VERSION, (short) 0, buffer, (short) (offset + length), (short) (VERSION.length));
- length += VERSION.length;
- Util.setShort(buffer, (short) (offset + length), getBase());
- length += 2;
- Util.setShort(buffer, (short) (offset + length), JCSystem.getVersion());
- length += 2;
- Util.setShort(buffer, (short) (offset + length), (short) (JCSystem.isObjectDeletionSupported() ? 1 : 0));
- length += 2;
- Util.setShort(buffer, (short) (offset + length), (short) buffer.length);
- length += 2;
- Util.setShort(buffer, (short) (offset + length), (short) ramArray.length);
- length += 2;
- Util.setShort(buffer, (short) (offset + length), (short) ramArray2.length);
- length += 2;
- Util.setShort(buffer, (short) (offset + length), (short) apduArray.length);
- length += 2;
- return length;
- }
-
- private short setDryRunMode(byte[] buffer, boolean mode, short offset) {
- if (keyTester != null) {
- keyTester.setDryRun(mode);
- }
- if (keyGenerator != null) {
- keyGenerator.setDryRun(mode);
- }
- Util.setShort(buffer, offset, ISO7816.SW_NO_ERROR);
- return 2;
- }
-}