aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJ08nY2018-11-30 19:33:50 +0100
committerJ08nY2018-11-30 19:33:50 +0100
commita058a9162e894a740d3a11893bd831a72c936c05 (patch)
tree209f6ec67073dddeccd372338960969b3e379dd7 /src
parent687a09baf6fd858d393b8f284cfe7236b52d7457 (diff)
downloadECTester-a058a9162e894a740d3a11893bd831a72c936c05.tar.gz
ECTester-a058a9162e894a740d3a11893bd831a72c936c05.tar.zst
ECTester-a058a9162e894a740d3a11893bd831a72c936c05.zip
Diffstat (limited to 'src')
-rw-r--r--src/cz/crcs/ectester/applet/AppletBase.java36
-rw-r--r--src/cz/crcs/ectester/applet/ECKeyGenerator.java154
-rw-r--r--src/cz/crcs/ectester/applet/ECKeyTester.java63
-rw-r--r--src/cz/crcs/ectester/common/ec/EC_Category.java2
-rw-r--r--src/cz/crcs/ectester/reader/command/Command.java31
-rw-r--r--src/cz/crcs/ectester/reader/response/Response.java12
-rw-r--r--src/cz/crcs/ectester/reader/test/CardDefaultSuite.java6
-rw-r--r--src/cz/crcs/ectester/reader/test/PerformanceTest.java38
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;
}