diff options
| -rw-r--r-- | !uploader/ectester.cap | bin | 14675 -> 14877 bytes | |||
| -rw-r--r-- | dist/ECTester.jar | bin | 705430 -> 709688 bytes | |||
| -rw-r--r-- | jcbuild.xml | 2 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/AppletUtil.java | 57 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECKeyGenerator.java | 45 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECKeyTester.java | 11 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECTesterApplet.java | 288 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECUtil.java | 35 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/EC_Consts.java | 4 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/data/nist/p521.csv | 2 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/Command.java | 3 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/ECTester.java | 8 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/Response.java | 2 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/Test.java | 4 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/TestSuite.java | 26 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/Util.java | 215 |
16 files changed, 390 insertions, 312 deletions
diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap Binary files differindex 0d50b57..e5d5183 100644 --- a/!uploader/ectester.cap +++ b/!uploader/ectester.cap diff --git a/dist/ECTester.jar b/dist/ECTester.jar Binary files differindex 8119521..691d575 100644 --- a/dist/ECTester.jar +++ b/dist/ECTester.jar diff --git a/jcbuild.xml b/jcbuild.xml index 9b1dabb..a4d7619 100644 --- a/jcbuild.xml +++ b/jcbuild.xml @@ -12,7 +12,7 @@ <taskdef name="javacard" classname="pro.javacard.ant.JavaCard" classpath="ext/ant-javacard.jar"/> <target name="build" description="Builds the CAP file."> - <javacard jckit="${JC221}"> + <javacard jckit="${JC222}"> <cap output="!uploader/ectester.cap" sources="src/cz/crcs/ectester/applet" aid="4543546573746572" > <applet class="cz.crcs.ectester.applet.ECTesterApplet" aid="45435465737465723031"/> </cap> diff --git a/src/cz/crcs/ectester/applet/AppletUtil.java b/src/cz/crcs/ectester/applet/AppletUtil.java new file mode 100644 index 0000000..296541d --- /dev/null +++ b/src/cz/crcs/ectester/applet/AppletUtil.java @@ -0,0 +1,57 @@ +package cz.crcs.ectester.applet; + +import javacard.framework.APDU; +import javacard.framework.ISO7816; +import javacard.framework.ISOException; +import javacard.framework.Util; +import javacard.security.KeyAgreement; +import javacard.security.KeyPair; +import javacard.security.Signature; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class AppletUtil { + + private static short nullCheck(Object obj, short sw) { + if (obj == null) + ISOException.throwIt(sw); + return ISO7816.SW_NO_ERROR; + } + + public static short objCheck(Object obj) { + return nullCheck(obj, ECTesterApplet.SW_OBJECT_NULL); + } + + public static short keypairCheck(KeyPair keyPair) { + return nullCheck(keyPair, ECTesterApplet.SW_KEYPAIR_NULL); + } + + public static short kaCheck(KeyAgreement keyAgreement) { + return nullCheck(keyAgreement, ECTesterApplet.SW_KA_NULL); + } + + public static short signCheck(Signature signature) { + return nullCheck(signature, ECTesterApplet.SW_SIGNATURE_NULL); + } + + public static short readAPDU(APDU apdu, byte[] buffer, short length) { + short read = apdu.setIncomingAndReceive(); + read += apdu.getOffsetCdata(); + short total = apdu.getIncomingLength(); + if (total > length) { + return 0; + } + byte[] apduBuffer = apdu.getBuffer(); + + short sum = 0; + + do { + Util.arrayCopyNonAtomic(apduBuffer, (short) 0, buffer, sum, read); + sum += read; + read = apdu.receiveBytes((short) 0); + } while (sum < total); + // TODO figure this out, in buffer + out buffer(apdubuf) or just send each param on its own? + return 0; + } +} diff --git a/src/cz/crcs/ectester/applet/ECKeyGenerator.java b/src/cz/crcs/ectester/applet/ECKeyGenerator.java index f8cbf87..0c20333 100644 --- a/src/cz/crcs/ectester/applet/ECKeyGenerator.java +++ b/src/cz/crcs/ectester/applet/ECKeyGenerator.java @@ -38,9 +38,15 @@ public class ECKeyGenerator { return ecKeyPair; } + /** + * + * @param keypair + * @param key + * @return + */ public short clearPair(KeyPair keypair, byte key) { try { - sw = ECUtil.keypairCheck(keypair); + sw = AppletUtil.keypairCheck(keypair); if ((key & EC_Consts.KEY_PUBLIC) != 0) keypair.getPublic().clearKey(); if ((key & EC_Consts.KEY_PRIVATE) != 0) keypair.getPrivate().clearKey(); } catch (CardRuntimeException ce) { @@ -55,7 +61,7 @@ public class ECKeyGenerator { */ public short generatePair(KeyPair keypair) { try { - sw = ECUtil.keypairCheck(keypair); + sw = AppletUtil.keypairCheck(keypair); keypair.genKeyPair(); } catch (CardRuntimeException ce) { sw = ce.getReason(); @@ -63,14 +69,41 @@ public class ECKeyGenerator { return sw; } + /** + * + * @param keypair + * @param curve + * @param buffer + * @param offset + * @return + */ public short setCurve(KeyPair keypair, byte curve, byte[] buffer, short offset) { return setCurve(keypair, curve, EC_Consts.PARAMETERS_ALL, buffer, offset); } + /** + * + * @param keypair + * @param curve + * @param params + * @param buffer + * @param offset + * @return + */ public short setCurve(KeyPair keypair, byte curve, short params, byte[] buffer, short offset) { return setCurve(keypair, EC_Consts.KEY_BOTH, curve, params, buffer, offset); } + /** + * + * @param keypair + * @param key + * @param curve + * @param params + * @param buffer + * @param offset + * @return + */ public short setCurve(KeyPair keypair, byte key, byte curve, short params, byte[] buffer, short offset) { byte alg = EC_Consts.getCurveType(curve); sw = ISO7816.SW_NO_ERROR; @@ -156,7 +189,7 @@ public class ECKeyGenerator { */ public short setParameter(KeyPair keypair, byte key, short param, byte[] data, short offset, short length) { try { - sw = ECUtil.keypairCheck(keypair); + sw = AppletUtil.keypairCheck(keypair); ECPublicKey ecPublicKey = (ECPublicKey) keypair.getPublic(); ECPrivateKey ecPrivateKey = (ECPrivateKey) keypair.getPrivate(); @@ -281,7 +314,7 @@ public class ECKeyGenerator { public short exportParameter(KeyPair keypair, byte key, short param, byte[] outputBuffer, short outputOffset) { short length = 0; try { - sw = ECUtil.keypairCheck(keypair); + sw = AppletUtil.keypairCheck(keypair); ECPublicKey ecPublicKey = (ECPublicKey) keypair.getPublic(); ECPrivateKey ecPrivateKey = (ECPrivateKey) keypair.getPrivate(); @@ -390,8 +423,8 @@ public class ECKeyGenerator { */ public short copyCurve(KeyPair from, KeyPair to, short params, byte[] buffer, short offset) { try { - sw = ECUtil.keypairCheck(from); - sw = ECUtil.keypairCheck(to); + sw = AppletUtil.keypairCheck(from); + sw = AppletUtil.keypairCheck(to); short param = EC_Consts.PARAMETER_FP; while (param <= EC_Consts.PARAMETER_K) { diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index 1d113ae..7664c72 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -3,7 +3,6 @@ package cz.crcs.ectester.applet; import javacard.framework.CardRuntimeException; import javacard.framework.ISO7816; -import javacard.framework.Util; import javacard.security.*; /** @@ -53,9 +52,9 @@ public class ECKeyTester { private short testKA(KeyAgreement ka, KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, short corruption) { short length = 0; try { - sw = ECUtil.kaCheck(ka); - sw = ECUtil.keypairCheck(privatePair); - sw = ECUtil.keypairCheck(publicPair); + sw = AppletUtil.kaCheck(ka); + sw = AppletUtil.keypairCheck(privatePair); + sw = AppletUtil.keypairCheck(publicPair); ka.init(privatePair.getPrivate()); short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset); @@ -123,7 +122,7 @@ public class ECKeyTester { if (sw != ISO7816.SW_NO_ERROR) { return length; } - if (Util.arrayCompare(outputBuffer, outputOffset, outputBuffer, (short) (outputOffset + ecdhLength), ecdhLength) != 0) { + if (javacard.framework.Util.arrayCompare(outputBuffer, outputOffset, outputBuffer, (short) (outputOffset + ecdhLength), ecdhLength) != 0) { sw = ECTesterApplet.SW_DH_DHC_MISMATCH; } return length; @@ -164,7 +163,7 @@ public class ECKeyTester { public short testECDSA(ECPrivateKey signKey, ECPublicKey verifyKey, byte[] inputBuffer, short inputOffset, short inputLength, byte[] sigBuffer, short sigOffset) { short length = 0; try { - sw = ECUtil.signCheck(ecdsaSignature); + sw = AppletUtil.signCheck(ecdsaSignature); ecdsaSignature.init(signKey, Signature.MODE_SIGN); length = ecdsaSignature.sign(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset); diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index 4e586ec..f957273 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -30,6 +30,7 @@ import javacard.security.ECPrivateKey; import javacard.security.ECPublicKey; import javacard.security.KeyPair; import javacard.security.RandomData; +import javacardx.apdu.ExtendedLength; /** * Applet part of ECTester, a tool for testing Elliptic curve support on javacards. @@ -37,7 +38,7 @@ import javacard.security.RandomData; * @author Petr Svenda petr@svenda.com * @author Jan Jancar johny@neuromancer.sk */ -public class ECTesterApplet extends Applet { +public class ECTesterApplet extends Applet implements ExtendedLength { // MAIN INSTRUCTION CLASS public static final byte CLA_ECTESTERAPPLET = (byte) 0xB0; @@ -71,9 +72,11 @@ public class ECTesterApplet extends Applet { private static final short ARRAY_LENGTH = (short) 0xff; + private static final short APDU_MAX_LENGTH = (short) 1024; // TEMPORARRY ARRAY IN RAM private byte[] ramArray = null; private byte[] ramArray2 = null; + private byte[] apduArray = null; // PERSISTENT ARRAY IN EEPROM private byte[] dataArray = null; // unused @@ -102,6 +105,7 @@ public class ECTesterApplet extends Applet { ramArray = JCSystem.makeTransientByteArray(ARRAY_LENGTH, JCSystem.CLEAR_ON_RESET); ramArray2 = JCSystem.makeTransientByteArray(ARRAY_LENGTH, JCSystem.CLEAR_ON_RESET); + apduArray = JCSystem.makeTransientByteArray(APDU_MAX_LENGTH, JCSystem.CLEAR_ON_RESET); dataArray = new byte[ARRAY_LENGTH]; Util.arrayFillNonAtomic(dataArray, (short) 0, ARRAY_LENGTH, (byte) 0); @@ -126,49 +130,56 @@ public class ECTesterApplet extends Applet { 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 dispached to the process if (selectingApplet()) { return; } - if (apduBuffer[ISO7816.OFFSET_CLA] == CLA_ECTESTERAPPLET) { - switch (apduBuffer[ISO7816.OFFSET_INS]) { + if (cla == CLA_ECTESTERAPPLET) { + AppletUtil.readAPDU(apdu, apduArray, APDU_MAX_LENGTH); + + short length = 0; + switch (ins) { case INS_ALLOCATE: - insAllocate(apdu); + length = insAllocate(apdu); break; case INS_CLEAR: - insClear(apdu); + length = insClear(apdu); break; case INS_SET: - insSet(apdu); + length = insSet(apdu); break; case INS_CORRUPT: - insCorrupt(apdu); + length = insCorrupt(apdu); break; case INS_GENERATE: - insGenerate(apdu); + length = insGenerate(apdu); break; case INS_EXPORT: - insExport(apdu); + length = insExport(apdu); break; case INS_ECDH: - insECDH(apdu); + length = insECDH(apdu); break; case INS_ECDSA: - insECDSA(apdu); + length = insECDSA(apdu); break; case INS_CLEANUP: - insCleanup(apdu); + length = insCleanup(apdu); break; case INS_SUPPORT: - insSupport(apdu); + length = insSupport(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); } else ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); } @@ -180,18 +191,15 @@ public class ECTesterApplet extends Applet { * P2 = * DATA = short keyLength * byte keyClass + * @return length of response */ - private void insAllocate(APDU apdu) { - apdu.setIncomingAndReceive(); - byte[] apdubuf = apdu.getBuffer(); - - byte keyPair = apdubuf[ISO7816.OFFSET_P1]; - short keyLength = Util.getShort(apdubuf, ISO7816.OFFSET_CDATA); - byte keyClass = apdubuf[ISO7816.OFFSET_CDATA + 2]; + private short insAllocate(APDU apdu) { + byte keyPair = apduArray[ISO7816.OFFSET_P1]; + short cdata = apdu.getOffsetCdata(); + short keyLength = Util.getShort(apduArray, cdata); + byte keyClass = apduArray[(short) (cdata + 2)]; - short len = allocate(keyPair, keyLength, keyClass, apdubuf, (short) 0); - - apdu.setOutgoingAndSend((short) 0, len); + return allocate(keyPair, keyLength, keyClass, apdu.getBuffer(), (short) 0); } /** @@ -200,21 +208,20 @@ public class ECTesterApplet extends Applet { * * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) * P2 = + * @return length of response */ - private void insClear(APDU apdu) { - apdu.setIncomingAndReceive(); - byte[] apdubuf = apdu.getBuffer(); - byte keyPair = apdubuf[ISO7816.OFFSET_P1]; + private short insClear(APDU apdu) { + byte keyPair = apduArray[ISO7816.OFFSET_P1]; short len = 0; if ((keyPair & KEYPAIR_LOCAL) != 0) { - len += clear(localKeypair, apdubuf, (short) 0); + len += clear(localKeypair, apdu.getBuffer(), (short) 0); } if ((keyPair & KEYPAIR_REMOTE) != 0) { - len += clear(remoteKeypair, apdubuf, len); + len += clear(remoteKeypair, apdu.getBuffer(), len); } - apdu.setOutgoingAndSend((short) 0, len); + return len; } /** @@ -229,25 +236,24 @@ public class ECTesterApplet extends Applet { * [short paramLength, byte[] param], * for all params in params, * in order: field,a,b,g,r,k,w,s + * @return length of response */ - private void insSet(APDU apdu) { - apdu.setIncomingAndReceive(); - byte[] apdubuf = apdu.getBuffer(); - - byte keyPair = apdubuf[ISO7816.OFFSET_P1]; - byte curve = apdubuf[ISO7816.OFFSET_P2]; - short params = Util.getShort(apdubuf, ISO7816.OFFSET_CDATA); + private short insSet(APDU apdu) { + byte keyPair = apduArray[ISO7816.OFFSET_P1]; + byte curve = apduArray[ISO7816.OFFSET_P2]; + short cdata = apdu.getOffsetCdata(); + short params = Util.getShort(apduArray, cdata); short len = 0; if ((keyPair & KEYPAIR_LOCAL) != 0) { - len += set(localKeypair, curve, params, apdubuf, (short) (ISO7816.OFFSET_CDATA + 2), (short) 0); + len += set(localKeypair, curve, params, apduArray, (short) (cdata + 2), apdu.getBuffer(), (short) 0); } if ((keyPair & KEYPAIR_REMOTE) != 0) { - len += set(remoteKeypair, curve, params, apdubuf, (short) (ISO7816.OFFSET_CDATA + 2), len); + len += set(remoteKeypair, curve, params, apduArray, (short) (cdata + 2), apdu.getBuffer(), len); } - apdu.setOutgoingAndSend((short) 0, len); + return len; } /** @@ -258,26 +264,25 @@ public class ECTesterApplet extends Applet { * P2 = byte key (EC_Consts.KEY_* | ...) * DATA = short params (EC_Consts.PARAMETER_* | ...) * byte corruption (EC_Consts.CORRUPTION_* || ...) + * @return length of response */ - private void insCorrupt(APDU apdu) { - apdu.setIncomingAndReceive(); - byte[] apdubuf = apdu.getBuffer(); - - byte keyPair = apdubuf[ISO7816.OFFSET_P1]; - byte key = apdubuf[ISO7816.OFFSET_P2]; - short params = Util.getShort(apdubuf, ISO7816.OFFSET_CDATA); - byte corruption = apdubuf[(short) (ISO7816.OFFSET_CDATA + 2)]; + private short insCorrupt(APDU apdu) { + byte keyPair = apduArray[ISO7816.OFFSET_P1]; + byte key = apduArray[ISO7816.OFFSET_P2]; + short cdata = apdu.getOffsetCdata(); + short params = Util.getShort(apduArray, cdata); + byte corruption = apduArray[(short) (cdata + 2)]; short len = 0; if ((keyPair & KEYPAIR_LOCAL) != 0) { - len += corrupt(localKeypair, key, params, corruption, apdubuf, (short) 0); + len += corrupt(localKeypair, key, params, corruption, apdu.getBuffer(), (short) 0); } if ((keyPair & KEYPAIR_REMOTE) != 0) { - len += corrupt(remoteKeypair, key, params, corruption, apdubuf, len); + len += corrupt(remoteKeypair, key, params, corruption, apdu.getBuffer(), len); } - apdu.setOutgoingAndSend((short) 0, len); + return len; } /** @@ -286,22 +291,20 @@ public class ECTesterApplet extends Applet { * * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) * P2 = + * @return length of response */ - private void insGenerate(APDU apdu) { - apdu.setIncomingAndReceive(); - byte[] apdubuf = apdu.getBuffer(); - - byte keyPair = apdubuf[ISO7816.OFFSET_P1]; + private short insGenerate(APDU apdu) { + byte keyPair = apduArray[ISO7816.OFFSET_P1]; short len = 0; if ((keyPair & KEYPAIR_LOCAL) != 0) { - len += generate(localKeypair, apdubuf, (short) 0); + len += generate(localKeypair, apdu.getBuffer(), (short) 0); } if ((keyPair & KEYPAIR_REMOTE) != 0) { - len += generate(remoteKeypair, apdubuf, len); + len += generate(remoteKeypair, apdu.getBuffer(), len); } - apdu.setOutgoingAndSend((short) 0, len); + return len; } /** @@ -310,27 +313,26 @@ public class ECTesterApplet extends Applet { * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) * P2 = byte key (EC_Consts.KEY_* | ...) * DATA = short params + * @return length of response */ - private void insExport(APDU apdu) { - apdu.setIncomingAndReceive(); - byte[] apdubuf = apdu.getBuffer(); - - byte keyPair = apdubuf[ISO7816.OFFSET_P1]; - byte key = apdubuf[ISO7816.OFFSET_P2]; - short params = Util.getShort(apdubuf, ISO7816.OFFSET_CDATA); + private short insExport(APDU apdu) { + byte keyPair = apduArray[ISO7816.OFFSET_P1]; + byte key = apduArray[ISO7816.OFFSET_P2]; + short cdata = apdu.getOffsetCdata(); + 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, apdubuf, swOffset, len); + len += export(localKeypair, key, params, apdu.getBuffer(), swOffset, len); swOffset += 2; } if ((keyPair & KEYPAIR_REMOTE) != 0) { - len += export(remoteKeypair, key, params, apdubuf, swOffset, len); + len += export(remoteKeypair, key, params, apdu.getBuffer(), swOffset, len); } - apdu.setOutgoingAndSend((short) 0, len); + return len; } /** @@ -342,20 +344,17 @@ public class ECTesterApplet extends Applet { * DATA = byte export (EXPORT_TRUE || EXPORT_FALSE) * short corruption (EC_Consts.CORRUPTION_* | ...) * byte type (EC_Consts.KA_* | ...) + * @return length of response */ - private void insECDH(APDU apdu) { - apdu.setIncomingAndReceive(); - byte[] apdubuf = apdu.getBuffer(); - - byte pubkey = apdubuf[ISO7816.OFFSET_P1]; - byte privkey = apdubuf[ISO7816.OFFSET_P2]; - byte export = apdubuf[ISO7816.OFFSET_CDATA]; - short corruption = Util.getShort(apdubuf, (short) (ISO7816.OFFSET_CDATA + 1)); - byte type = apdubuf[(short) (ISO7816.OFFSET_CDATA + 3)]; - - short len = ecdh(pubkey, privkey, export, corruption, type, apdubuf, (short) 0); + private short insECDH(APDU apdu) { + byte pubkey = apduArray[ISO7816.OFFSET_P1]; + byte privkey = apduArray[ISO7816.OFFSET_P2]; + short cdata = apdu.getOffsetCdata(); + byte export = apduArray[cdata]; + short corruption = Util.getShort(apduArray, (short) (cdata + 1)); + byte type = apduArray[(short) (cdata + 3)]; - apdu.setOutgoingAndSend((short) 0, len); + return ecdh(pubkey, privkey, export, corruption, type, apdu.getBuffer(), (short) 0); } /** @@ -366,37 +365,34 @@ public class ECTesterApplet extends Applet { * P2 = byte export (EXPORT_TRUE || EXPORT_FALSE) * DATA = short dataLength (00 = random data generated, !00 = data length) * byte[] data + * @return length of response */ - private void insECDSA(APDU apdu) { - apdu.setIncomingAndReceive(); - byte[] apdubuf = apdu.getBuffer(); - - byte keyPair = apdubuf[ISO7816.OFFSET_P1]; - byte export = apdubuf[ISO7816.OFFSET_P2]; + private short insECDSA(APDU apdu) { + byte keyPair = apduArray[ISO7816.OFFSET_P1]; + byte export = apduArray[ISO7816.OFFSET_P2]; + short cdata = apdu.getOffsetCdata(); short len = 0; if ((keyPair & KEYPAIR_LOCAL) != 0) { - len += ecdsa(localKeypair, export, apdubuf, ISO7816.OFFSET_CDATA, (short) 0); + len += ecdsa(localKeypair, export, apduArray, cdata, apdu.getBuffer(), (short) 0); } if ((keyPair & KEYPAIR_REMOTE) != 0) { - len += ecdsa(remoteKeypair, export, apdubuf, ISO7816.OFFSET_CDATA, len); + len += ecdsa(remoteKeypair, export, apduArray, cdata, apdu.getBuffer(), len); } - apdu.setOutgoingAndSend((short) 0, len); + return len; } /** * Performs card memory cleanup via JCSystem.requestObjectDeletion() * * @param apdu no data + * @return length of response */ - private void insCleanup(APDU apdu) { - apdu.setIncomingAndReceive(); + private short insCleanup(APDU apdu) { byte[] apdubuf = apdu.getBuffer(); - short len = cleanup(apdubuf, (short) 0); - - apdu.setOutgoingAndSend((short) 0, len); + return cleanup(apdubuf, (short) 0); } /** @@ -404,35 +400,33 @@ public class ECTesterApplet extends Applet { * install. * * @param apdu no data + * @return length of response */ - private void insSupport(APDU apdu) { - apdu.setIncomingAndReceive(); + private short insSupport(APDU apdu) { byte[] apdubuf = apdu.getBuffer(); - short len = support(apdubuf, (short) 0); - - apdu.setOutgoingAndSend((short) 0, len); + return support(apdubuf, (short) 0); } /** * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) * @param keyLength key length to set * @param keyClass key class to allocate - * @param buffer buffer to write sw to - * @param offset offset into buffer + * @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, short keyLength, byte keyClass, byte[] buffer, short offset) { + private short allocate(byte keyPair, short keyLength, byte keyClass, byte[] outBuffer, short outOffset) { short length = 0; if ((keyPair & KEYPAIR_LOCAL) != 0) { localKeypair = keyGenerator.allocatePair(keyClass, keyLength); - Util.setShort(buffer, offset, keyGenerator.getSW()); + Util.setShort(outBuffer, outOffset, keyGenerator.getSW()); length += 2; } if ((keyPair & KEYPAIR_REMOTE) != 0) { remoteKeypair = keyGenerator.allocatePair(keyClass, keyLength); - Util.setShort(buffer, (short) (offset + length), keyGenerator.getSW()); + Util.setShort(outBuffer, (short) (outOffset + length), keyGenerator.getSW()); length += 2; } @@ -440,14 +434,14 @@ public class ECTesterApplet extends Applet { } /** - * @param keyPair KeyPair to clear - * @param buffer buffer to write sw to - * @param offset offset into buffer + * @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[] buffer, short offset) { + private short clear(KeyPair keyPair, byte[] outBuffer, short outOffset) { short sw = keyGenerator.clearPair(keyPair, EC_Consts.KEY_BOTH); - Util.setShort(buffer, offset, sw); + Util.setShort(outBuffer, outOffset, sw); return 2; } @@ -456,12 +450,13 @@ public class ECTesterApplet extends Applet { * @param keyPair KeyPair to set params on * @param curve curve to set (EC_Consts.CURVE_*) * @param params parameters to set (EC_Consts.PARAMETER_* | ...) - * @param buffer buffer to read params from and write sw to + * @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[] buffer, short inOffset, short outOffset) { + 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) { @@ -470,7 +465,7 @@ public class ECTesterApplet extends Applet { break; case EC_Consts.CURVE_external: //external - sw = keyGenerator.setExternalCurve(keyPair, params, buffer, inOffset); + sw = keyGenerator.setExternalCurve(keyPair, params, inBuffer, inOffset); break; default: //custom @@ -478,7 +473,7 @@ public class ECTesterApplet extends Applet { break; } - Util.setShort(buffer, outOffset, sw); + Util.setShort(outBuffer, outOffset, sw); return 2; } @@ -487,54 +482,54 @@ public class ECTesterApplet extends Applet { * @param key key to corrupt (EC_Consts.KEY_* | ...) * @param params parameters to corrupt (EC_Consts.PARAMETER_* | ...) * @param corruption corruption type (EC_Consts.CORRUPTION_*) - * @param buffer buffer to output sw to - * @param offset output offset in buffer + * @param outBuffer buffer to output sw to + * @param outOffset output offset in buffer * @return length of data written to the buffer */ - private short corrupt(KeyPair keyPair, byte key, short params, byte corruption, byte[] buffer, short offset) { + private short corrupt(KeyPair keyPair, byte key, short params, byte corruption, byte[] outBuffer, short outOffset) { short sw = keyGenerator.corruptCurve(keyPair, key, params, corruption, ramArray, (short) 0); - Util.setShort(buffer, offset, sw); + Util.setShort(outBuffer, outOffset, sw); return 2; } /** - * @param keyPair KeyPair to generate - * @param buffer buffer to write sw to - * @param offset output offset in buffer + * @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[] buffer, short offset) { + private short generate(KeyPair keyPair, byte[] outBuffer, short outOffset) { short sw = keyGenerator.generatePair(keyPair); - Util.setShort(buffer, offset, sw); + 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 buffer buffer to export params to - * @param swOffset offset to output sw to buffer - * @param offset output offset in buffer + * @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[] buffer, short swOffset, short offset) { + 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, buffer, offset); + length += keyGenerator.exportParameters(keyPair, EC_Consts.KEY_PUBLIC, params, outBuffer, outOffset); sw = keyGenerator.getSW(); } //TODO unify this, now that param key == the passed on param. 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, buffer, (short) (offset + length)); + length += keyGenerator.exportParameters(keyPair, EC_Consts.KEY_PRIVATE, params, outBuffer, (short) (outOffset + length)); sw = keyGenerator.getSW(); } - Util.setShort(buffer, swOffset, sw); + Util.setShort(outBuffer, swOffset, sw); return length; } @@ -545,11 +540,11 @@ public class ECTesterApplet extends Applet { * @param export whether to export ECDH secret * @param corruption whether to invalidate the pubkey before ECDH * @param type KeyAgreement type to test (EC_Consts.KA_* || ...) - * @param buffer buffer to write sw to, and export ECDH secret {@code if(export == EXPORT_TRUE)} - * @param offset output offset in buffer + * @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 corruption, byte type, byte[] buffer, short offset) { + private short ecdh(byte pubkey, byte privkey, byte export, short corruption, byte type, byte[] outBuffer, short outOffset) { short length = 0; KeyPair pub = ((pubkey & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair; @@ -573,13 +568,13 @@ public class ECTesterApplet extends Applet { ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } - Util.setShort(buffer, offset, keyTester.getSW()); + Util.setShort(outBuffer, outOffset, keyTester.getSW()); length += 2; if ((export == EXPORT_TRUE)) { - Util.setShort(buffer, (short) (offset + length), secretLength); + Util.setShort(outBuffer, (short) (outOffset + length), secretLength); length += 2; - Util.arrayCopyNonAtomic(ramArray2, (short) 0, buffer, (short) (offset + length), secretLength); + Util.arrayCopyNonAtomic(ramArray2, (short) 0, outBuffer, (short) (outOffset + length), secretLength); length += secretLength; } @@ -589,32 +584,33 @@ public class ECTesterApplet extends Applet { /** * @param sign keyPair to use for signing and verification * @param export whether to export ECDSA signature - * @param buffer buffer to write sw to, and export ECDSA signature {@code if(export == EXPORT_TRUE)} + * @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 export, byte[] buffer, short inOffset, short outOffset) { + private short ecdsa(KeyPair sign, byte export, byte[] inBuffer, short inOffset, byte[] outBuffer, short outOffset) { short length = 0; - short dataLength = Util.getShort(buffer, inOffset); + 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(buffer, (short) (inOffset + 2), ramArray, (short) 0, dataLength); + Util.arrayCopyNonAtomic(inBuffer, (short) (inOffset + 2), ramArray, (short) 0, dataLength); } short signatureLength = keyTester.testECDSA((ECPrivateKey) sign.getPrivate(), (ECPublicKey) sign.getPublic(), ramArray, (short) 0, dataLength, ramArray2, (short) 0); - Util.setShort(buffer, outOffset, keyTester.getSW()); + Util.setShort(outBuffer, outOffset, keyTester.getSW()); length += 2; if (export == EXPORT_TRUE) { - Util.setShort(buffer, (short) (outOffset + length), signatureLength); + Util.setShort(outBuffer, (short) (outOffset + length), signatureLength); length += 2; - Util.arrayCopyNonAtomic(ramArray2, (short) 0, buffer, (short) (outOffset + length), signatureLength); + Util.arrayCopyNonAtomic(ramArray2, (short) 0, outBuffer, (short) (outOffset + length), signatureLength); length += signatureLength; } diff --git a/src/cz/crcs/ectester/applet/ECUtil.java b/src/cz/crcs/ectester/applet/ECUtil.java deleted file mode 100644 index 5d5c4d2..0000000 --- a/src/cz/crcs/ectester/applet/ECUtil.java +++ /dev/null @@ -1,35 +0,0 @@ -package cz.crcs.ectester.applet; - -import javacard.framework.ISO7816; -import javacard.framework.ISOException; -import javacard.security.KeyAgreement; -import javacard.security.KeyPair; -import javacard.security.Signature; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class ECUtil { - - private static short nullCheck(Object obj, short sw) { - if (obj == null) - ISOException.throwIt(sw); - return ISO7816.SW_NO_ERROR; - } - - static short objCheck(Object obj) { - return nullCheck(obj, ECTesterApplet.SW_OBJECT_NULL); - } - - static short keypairCheck(KeyPair keyPair) { - return nullCheck(keyPair, ECTesterApplet.SW_KEYPAIR_NULL); - } - - static short kaCheck(KeyAgreement keyAgreement) { - return nullCheck(keyAgreement, ECTesterApplet.SW_KA_NULL); - } - - static short signCheck(Signature signature) { - return nullCheck(signature, ECTesterApplet.SW_SIGNATURE_NULL); - } -} diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index d970542..0276019 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -1306,7 +1306,7 @@ public class EC_Consts { // an uncompressed point should have odd length (since 1 byte type, + 2 * coords) ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } - short half = (short) ((short)(length - 1) / 2); + short half = (short) ((short) (length - 1) / 2); byte yLSB = buffer[(short) (offset + length)]; byte yBit = (byte) (yLSB & 0x01); if (yBit == 1) { @@ -1317,7 +1317,7 @@ public class EC_Consts { length = (short) (half + 1); break; - //TODO: test hybrid form with not corresponding yBit (in first byte value) and y_value in the second half of the param + //TODO: test hybrid form with not corresponding yBit (in first byte value) and y_value in the second half of the param default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } diff --git a/src/cz/crcs/ectester/data/nist/p521.csv b/src/cz/crcs/ectester/data/nist/p521.csv index fee50ce..e280665 100644 --- a/src/cz/crcs/ectester/data/nist/p521.csv +++ b/src/cz/crcs/ectester/data/nist/p521.csv @@ -1 +1 @@ -1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff,1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc,051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00,c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66,11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650,1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409,1
\ No newline at end of file +01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff,01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc,0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00,00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66,011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650,01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409,1
\ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/Command.java b/src/cz/crcs/ectester/reader/Command.java index 4e210ed..6c2b769 100644 --- a/src/cz/crcs/ectester/reader/Command.java +++ b/src/cz/crcs/ectester/reader/Command.java @@ -66,6 +66,9 @@ public abstract class Command { if (curve.getBits() != keyLength) { throw new IOException("Curve bits mismatch: " + curve.getBits() + " vs " + keyLength + " entered."); } + if (curve.getField() != keyClass) { + throw new IOException("Curve field mismatch."); + } byte[] external = curve.flatten(); if (external == null) { diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 217b9ef..4ba8e9a 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -368,6 +368,9 @@ public class ECTester { keysFile.flush(); generated++; } + Response cleanup = new Command.Cleanup(cardManager).send(); + systemOutLogger.println(cleanup.toString()); + keysFile.close(); } @@ -474,6 +477,8 @@ public class ECTester { ++done; } + Response cleanup = new Command.Cleanup(cardManager).send(); + systemOutLogger.println(cleanup.toString()); if (out != null) out.close(); @@ -545,6 +550,9 @@ public class ECTester { ++done; } + Response cleanup = new Command.Cleanup(cardManager).send(); + systemOutLogger.println(cleanup.toString()); + if (out != null) out.close(); } diff --git a/src/cz/crcs/ectester/reader/Response.java b/src/cz/crcs/ectester/reader/Response.java index c82772f..d74724c 100644 --- a/src/cz/crcs/ectester/reader/Response.java +++ b/src/cz/crcs/ectester/reader/Response.java @@ -126,7 +126,7 @@ public abstract class Response { } } if (suffix.length() == 0) { - suffix.append(" ").append(Util.getSWString(getNaturalSW())); + suffix.append(" [").append(Util.getSW(getNaturalSW())).append("]"); } return String.format("%-62s:%4d ms : %s", inner, time / 1000000, suffix); } diff --git a/src/cz/crcs/ectester/reader/Test.java b/src/cz/crcs/ectester/reader/Test.java index 651274d..157e360 100644 --- a/src/cz/crcs/ectester/reader/Test.java +++ b/src/cz/crcs/ectester/reader/Test.java @@ -61,6 +61,10 @@ public class Test { hasRun = true; } + public boolean hasRun() { + return hasRun; + } + @Override public String toString() { if (hasRun) { diff --git a/src/cz/crcs/ectester/reader/TestSuite.java b/src/cz/crcs/ectester/reader/TestSuite.java index 5e9511b..414c2a9 100644 --- a/src/cz/crcs/ectester/reader/TestSuite.java +++ b/src/cz/crcs/ectester/reader/TestSuite.java @@ -4,6 +4,7 @@ import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.ec.*; +import javacard.security.Key; import javacard.security.KeyPair; import javax.smartcardio.CardException; @@ -18,7 +19,6 @@ public abstract class TestSuite { EC_Store dataStore; ECTester.Config cfg; String name; - boolean hasRun = false; List<Test> tests = new LinkedList<>(); TestSuite(EC_Store dataStore, ECTester.Config cfg, String name) { @@ -29,10 +29,11 @@ public abstract class TestSuite { public List<Test> run(CardMngr cardManager) throws CardException, IOException { for (Test t : tests) { - t.run(); - System.out.println(t); + if (!t.hasRun()) { + t.run(); + System.out.println(t); + } } - hasRun = true; return tests; } @@ -40,10 +41,6 @@ public abstract class TestSuite { return Collections.unmodifiableList(tests); } - public boolean hasRun() { - return hasRun; - } - public String getName() { return name; } @@ -171,6 +168,9 @@ public abstract class TestSuite { if (curve.getBits() != cfg.bits && !cfg.all) { continue; } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } EC_Params onekey = dataStore.getObject(EC_Keypair.class, result.getOneKey()); if (onekey == null) { onekey = dataStore.getObject(EC_Key.Private.class, result.getOneKey()); @@ -206,7 +206,6 @@ public abstract class TestSuite { public static class NonPrime extends TestSuite { - public NonPrime(EC_Store dataStore, ECTester.Config cfg) { super(dataStore, cfg, "nonprime"); } @@ -222,6 +221,12 @@ public abstract class TestSuite { Map<String, EC_Key> keys = dataStore.getObjects(EC_Key.class, "nonprime"); for (EC_Key key : keys.values()) { EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); + if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } if ((curve.getBits() == cfg.bits || cfg.all)) { tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); @@ -256,6 +261,9 @@ public abstract class TestSuite { if (curve.getBits() != cfg.bits && !cfg.all) { continue; } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } List<EC_Key.Public> keys = curves.getOrDefault(curve, new LinkedList<>()); keys.add(key); curves.putIfAbsent(curve, keys); diff --git a/src/cz/crcs/ectester/reader/Util.java b/src/cz/crcs/ectester/reader/Util.java index 986433f..3a7e9fe 100644 --- a/src/cz/crcs/ectester/reader/Util.java +++ b/src/cz/crcs/ectester/reader/Util.java @@ -166,115 +166,120 @@ public class Util { } } + public static String getSW(short sw) { + String str; + switch (sw) { + case ISO7816.SW_APPLET_SELECT_FAILED: + str = "APPLET_SELECT_FAILED"; + break; + case ISO7816.SW_BYTES_REMAINING_00: + str = "BYTES_REMAINING"; + break; + case ISO7816.SW_CLA_NOT_SUPPORTED: + str = "CLA_NOT_SUPPORTED"; + break; + case ISO7816.SW_COMMAND_NOT_ALLOWED: + str = "COMMAND_NOT_ALLOWED"; + break; + case ISO7816.SW_CONDITIONS_NOT_SATISFIED: + str = "CONDITIONS_NOT_SATISFIED"; + break; + case ISO7816.SW_CORRECT_LENGTH_00: + str = "CORRECT_LENGTH"; + break; + case ISO7816.SW_DATA_INVALID: + str = "DATA_INVALID"; + break; + case ISO7816.SW_FILE_FULL: + str = "FILE_FULL"; + break; + case ISO7816.SW_FILE_INVALID: + str = "FILE_INVALID"; + break; + case ISO7816.SW_FILE_NOT_FOUND: + str = "FILE_NOT_FOUND"; + break; + case ISO7816.SW_FUNC_NOT_SUPPORTED: + str = "FUNC_NOT_SUPPORTED"; + break; + case ISO7816.SW_INCORRECT_P1P2: + str = "INCORRECT_P1P2"; + break; + case ISO7816.SW_INS_NOT_SUPPORTED: + str = "INS_NOT_SUPPORTED"; + break; + case ISO7816.SW_LOGICAL_CHANNEL_NOT_SUPPORTED: + str = "LOGICAL_CHANNEL_NOT_SUPPORTED"; + break; + case ISO7816.SW_RECORD_NOT_FOUND: + str = "RECORD_NOT_FOUND"; + break; + case ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED: + str = "SECURE_MESSAGING_NOT_SUPPORTED"; + break; + case ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED: + str = "SECURITY_STATUS_NOT_SATISFIED"; + break; + case ISO7816.SW_UNKNOWN: + str = "UNKNOWN"; + break; + case ISO7816.SW_WARNING_STATE_UNCHANGED: + str = "WARNING_STATE_UNCHANGED"; + break; + case ISO7816.SW_WRONG_DATA: + str = "WRONG_DATA"; + break; + case ISO7816.SW_WRONG_LENGTH: + str = "WRONG_LENGTH"; + break; + case ISO7816.SW_WRONG_P1P2: + str = "WRONG_P1P2"; + break; + case CryptoException.ILLEGAL_VALUE: + str = "ILLEGAL_VALUE"; + break; + case CryptoException.UNINITIALIZED_KEY: + str = "UNINITIALIZED_KEY"; + break; + case CryptoException.NO_SUCH_ALGORITHM: + str = "NO_SUCH_ALG"; + break; + case CryptoException.INVALID_INIT: + str = "INVALID_INIT"; + break; + case CryptoException.ILLEGAL_USE: + str = "ILLEGAL_USE"; + break; + case ECTesterApplet.SW_SIG_VERIFY_FAIL: + str = "SIG_VERIFY_FAIL"; + break; + case ECTesterApplet.SW_DH_DHC_MISMATCH: + str = "DH_DHC_MISMATCH"; + break; + case ECTesterApplet.SW_KEYPAIR_NULL: + str = "KEYPAIR_NULL"; + break; + case ECTesterApplet.SW_KA_NULL: + str = "KA_NULL"; + break; + case ECTesterApplet.SW_SIGNATURE_NULL: + str = "SIGNATURE_NULL"; + break; + case ECTesterApplet.SW_OBJECT_NULL: + str = "OBJECT_NULL"; + break; + default: + str = "unknown"; + break; + } + return str; + } + public static String getSWString(short sw) { if (sw == ISO7816.SW_NO_ERROR) { return "OK\t(0x9000)"; } else { - String str; - switch (sw) { - case ISO7816.SW_APPLET_SELECT_FAILED: - str = "APPLET_SELECT_FAILED"; - break; - case ISO7816.SW_BYTES_REMAINING_00: - str = "BYTES_REMAINING"; - break; - case ISO7816.SW_CLA_NOT_SUPPORTED: - str = "CLA_NOT_SUPPORTED"; - break; - case ISO7816.SW_COMMAND_NOT_ALLOWED: - str = "COMMAND_NOT_ALLOWED"; - break; - case ISO7816.SW_CONDITIONS_NOT_SATISFIED: - str = "CONDITIONS_NOT_SATISFIED"; - break; - case ISO7816.SW_CORRECT_LENGTH_00: - str = "CORRECT_LENGTH"; - break; - case ISO7816.SW_DATA_INVALID: - str = "DATA_INVALID"; - break; - case ISO7816.SW_FILE_FULL: - str = "FILE_FULL"; - break; - case ISO7816.SW_FILE_INVALID: - str = "FILE_INVALID"; - break; - case ISO7816.SW_FILE_NOT_FOUND: - str = "FILE_NOT_FOUND"; - break; - case ISO7816.SW_FUNC_NOT_SUPPORTED: - str = "FUNC_NOT_SUPPORTED"; - break; - case ISO7816.SW_INCORRECT_P1P2: - str = "INCORRECT_P1P2"; - break; - case ISO7816.SW_INS_NOT_SUPPORTED: - str = "INS_NOT_SUPPORTED"; - break; - case ISO7816.SW_LOGICAL_CHANNEL_NOT_SUPPORTED: - str = "LOGICAL_CHANNEL_NOT_SUPPORTED"; - break; - case ISO7816.SW_RECORD_NOT_FOUND: - str = "RECORD_NOT_FOUND"; - break; - case ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED: - str = "SECURE_MESSAGING_NOT_SUPPORTED"; - break; - case ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED: - str = "SECURITY_STATUS_NOT_SATISFIED"; - break; - case ISO7816.SW_UNKNOWN: - str = "UNKNOWN"; - break; - case ISO7816.SW_WARNING_STATE_UNCHANGED: - str = "WARNING_STATE_UNCHANGED"; - break; - case ISO7816.SW_WRONG_DATA: - str = "WRONG_DATA"; - break; - case ISO7816.SW_WRONG_LENGTH: - str = "WRONG_LENGTH"; - break; - case ISO7816.SW_WRONG_P1P2: - str = "WRONG_P1P2"; - break; - case CryptoException.ILLEGAL_VALUE: - str = "ILLEGAL_VALUE"; - break; - case CryptoException.UNINITIALIZED_KEY: - str = "UNINITIALIZED_KEY"; - break; - case CryptoException.NO_SUCH_ALGORITHM: - str = "NO_SUCH_ALG"; - break; - case CryptoException.INVALID_INIT: - str = "INVALID_INIT"; - break; - case CryptoException.ILLEGAL_USE: - str = "ILLEGAL_USE"; - break; - case ECTesterApplet.SW_SIG_VERIFY_FAIL: - str = "SIG_VERIFY_FAIL"; - break; - case ECTesterApplet.SW_DH_DHC_MISMATCH: - str = "DH_DHC_MISMATCH"; - break; - case ECTesterApplet.SW_KEYPAIR_NULL: - str = "KEYPAIR_NULL"; - break; - case ECTesterApplet.SW_KA_NULL: - str = "KA_NULL"; - break; - case ECTesterApplet.SW_SIGNATURE_NULL: - str = "SIGNATURE_NULL"; - break; - case ECTesterApplet.SW_OBJECT_NULL: - str = "OBJECT_NULL"; - break; - default: - str = "unknown"; - break; - } + String str = getSW(sw); return String.format("fail\t(%s,\t0x%04x)", str, sw); } } |
