diff options
| author | J08nY | 2018-11-30 19:33:50 +0100 |
|---|---|---|
| committer | J08nY | 2018-11-30 19:33:50 +0100 |
| commit | a058a9162e894a740d3a11893bd831a72c936c05 (patch) | |
| tree | 209f6ec67073dddeccd372338960969b3e379dd7 | |
| parent | 687a09baf6fd858d393b8f284cfe7236b52d7457 (diff) | |
| download | ECTester-a058a9162e894a740d3a11893bd831a72c936c05.tar.gz ECTester-a058a9162e894a740d3a11893bd831a72c936c05.tar.zst ECTester-a058a9162e894a740d3a11893bd831a72c936c05.zip | |
| -rw-r--r-- | src/cz/crcs/ectester/applet/AppletBase.java | 36 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECKeyGenerator.java | 154 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECKeyTester.java | 63 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/common/ec/EC_Category.java | 2 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/command/Command.java | 31 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/response/Response.java | 12 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/test/CardDefaultSuite.java | 6 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/test/PerformanceTest.java | 38 |
8 files changed, 259 insertions, 83 deletions
diff --git a/src/cz/crcs/ectester/applet/AppletBase.java b/src/cz/crcs/ectester/applet/AppletBase.java index 48e7785..154b209 100644 --- a/src/cz/crcs/ectester/applet/AppletBase.java +++ b/src/cz/crcs/ectester/applet/AppletBase.java @@ -24,6 +24,7 @@ public abstract class AppletBase extends Applet { 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; // PARAMETERS for P1 and P2 public static final byte KEYPAIR_LOCAL = (byte) 0x01; @@ -31,6 +32,8 @@ public abstract class AppletBase extends Applet { public static final byte KEYPAIR_BOTH = KEYPAIR_LOCAL | KEYPAIR_REMOTE; 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; @@ -159,6 +162,8 @@ public abstract class AppletBase extends Applet { case INS_GET_INFO: length = insGetInfo(apdu); break; + case INS_SET_DRY_RUN_MODE: + length = insSetDryRunMode(apdu); default: // The INS code is not supported by the dispatcher ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); @@ -545,6 +550,26 @@ public abstract class AppletBase extends Applet { } /** + * 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 keyLength key length to set * @param keyClass key class to allocate @@ -883,4 +908,15 @@ public abstract class AppletBase extends Applet { 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; + } } diff --git a/src/cz/crcs/ectester/applet/ECKeyGenerator.java b/src/cz/crcs/ectester/applet/ECKeyGenerator.java index 4326752..30910ca 100644 --- a/src/cz/crcs/ectester/applet/ECKeyGenerator.java +++ b/src/cz/crcs/ectester/applet/ECKeyGenerator.java @@ -14,6 +14,7 @@ import javacard.security.KeyPair; public class ECKeyGenerator { private short sw = ISO7816.SW_NO_ERROR; + private boolean dryRun = false; /** * @param keyClass @@ -24,12 +25,14 @@ public class ECKeyGenerator { sw = ISO7816.SW_NO_ERROR; KeyPair ecKeyPair = null; try { - ecKeyPair = new KeyPair(keyClass, keyLength); + if (!dryRun) { + ecKeyPair = new KeyPair(keyClass, keyLength); - if (ecKeyPair.getPublic() == null || ecKeyPair.getPrivate() == null) { - try { - ecKeyPair.genKeyPair(); - } catch (Exception ignored) { + if (ecKeyPair.getPublic() == null || ecKeyPair.getPrivate() == null) { + try { + ecKeyPair.genKeyPair(); + } catch (Exception ignored) { + } } } } catch (CardRuntimeException ce) { @@ -46,8 +49,10 @@ public class ECKeyGenerator { public short clearPair(KeyPair keypair, byte key) { try { sw = AppletUtil.keypairCheck(keypair); - if ((key & EC_Consts.KEY_PUBLIC) != 0) keypair.getPublic().clearKey(); - if ((key & EC_Consts.KEY_PRIVATE) != 0) keypair.getPrivate().clearKey(); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) keypair.getPublic().clearKey(); + if ((key & EC_Consts.KEY_PRIVATE) != 0) keypair.getPrivate().clearKey(); + } } catch (CardRuntimeException ce) { sw = ce.getReason(); } @@ -61,7 +66,9 @@ public class ECKeyGenerator { public short generatePair(KeyPair keypair) { try { sw = AppletUtil.keypairCheck(keypair); - keypair.genKeyPair(); + if (!dryRun) { + keypair.genKeyPair(); + } } catch (CardRuntimeException ce) { sw = ce.getReason(); } @@ -187,25 +194,35 @@ public class ECKeyGenerator { try { sw = AppletUtil.keypairCheck(keypair); - ECPublicKey ecPublicKey = (ECPublicKey) keypair.getPublic(); - ECPrivateKey ecPrivateKey = (ECPrivateKey) keypair.getPrivate(); + ECPublicKey ecPublicKey = null; + ECPrivateKey ecPrivateKey = null; + if (!dryRun) { + ecPublicKey = (ECPublicKey) keypair.getPublic(); + ecPrivateKey = (ECPrivateKey) keypair.getPrivate(); + } switch (param) { case EC_Consts.PARAMETER_FP: - if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldFP(data, offset, length); - if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setFieldFP(data, offset, length); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldFP(data, offset, length); + if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setFieldFP(data, offset, length); + } break; case EC_Consts.PARAMETER_F2M: if (length == 4) { short i = Util.getShort(data, (short) (offset + 2)); - if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldF2M(i); - if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setFieldF2M(i); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldF2M(i); + if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setFieldF2M(i); + } } else if (length == 8) { short i1 = Util.getShort(data, (short) (offset + 2)); short i2 = Util.getShort(data, (short) (offset + 4)); short i3 = Util.getShort(data, (short) (offset + 6)); - if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldF2M(i1, i2, i3); - if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setFieldF2M(i1, i2, i3); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldF2M(i1, i2, i3); + if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setFieldF2M(i1, i2, i3); + } // if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldF2M(i3, i2, i1); // if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setFieldF2M(i3, i2, i1); } else { @@ -213,20 +230,28 @@ public class ECKeyGenerator { } break; case EC_Consts.PARAMETER_A: - if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setA(data, offset, length); - if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setA(data, offset, length); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setA(data, offset, length); + if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setA(data, offset, length); + } break; case EC_Consts.PARAMETER_B: - if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setB(data, offset, length); - if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setB(data, offset, length); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setB(data, offset, length); + if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setB(data, offset, length); + } break; case EC_Consts.PARAMETER_G: - if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setG(data, offset, length); - if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setG(data, offset, length); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setG(data, offset, length); + if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setG(data, offset, length); + } break; case EC_Consts.PARAMETER_R: - if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setR(data, offset, length); - if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setR(data, offset, length); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setR(data, offset, length); + if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setR(data, offset, length); + } break; case EC_Consts.PARAMETER_K: short k = 0; @@ -238,14 +263,20 @@ public class ECKeyGenerator { } else if (length == 1) { k = data[offset]; } - if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setK(k); - if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setK(k); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setK(k); + if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setK(k); + } break; case EC_Consts.PARAMETER_S: - if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setS(data, offset, length); + if (!dryRun) { + if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setS(data, offset, length); + } break; case EC_Consts.PARAMETER_W: - if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setW(data, offset, length); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setW(data, offset, length); + } break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); @@ -310,54 +341,75 @@ public class ECKeyGenerator { short length = 0; try { sw = AppletUtil.keypairCheck(keypair); - ECPublicKey ecPublicKey = (ECPublicKey) keypair.getPublic(); - ECPrivateKey ecPrivateKey = (ECPrivateKey) keypair.getPrivate(); + + ECPublicKey ecPublicKey = null; + ECPrivateKey ecPrivateKey = null; + if (!dryRun) { + ecPublicKey = (ECPublicKey) keypair.getPublic(); + ecPrivateKey = (ECPrivateKey) keypair.getPrivate(); + } switch (param) { case EC_Consts.PARAMETER_FP: - if ((key & EC_Consts.KEY_PUBLIC) != 0) length = ecPublicKey.getField(outputBuffer, outputOffset); - if ((key & EC_Consts.KEY_PRIVATE) != 0) length = ecPrivateKey.getField(outputBuffer, outputOffset); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) + length = ecPublicKey.getField(outputBuffer, outputOffset); + if ((key & EC_Consts.KEY_PRIVATE) != 0) + length = ecPrivateKey.getField(outputBuffer, outputOffset); + } break; case EC_Consts.PARAMETER_F2M: - if ((key & EC_Consts.KEY_PUBLIC) != 0) { + if ((key & EC_Consts.KEY_PUBLIC) != 0 && !dryRun) { Util.setShort(outputBuffer, outputOffset, ecPublicKey.getSize()); length = 2; length += ecPublicKey.getField(outputBuffer, (short) (outputOffset + 2)); } - if ((key & EC_Consts.KEY_PRIVATE) != 0) { + if ((key & EC_Consts.KEY_PRIVATE) != 0 && !dryRun) { Util.setShort(outputBuffer, outputOffset, ecPrivateKey.getSize()); length = 2; length += ecPrivateKey.getField(outputBuffer, (short) (outputOffset + 2)); } break; case EC_Consts.PARAMETER_A: - if ((key & EC_Consts.KEY_PUBLIC) != 0) length = ecPublicKey.getA(outputBuffer, outputOffset); - if ((key & EC_Consts.KEY_PRIVATE) != 0) length = ecPrivateKey.getA(outputBuffer, outputOffset); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) length = ecPublicKey.getA(outputBuffer, outputOffset); + if ((key & EC_Consts.KEY_PRIVATE) != 0) length = ecPrivateKey.getA(outputBuffer, outputOffset); + } break; case EC_Consts.PARAMETER_B: - if ((key & EC_Consts.KEY_PUBLIC) != 0) length = ecPublicKey.getB(outputBuffer, outputOffset); - if ((key & EC_Consts.KEY_PRIVATE) != 0) length = ecPrivateKey.getB(outputBuffer, outputOffset); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) length = ecPublicKey.getB(outputBuffer, outputOffset); + if ((key & EC_Consts.KEY_PRIVATE) != 0) length = ecPrivateKey.getB(outputBuffer, outputOffset); + } break; case EC_Consts.PARAMETER_G: - if ((key & EC_Consts.KEY_PUBLIC) != 0) length = ecPublicKey.getG(outputBuffer, outputOffset); - if ((key & EC_Consts.KEY_PRIVATE) != 0) length = ecPrivateKey.getG(outputBuffer, outputOffset); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) length = ecPublicKey.getG(outputBuffer, outputOffset); + if ((key & EC_Consts.KEY_PRIVATE) != 0) length = ecPrivateKey.getG(outputBuffer, outputOffset); + } break; case EC_Consts.PARAMETER_R: - if ((key & EC_Consts.KEY_PUBLIC) != 0) length = ecPublicKey.getR(outputBuffer, outputOffset); - if ((key & EC_Consts.KEY_PRIVATE) != 0) length = ecPrivateKey.getR(outputBuffer, outputOffset); + if (!dryRun) { + if ((key & EC_Consts.KEY_PUBLIC) != 0) length = ecPublicKey.getR(outputBuffer, outputOffset); + if ((key & EC_Consts.KEY_PRIVATE) != 0) length = ecPrivateKey.getR(outputBuffer, outputOffset); + } break; case EC_Consts.PARAMETER_K: - length = 2; - if ((key & EC_Consts.KEY_PUBLIC) != 0) - Util.setShort(outputBuffer, outputOffset, ecPublicKey.getK()); - if ((key & EC_Consts.KEY_PRIVATE) != 0) - Util.setShort(outputBuffer, outputOffset, ecPrivateKey.getK()); + if (!dryRun) { + length = 2; + if ((key & EC_Consts.KEY_PUBLIC) != 0) + Util.setShort(outputBuffer, outputOffset, ecPublicKey.getK()); + if ((key & EC_Consts.KEY_PRIVATE) != 0) + Util.setShort(outputBuffer, outputOffset, ecPrivateKey.getK()); + } break; case EC_Consts.PARAMETER_W: - if ((key & EC_Consts.KEY_PUBLIC) != 0) length = ecPublicKey.getW(outputBuffer, outputOffset); + if ((key & EC_Consts.KEY_PUBLIC) != 0 && !dryRun) + length = ecPublicKey.getW(outputBuffer, outputOffset); break; case EC_Consts.PARAMETER_S: - if ((key & EC_Consts.KEY_PRIVATE) != 0) length = ecPrivateKey.getS(outputBuffer, outputOffset); + if ((key & EC_Consts.KEY_PRIVATE) != 0 && !dryRun) + length = ecPrivateKey.getS(outputBuffer, outputOffset); break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); @@ -439,4 +491,8 @@ public class ECKeyGenerator { public short getSW() { return sw; } + + public void setDryRun(boolean dryRun) { + this.dryRun = dryRun; + } } diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index 0e46971..89590d0 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -18,12 +18,15 @@ public class ECKeyTester { private short sigType = 0; private short sw = ISO7816.SW_NO_ERROR; + private boolean dryRun = false; public short allocateKA(byte algorithm) { sw = ISO7816.SW_NO_ERROR; try { - ecKeyAgreement = KeyAgreement.getInstance(algorithm, false); - kaType = algorithm; + if (!dryRun) { + ecKeyAgreement = KeyAgreement.getInstance(algorithm, false); + kaType = algorithm; + } } catch (CardRuntimeException ce) { sw = ce.getReason(); } @@ -33,8 +36,10 @@ public class ECKeyTester { public short allocateSig(byte algorithm) { sw = ISO7816.SW_NO_ERROR; try { - ecdsaSignature = Signature.getInstance(algorithm, false); - sigType = algorithm; + if (!dryRun) { + ecdsaSignature = Signature.getInstance(algorithm, false); + sigType = algorithm; + } } catch (CardRuntimeException ce) { sw = ce.getReason(); } @@ -61,11 +66,13 @@ public class ECKeyTester { sw = AppletUtil.kaCheck(ecKeyAgreement); sw = AppletUtil.keypairCheck(privatePair); sw = AppletUtil.keypairCheck(publicPair); - short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset); - ecKeyAgreement.init(privatePair.getPrivate()); + if (!dryRun) { + short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset); + ecKeyAgreement.init(privatePair.getPrivate()); - pubkeyLength = EC_Consts.transformParameter(transformation, pubkeyBuffer, pubkeyOffset, pubkeyLength); - length = ecKeyAgreement.generateSecret(pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset); + pubkeyLength = EC_Consts.transformParameter(transformation, pubkeyBuffer, pubkeyOffset, pubkeyLength); + length = ecKeyAgreement.generateSecret(pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset); + } } catch (CardRuntimeException ce) { sw = ce.getReason(); } @@ -88,9 +95,11 @@ public class ECKeyTester { sw = AppletUtil.kaCheck(ecKeyAgreement); sw = AppletUtil.keypairCheck(privatePair); - ecKeyAgreement.init(privatePair.getPrivate()); - pubkeyLength = EC_Consts.transformParameter(transformation, pubkey, pubkeyOffset, pubkeyLength); - length = ecKeyAgreement.generateSecret(pubkey, pubkeyOffset, pubkeyLength, outpuBuffer, outputOffset); + if (!dryRun) { + ecKeyAgreement.init(privatePair.getPrivate()); + pubkeyLength = EC_Consts.transformParameter(transformation, pubkey, pubkeyOffset, pubkeyLength); + length = ecKeyAgreement.generateSecret(pubkey, pubkeyOffset, pubkeyLength, outpuBuffer, outputOffset); + } } catch (CardRuntimeException ce) { sw = ce.getReason(); } @@ -116,13 +125,14 @@ public class ECKeyTester { try { sw = AppletUtil.signCheck(ecdsaSignature); - ecdsaSignature.init(signKey, Signature.MODE_SIGN); - length = ecdsaSignature.sign(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset); + if (!dryRun) { + ecdsaSignature.init(signKey, Signature.MODE_SIGN); + length = ecdsaSignature.sign(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset); - ecdsaSignature.init(verifyKey, Signature.MODE_VERIFY); - boolean correct = ecdsaSignature.verify(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset, length); - if (!correct) { - sw = AppletBase.SW_SIG_VERIFY_FAIL; + ecdsaSignature.init(verifyKey, Signature.MODE_VERIFY); + if (!ecdsaSignature.verify(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset, length)) { + sw = AppletBase.SW_SIG_VERIFY_FAIL; + } } } catch (CardRuntimeException ce) { sw = ce.getReason(); @@ -144,8 +154,10 @@ public class ECKeyTester { try { sw = AppletUtil.signCheck(ecdsaSignature); - ecdsaSignature.init(signKey, Signature.MODE_SIGN); - length = ecdsaSignature.sign(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset); + if (!dryRun) { + ecdsaSignature.init(signKey, Signature.MODE_SIGN); + length = ecdsaSignature.sign(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset); + } } catch (CardRuntimeException ce) { sw = ce.getReason(); } @@ -167,10 +179,11 @@ public class ECKeyTester { try { sw = AppletUtil.signCheck(ecdsaSignature); - ecdsaSignature.init(verifyKey, Signature.MODE_VERIFY); - boolean correct = ecdsaSignature.verify(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset, sigLength); - if (!correct) { - sw = AppletBase.SW_SIG_VERIFY_FAIL; + if (!dryRun) { + ecdsaSignature.init(verifyKey, Signature.MODE_VERIFY); + if (!ecdsaSignature.verify(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset, sigLength)) { + sw = AppletBase.SW_SIG_VERIFY_FAIL; + } } } catch (CardRuntimeException ce) { sw = ce.getReason(); @@ -205,4 +218,8 @@ public class ECKeyTester { public short getSW() { return sw; } + + public void setDryRun(boolean dryRun) { + this.dryRun = dryRun; + } } diff --git a/src/cz/crcs/ectester/common/ec/EC_Category.java b/src/cz/crcs/ectester/common/ec/EC_Category.java index 05c910c..1eb818f 100644 --- a/src/cz/crcs/ectester/common/ec/EC_Category.java +++ b/src/cz/crcs/ectester/common/ec/EC_Category.java @@ -92,7 +92,7 @@ public class EC_Category { } String[] headers = new String[]{"Public keys", "Private keys", "KeyPairs", "Results(KA)", "Results(SIG)"}; - Class[] classes = new Class[]{EC_Key.Public.class, EC_Key.Private.class, EC_Keypair.class, EC_KAResult.class, EC_SigResult.class}; + Class<EC_Data>[] classes = new Class[]{EC_Key.Public.class, EC_Key.Private.class, EC_Keypair.class, EC_KAResult.class, EC_SigResult.class}; for (int i = 0; i < headers.length; ++i) { Map<String, EC_Data> data = getObjects(classes[i]); size = data.size(); diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index a3560df..1b1ec33 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -890,5 +890,36 @@ public abstract class Command implements Cloneable { return "Get applet info"; } } + + /** + * + */ + public static class SetDryRunMode extends Command { + private byte dryRunMode; + /** + * + * @param cardManager + * @param dryRunMode + */ + public SetDryRunMode(CardMngr cardManager, byte dryRunMode) { + super(cardManager); + this.dryRunMode = dryRunMode; + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SET_DRY_RUN_MODE, dryRunMode, 0); + } + + @Override + public Response send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.SetDryRunMode(response, getDescription(), elapsed); + } + + @Override + public String getDescription() { + return (dryRunMode == ECTesterApplet.MODE_NORMAL ? "Disable" : "Enable") + " dry run mode"; + } + } } diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java index 235564e..0dded7c 100644 --- a/src/cz/crcs/ectester/reader/response/Response.java +++ b/src/cz/crcs/ectester/reader/response/Response.java @@ -502,4 +502,16 @@ public abstract class Response { return apduArrayLength; } } + + /** + * + */ + public static class SetDryRunMode extends Response { + + public SetDryRunMode(ResponseAPDU response, String description, long time) { + super(response, description, time); + + parse(1, 0); + } + } } diff --git a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java index 91f9ef6..f42af23 100644 --- a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java @@ -83,7 +83,7 @@ public class CardDefaultSuite extends CardTestSuite { Test compound; if (ka.ok()) { - Test perfTest = runTest(PerformanceTest.repeat(ecdh, 10)); + Test perfTest = runTest(PerformanceTest.repeat(this.card, ecdh, 10)); compound = runTest(CompoundTest.function(kaCallback, kaDesc, allocate, ka, kaCompressed, perfTest)); } else { compound = runTest(CompoundTest.function(kaCallback, kaDesc, allocate, ka, kaCompressed)); @@ -114,10 +114,10 @@ public class CardDefaultSuite extends CardTestSuite { Test compound; if (expect.ok()) { Command ecdsaSign = new Command.ECDSA_sign(this.card, ECTesterApplet.KEYPAIR_LOCAL, sigType, ECTesterApplet.EXPORT_TRUE, sigData); - PerformanceTest signTest = runTest(PerformanceTest.repeat("Sign", ecdsaSign, 10)); + PerformanceTest signTest = runTest(PerformanceTest.repeat(this.card, "Sign", ecdsaSign, 10)); byte[] signature = signTest.getResponses()[0].getParam(0); Command ecdsaVerify = new Command.ECDSA_verify(this.card, ECTesterApplet.KEYPAIR_LOCAL, sigType, sigData, signature); - PerformanceTest verifyTest = runTest(PerformanceTest.repeat("Verify", ecdsaVerify, 10)); + PerformanceTest verifyTest = runTest(PerformanceTest.repeat(this.card, "Verify", ecdsaVerify, 10)); compound = runTest(CompoundTest.all(ExpectedValue.SUCCESS, signDesc, allocate, expect, signTest, verifyTest)); } else { compound = runTest(CompoundTest.all(ExpectedValue.SUCCESS, signDesc, allocate, expect)); diff --git a/src/cz/crcs/ectester/reader/test/PerformanceTest.java b/src/cz/crcs/ectester/reader/test/PerformanceTest.java index f9a4472..ce6780d 100644 --- a/src/cz/crcs/ectester/reader/test/PerformanceTest.java +++ b/src/cz/crcs/ectester/reader/test/PerformanceTest.java @@ -1,18 +1,24 @@ package cz.crcs.ectester.reader.test; +import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.common.test.Result; import cz.crcs.ectester.common.test.SimpleTest; import cz.crcs.ectester.common.test.TestCallback; +import cz.crcs.ectester.common.test.TestException; +import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; +import javax.smartcardio.CardException; import java.util.Arrays; /** * @author Jan Jancar johny@neuromancer.sk */ public class PerformanceTest extends SimpleTest<CommandTestable> { + private CardMngr cardManager; private long[] times; + private long[] reducedTimes; private Response[] responses; private long mean; private long median; @@ -20,23 +26,24 @@ public class PerformanceTest extends SimpleTest<CommandTestable> { private int count; private String desc; - private PerformanceTest(CommandTestable testable, int count, String desc) { + private PerformanceTest(CardMngr cardManager, CommandTestable testable, int count, String desc) { super(testable, new TestCallback<CommandTestable>() { @Override public Result apply(CommandTestable testable) { return new Result(Result.Value.SUCCESS); } }); + this.cardManager = cardManager; this.count = count; this.desc = desc; } - public static PerformanceTest repeat(Command cmd, int count) { - return new PerformanceTest(new CommandTestable(cmd), count, null); + public static PerformanceTest repeat(CardMngr cardManager, Command cmd, int count) { + return new PerformanceTest(cardManager, new CommandTestable(cmd), count, null); } - public static PerformanceTest repeat(String desc, Command cmd, int count) { - return new PerformanceTest(new CommandTestable(cmd), count, desc); + public static PerformanceTest repeat(CardMngr cardManager, String desc, Command cmd, int count) { + return new PerformanceTest(cardManager, new CommandTestable(cmd), count, desc); } @Override @@ -47,18 +54,31 @@ public class PerformanceTest extends SimpleTest<CommandTestable> { @Override protected void runSelf() { + long baseTime = 0; + try { + new Command.SetDryRunMode(cardManager, ECTesterApplet.MODE_DRY_RUN).send(); + testable.run(); + baseTime = testable.getResponse().getDuration(); + testable.reset(); + new Command.SetDryRunMode(cardManager, ECTesterApplet.MODE_NORMAL).send(); + } catch (CardException ce) { + throw new TestException(ce); + } + times = new long[count]; + reducedTimes = new long[count]; responses = new Response[count]; for (int i = 0; i < count; ++i) { testable.run(); responses[i] = testable.getResponse(); times[i] = responses[i].getDuration(); + reducedTimes[i] = times[i] - baseTime; testable.reset(); } - mean = Arrays.stream(times).sum() / count; + mean = Arrays.stream(reducedTimes).sum() / count; - long[] sorted = times.clone(); + long[] sorted = reducedTimes.clone(); Arrays.sort(sorted); if (count % 2 == 0) { median = (sorted[(count / 2) - 1] + sorted[count / 2]) / 2; @@ -99,6 +119,10 @@ public class PerformanceTest extends SimpleTest<CommandTestable> { return times; } + public long[] getReducedTimes() { + return reducedTimes; + } + public long getMean() { return mean; } |
