aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cz/crcs/ectester/common/test/CompoundTest.java108
-rw-r--r--src/cz/crcs/ectester/common/test/Result.java (renamed from src/cz/crcs/ectester/reader/test/Result.java)4
-rw-r--r--src/cz/crcs/ectester/common/test/Test.java50
-rw-r--r--src/cz/crcs/ectester/common/test/TestException.java11
-rw-r--r--src/cz/crcs/ectester/common/test/Testable.java13
-rw-r--r--src/cz/crcs/ectester/reader/ECTesterReader.java9
-rw-r--r--src/cz/crcs/ectester/reader/output/TestWriter.java2
-rw-r--r--src/cz/crcs/ectester/reader/output/TextTestWriter.java10
-rw-r--r--src/cz/crcs/ectester/reader/output/XMLTestWriter.java12
-rw-r--r--src/cz/crcs/ectester/reader/output/YAMLTestWriter.java12
-rw-r--r--src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java12
-rw-r--r--src/cz/crcs/ectester/reader/test/DefaultSuite.java10
-rw-r--r--src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java16
-rw-r--r--src/cz/crcs/ectester/reader/test/SimpleTest.java71
-rw-r--r--src/cz/crcs/ectester/reader/test/Test.java217
-rw-r--r--src/cz/crcs/ectester/reader/test/TestRunner.java6
-rw-r--r--src/cz/crcs/ectester/reader/test/TestSuite.java33
-rw-r--r--src/cz/crcs/ectester/reader/test/TestVectorSuite.java21
-rw-r--r--src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java2
19 files changed, 336 insertions, 283 deletions
diff --git a/src/cz/crcs/ectester/common/test/CompoundTest.java b/src/cz/crcs/ectester/common/test/CompoundTest.java
new file mode 100644
index 0000000..bcf4a0e
--- /dev/null
+++ b/src/cz/crcs/ectester/common/test/CompoundTest.java
@@ -0,0 +1,108 @@
+package cz.crcs.ectester.common.test;
+
+import java.util.function.Function;
+
+/**
+ * A compound test that runs many Tests and has a Result dependent on all/some of their Results.
+ *
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public class CompoundTest extends Test {
+ private Function<Test[], Result> callback;
+ private Test[] tests;
+ private String description;
+
+ private CompoundTest(Function<Test[], Result> callback, Test... tests) {
+ this.callback = callback;
+ this.tests = tests;
+ }
+
+ private CompoundTest(Function<Test[], Result> callback, String descripiton, Test... tests) {
+ this(callback, tests);
+ this.description = descripiton;
+ }
+
+ public static CompoundTest function(Function<Test[], Result> callback, Test... tests) {
+ return new CompoundTest(callback, tests);
+ }
+
+ public static CompoundTest function(Function<Test[], Result> callback, String description, Test... tests) {
+ return new CompoundTest(callback, description, tests);
+ }
+
+ public static CompoundTest all(Result.ExpectedValue what, Test... all) {
+ return new CompoundTest((tests) -> {
+ for (Test test : tests) {
+ if (!Result.Value.fromExpected(what, test.ok()).ok()) {
+ return new Result(Result.Value.FAILURE, "At least one of the sub-tests did not have the expected result.");
+ }
+ }
+ return new Result(Result.Value.SUCCESS, "All sub-tests had the expected result.");
+ }, all);
+ }
+
+ public static CompoundTest all(Result.ExpectedValue what, String description, Test... all) {
+ CompoundTest result = CompoundTest.all(what, all);
+ result.setDescription(description);
+ return result;
+ }
+
+ public static CompoundTest any(Result.ExpectedValue what, Test... any) {
+ return new CompoundTest((tests) -> {
+ for (Test test : tests) {
+ if (Result.Value.fromExpected(what, test.ok()).ok()) {
+ return new Result(Result.Value.SUCCESS, "At least one of the sub-tests did have the expected result.");
+ }
+ }
+ return new Result(Result.Value.FAILURE, "None of the sub-tests had the expected result.");
+ }, any);
+ }
+
+ public static CompoundTest any(Result.ExpectedValue what, String description, Test... any) {
+ CompoundTest result = CompoundTest.any(what, any);
+ result.setDescription(description);
+ return result;
+ }
+
+ public static CompoundTest mask(Result.ExpectedValue[] results, Test... masked) {
+ return new CompoundTest((tests) -> {
+ for (int i = 0; i < results.length; ++i) {
+ if (!Result.Value.fromExpected(results[i], tests[i].ok()).ok()) {
+ return new Result(Result.Value.FAILURE, "At least one of the sub-tests did not match the result mask.");
+ }
+ }
+ return new Result(Result.Value.SUCCESS, "All sub-tests matched the expected mask.");
+ }, masked);
+ }
+
+ public static CompoundTest mask(Result.ExpectedValue[] results, String description, Test... masked) {
+ CompoundTest result = CompoundTest.mask(results, masked);
+ result.setDescription(description);
+ return result;
+ }
+
+ public Test[] getTests() {
+ return tests;
+ }
+
+ @Override
+ public void run() throws TestException {
+ if (hasRun)
+ return;
+
+ for (Test test : tests) {
+ test.run();
+ }
+ result = callback.apply(tests);
+ this.hasRun = true;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/src/cz/crcs/ectester/reader/test/Result.java b/src/cz/crcs/ectester/common/test/Result.java
index 82f0f32..523a9d7 100644
--- a/src/cz/crcs/ectester/reader/test/Result.java
+++ b/src/cz/crcs/ectester/common/test/Result.java
@@ -1,6 +1,8 @@
-package cz.crcs.ectester.reader.test;
+package cz.crcs.ectester.common.test;
/**
+ * A Result of a Test. Has a Value and an optional String cause.
+ *
* @author Jan Jancar johny@neuromancer.sk
*/
public class Result {
diff --git a/src/cz/crcs/ectester/common/test/Test.java b/src/cz/crcs/ectester/common/test/Test.java
new file mode 100644
index 0000000..8c025b8
--- /dev/null
+++ b/src/cz/crcs/ectester/common/test/Test.java
@@ -0,0 +1,50 @@
+package cz.crcs.ectester.common.test;
+
+import static cz.crcs.ectester.common.test.Result.Value;
+
+/**
+ * An abstract test that can be run and has a Result.
+ *
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public abstract class Test {
+ protected boolean hasRun = false;
+ protected Result result;
+
+ public Result getResult() {
+ if (!hasRun) {
+ return null;
+ }
+ return result;
+ }
+
+ public Value getResultValue() {
+ if (!hasRun) {
+ return null;
+ }
+ return result.getValue();
+ }
+
+ public String getResultCause() {
+ if (!hasRun) {
+ return null;
+ }
+ return result.getCause();
+ }
+
+ public boolean ok() {
+ if (!hasRun) {
+ return true;
+ }
+ return result.ok();
+ }
+
+ public abstract String getDescription();
+
+ public boolean hasRun() {
+ return hasRun;
+ }
+
+ public abstract void run() throws TestException;
+
+}
diff --git a/src/cz/crcs/ectester/common/test/TestException.java b/src/cz/crcs/ectester/common/test/TestException.java
new file mode 100644
index 0000000..01d195c
--- /dev/null
+++ b/src/cz/crcs/ectester/common/test/TestException.java
@@ -0,0 +1,11 @@
+package cz.crcs.ectester.common.test;
+
+/**
+ *
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public class TestException extends Exception {
+ public TestException(Throwable e) {
+ super(e);
+ }
+}
diff --git a/src/cz/crcs/ectester/common/test/Testable.java b/src/cz/crcs/ectester/common/test/Testable.java
new file mode 100644
index 0000000..e033b0a
--- /dev/null
+++ b/src/cz/crcs/ectester/common/test/Testable.java
@@ -0,0 +1,13 @@
+package cz.crcs.ectester.common.test;
+
+/**
+ *
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public interface Testable {
+
+ boolean hasRun();
+ void run() throws TestException;
+ boolean ok();
+ boolean error();
+}
diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java
index 4eadfd3..786ab05 100644
--- a/src/cz/crcs/ectester/reader/ECTesterReader.java
+++ b/src/cz/crcs/ectester/reader/ECTesterReader.java
@@ -23,11 +23,12 @@ package cz.crcs.ectester.reader;
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.command.Command;
import cz.crcs.ectester.common.ec.EC_Category;
import cz.crcs.ectester.common.ec.EC_Data;
import cz.crcs.ectester.common.ec.EC_Params;
+import cz.crcs.ectester.common.test.TestException;
+import cz.crcs.ectester.data.EC_Store;
+import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.reader.output.*;
import cz.crcs.ectester.reader.response.Response;
import cz.crcs.ectester.reader.test.*;
@@ -187,7 +188,7 @@ public class ECTesterReader {
System.err.println("File " + fnfe.getMessage() + " not found.");
} catch (ParseException | IOException ex) {
System.err.println(ex.getMessage());
- } catch (CardException ex) {
+ } catch (CardException | TestException ex) {
if (logger != null)
logger.println(ex.getMessage());
} catch (ParserConfigurationException e) {
@@ -436,7 +437,7 @@ public class ECTesterReader {
* @throws CardException if APDU transmission fails
* @throws IOException if an IO error occurs when writing to key file.
*/
- private void test() throws IOException, CardException {
+ private void test() throws IOException, TestException {
TestSuite suite;
switch (cfg.testSuite) {
diff --git a/src/cz/crcs/ectester/reader/output/TestWriter.java b/src/cz/crcs/ectester/reader/output/TestWriter.java
index 74c76fb..d79252d 100644
--- a/src/cz/crcs/ectester/reader/output/TestWriter.java
+++ b/src/cz/crcs/ectester/reader/output/TestWriter.java
@@ -1,6 +1,6 @@
package cz.crcs.ectester.reader.output;
-import cz.crcs.ectester.reader.test.Test;
+import cz.crcs.ectester.common.test.Test;
import cz.crcs.ectester.reader.test.TestSuite;
/**
diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java
index bcebcd5..07b2a2f 100644
--- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java
+++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java
@@ -1,6 +1,8 @@
package cz.crcs.ectester.reader.output;
-import cz.crcs.ectester.reader.test.Test;
+import cz.crcs.ectester.common.test.CompoundTest;
+import cz.crcs.ectester.common.test.Test;
+import cz.crcs.ectester.reader.test.SimpleTest;
import cz.crcs.ectester.reader.test.TestSuite;
import java.io.PrintStream;
@@ -31,8 +33,8 @@ public class TextTestWriter implements TestWriter {
}
StringBuilder out = new StringBuilder();
- if (t instanceof Test.Simple) {
- Test.Simple test = (Test.Simple) t;
+ if (t instanceof SimpleTest) {
+ SimpleTest test = (SimpleTest) t;
out.append(test.ok() ? "OK " : "NOK ");
out.append("━ ");
int width = BASE_WIDTH - (offset + out.length());
@@ -43,7 +45,7 @@ public class TextTestWriter implements TestWriter {
out.append(" ┃ ");
out.append(respWriter.responseSuffix(test.getResponse()));
} else {
- Test.Compound test = (Test.Compound) t;
+ CompoundTest test = (CompoundTest) t;
out.append(test.ok() ? "OK " : "NOK ");
out.append("┳ ");
int width = BASE_WIDTH - (offset + out.length());
diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java
index beb758c..f35e467 100644
--- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java
+++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java
@@ -1,9 +1,11 @@
package cz.crcs.ectester.reader.output;
+import cz.crcs.ectester.common.test.CompoundTest;
import cz.crcs.ectester.reader.Util;
import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.reader.response.Response;
-import cz.crcs.ectester.reader.test.Test;
+import cz.crcs.ectester.common.test.Test;
+import cz.crcs.ectester.reader.test.SimpleTest;
import cz.crcs.ectester.reader.test.TestSuite;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -89,13 +91,13 @@ public class XMLTestWriter implements TestWriter {
private Element testElement(Test t) {
Element testElem = doc.createElement("test");
- if (t instanceof Test.Simple) {
- Test.Simple test = (Test.Simple) t;
+ if (t instanceof SimpleTest) {
+ SimpleTest test = (SimpleTest) t;
testElem.setAttribute("type", "simple");
testElem.appendChild(commandElement(test.getCommand()));
testElem.appendChild(responseElement(test.getResponse()));
- } else if (t instanceof Test.Compound) {
- Test.Compound test = (Test.Compound) t;
+ } else if (t instanceof CompoundTest) {
+ CompoundTest test = (CompoundTest) t;
testElem.setAttribute("type", "compound");
for (Test innerTest : test.getTests()) {
testElem.appendChild(testElement(innerTest));
diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java
index 3b2b72d..15c0522 100644
--- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java
+++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java
@@ -1,9 +1,11 @@
package cz.crcs.ectester.reader.output;
+import cz.crcs.ectester.common.test.CompoundTest;
import cz.crcs.ectester.reader.Util;
import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.reader.response.Response;
-import cz.crcs.ectester.reader.test.Test;
+import cz.crcs.ectester.common.test.Test;
+import cz.crcs.ectester.reader.test.SimpleTest;
import cz.crcs.ectester.reader.test.TestSuite;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
@@ -64,13 +66,13 @@ public class YAMLTestWriter implements TestWriter {
private Map<String, Object> testObject(Test t) {
Map<String, Object> testObj = new HashMap<>();
- if (t instanceof Test.Simple) {
- Test.Simple test = (Test.Simple) t;
+ if (t instanceof SimpleTest) {
+ SimpleTest test = (SimpleTest) t;
testObj.put("type", "simple");
testObj.put("command", commandObject(test.getCommand()));
testObj.put("response", responseObject(test.getResponse()));
- } else if (t instanceof Test.Compound) {
- Test.Compound test = (Test.Compound) t;
+ } else if (t instanceof CompoundTest) {
+ CompoundTest test = (CompoundTest) t;
testObj.put("type", "compound");
List<Map<String, Object>> tests = new LinkedList<>();
for (Test innerTest : test.getTests()) {
diff --git a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java
index 9c8393d..2e711a2 100644
--- a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java
@@ -12,7 +12,7 @@ import javacard.security.KeyPair;
import java.util.Map;
-import static cz.crcs.ectester.reader.test.Result.ExpectedValue;
+import static cz.crcs.ectester.common.test.Result.ExpectedValue;
/**
* @author Jan Jancar johny@neuromancer.sk
@@ -41,12 +41,12 @@ public class CompositeCurvesSuite extends TestSuite {
continue;
}
if ((curve.getBits() == cfg.bits || cfg.all)) {
- tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
- tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY));
- tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY));
+ tests.add(new SimpleTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
+ tests.add(new SimpleTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY));
+ tests.add(new SimpleTest(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.ANY));
Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH, key.flatten());
- tests.add(new Test.Simple(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key."));
- tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY));
+ tests.add(new SimpleTest(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key."));
+ tests.add(new SimpleTest(new Command.Cleanup(cardManager), ExpectedValue.ANY));
}
}
}
diff --git a/src/cz/crcs/ectester/reader/test/DefaultSuite.java b/src/cz/crcs/ectester/reader/test/DefaultSuite.java
index b487a6e..fb8fdab 100644
--- a/src/cz/crcs/ectester/reader/test/DefaultSuite.java
+++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java
@@ -10,7 +10,7 @@ import javacard.security.KeyPair;
import java.io.IOException;
-import static cz.crcs.ectester.reader.test.Result.ExpectedValue;
+import static cz.crcs.ectester.common.test.Result.ExpectedValue;
/**
* @author Jan Jancar johny@neuromancer.sk
@@ -23,7 +23,7 @@ public class DefaultSuite extends TestSuite {
@Override
public void setup(CardMngr cardManager) throws IOException {
- tests.add(new Test.Simple(new Command.Support(cardManager), ExpectedValue.ANY));
+ tests.add(new SimpleTest(new Command.Support(cardManager), ExpectedValue.ANY));
if (cfg.namedCurve != null) {
String desc = "Default tests over the " + cfg.namedCurve + " curve category.";
if (cfg.primeField) {
@@ -59,11 +59,11 @@ public class DefaultSuite extends TestSuite {
}
private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException {
- tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), ExpectedValue.SUCCESS));
+ tests.add(new SimpleTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), ExpectedValue.SUCCESS));
Command curve = Command.prepareCurve(cardManager, dataStore, cfg, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType);
if (curve != null)
- tests.add(new Test.Simple(curve, ExpectedValue.SUCCESS));
+ tests.add(new SimpleTest(curve, ExpectedValue.SUCCESS));
tests.add(defaultCurveTests(cardManager, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, "Default tests."));
- tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY));
+ tests.add(new SimpleTest(new Command.Cleanup(cardManager), ExpectedValue.ANY));
}
}
diff --git a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java
index 3dcabb3..1f71ad5 100644
--- a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java
+++ b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java
@@ -2,6 +2,8 @@ package cz.crcs.ectester.reader.test;
import cz.crcs.ectester.applet.ECTesterApplet;
import cz.crcs.ectester.applet.EC_Consts;
+import cz.crcs.ectester.common.test.CompoundTest;
+import cz.crcs.ectester.common.test.Test;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.ECTesterReader;
@@ -16,7 +18,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import static cz.crcs.ectester.reader.test.Result.ExpectedValue;
+import static cz.crcs.ectester.common.test.Result.ExpectedValue;
/**
* @author Jan Jancar johny@neuromancer.sk
@@ -53,16 +55,16 @@ public class InvalidCurvesSuite extends TestSuite {
EC_Curve curve = e.getKey();
List<EC_Key.Public> keys = e.getValue();
- tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
- tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS));
- tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS));
+ tests.add(new SimpleTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
+ tests.add(new SimpleTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS));
+ tests.add(new SimpleTest(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS));
List<Test> ecdhTests = new LinkedList<>();
for (EC_Key.Public pub : keys) {
Command ecdhCommand = new Command.ECDH_direct(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ANY, pub.flatten());
- ecdhTests.add(new Test.Simple(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve."));
+ ecdhTests.add(new SimpleTest(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve."));
}
- tests.add(Test.Compound.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0])));
- tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY));
+ tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0])));
+ tests.add(new SimpleTest(new Command.Cleanup(cardManager), ExpectedValue.ANY));
}
}
}
diff --git a/src/cz/crcs/ectester/reader/test/SimpleTest.java b/src/cz/crcs/ectester/reader/test/SimpleTest.java
new file mode 100644
index 0000000..067f43e
--- /dev/null
+++ b/src/cz/crcs/ectester/reader/test/SimpleTest.java
@@ -0,0 +1,71 @@
+package cz.crcs.ectester.reader.test;
+
+import cz.crcs.ectester.common.test.Result;
+import cz.crcs.ectester.common.test.Test;
+import cz.crcs.ectester.common.test.TestException;
+import cz.crcs.ectester.reader.command.Command;
+import cz.crcs.ectester.reader.response.Response;
+
+import javax.smartcardio.CardException;
+import java.util.function.BiFunction;
+
+/**
+ * A simple test that runs one Command to get and evaluate one Response
+ * to get a Result and compare it with the expected one.
+ */
+public class SimpleTest extends Test {
+ private BiFunction<Command, Response, Result> callback;
+ private Command command;
+ private Response response;
+
+ public SimpleTest(Command command, BiFunction<Command, Response, Result> callback) {
+ this.command = command;
+ this.callback = callback;
+ }
+
+ public SimpleTest(Command command, Result.ExpectedValue expected, String ok, String nok) {
+ this(command, (cmd, resp) -> {
+ Result.Value resultValue = Result.Value.fromExpected(expected, resp.successful(), resp.error());
+ return new Result(resultValue, resultValue.ok() ? ok : nok);
+ });
+ }
+
+ public SimpleTest(Command command, Result.ExpectedValue expected) {
+ this(command, expected, null, null);
+ }
+
+ public Command getCommand() {
+ return command;
+ }
+
+ public Response getResponse() {
+ return response;
+ }
+
+ @Override
+ public void run() throws TestException {
+ if (hasRun)
+ return;
+
+ try {
+ response = command.send();
+ } catch (CardException e) {
+ throw new TestException(e);
+ }
+ if (callback != null) {
+ result = callback.apply(command, response);
+ } else {
+ if (response.successful()) {
+ result = new Result(Result.Value.SUCCESS);
+ } else {
+ result = new Result(Result.Value.FAILURE);
+ }
+ }
+ hasRun = true;
+ }
+
+ @Override
+ public String getDescription() {
+ return response.getDescription();
+ }
+}
diff --git a/src/cz/crcs/ectester/reader/test/Test.java b/src/cz/crcs/ectester/reader/test/Test.java
deleted file mode 100644
index 022ad56..0000000
--- a/src/cz/crcs/ectester/reader/test/Test.java
+++ /dev/null
@@ -1,217 +0,0 @@
-package cz.crcs.ectester.reader.test;
-
-import cz.crcs.ectester.reader.command.Command;
-import cz.crcs.ectester.reader.response.Response;
-
-import javax.smartcardio.CardException;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-
-import static cz.crcs.ectester.reader.test.Result.ExpectedValue;
-import static cz.crcs.ectester.reader.test.Result.Value;
-
-/**
- * An abstract test that can be run and has a Result.
- *
- * @author Jan Jancar johny@neuromancer.sk
- */
-public abstract class Test {
- boolean hasRun = false;
- Result result;
-
- public Result getResult() {
- if (!hasRun) {
- return null;
- }
- return result;
- }
-
- public Value getResultValue() {
- if (!hasRun) {
- return null;
- }
- return result.getValue();
- }
-
- public String getResultCause() {
- if (!hasRun) {
- return null;
- }
- return result.getCause();
- }
-
- public boolean ok() {
- if (!hasRun) {
- return true;
- }
- return result.ok();
- }
-
- public abstract String getDescription();
-
- public boolean hasRun() {
- return hasRun;
- }
-
- public abstract void run() throws CardException;
-
- /**
- * A simple test that runs one Command to get and evaluate one Response
- * to get a Result and compare it with the expected one.
- */
- public static class Simple extends Test {
- private BiFunction<Command, Response, Result> callback;
- private Command command;
- private Response response;
-
- public Simple(Command command, BiFunction<Command, Response, Result> callback) {
- this.command = command;
- this.callback = callback;
- }
-
- public Simple(Command command, ExpectedValue expected, String ok, String nok) {
- this(command, (cmd, resp) -> {
- Value resultValue = Value.fromExpected(expected, resp.successful(), resp.error());
- return new Result(resultValue, resultValue.ok() ? ok : nok);
- });
- }
-
- public Simple(Command command, ExpectedValue expected) {
- this(command, expected, null, null);
- }
-
- public Command getCommand() {
- return command;
- }
-
- public Response getResponse() {
- return response;
- }
-
- @Override
- public void run() throws CardException {
- if (hasRun)
- return;
-
- response = command.send();
- if (callback != null) {
- result = callback.apply(command, response);
- } else {
- if (response.successful()) {
- result = new Result(Value.SUCCESS);
- } else {
- result = new Result(Value.FAILURE);
- }
- }
- hasRun = true;
- }
-
- @Override
- public String getDescription() {
- return response.getDescription();
- }
- }
-
- /**
- * A compound test that runs many Tests and has a Result dependent on all/some of their Results.
- */
- public static class Compound extends Test {
- private Function<Test[], Result> callback;
- private Test[] tests;
- private String description;
-
- private Compound(Function<Test[], Result> callback, Test... tests) {
- this.callback = callback;
- this.tests = tests;
- }
-
- private Compound(Function<Test[], Result> callback, String descripiton, Test... tests) {
- this(callback, tests);
- this.description = descripiton;
- }
-
- public static Compound function(Function<Test[], Result> callback, Test... tests) {
- return new Compound(callback, tests);
- }
-
- public static Compound function(Function<Test[], Result> callback, String description, Test... tests) {
- return new Compound(callback, description, tests);
- }
-
- public static Compound all(ExpectedValue what, Test... all) {
- return new Compound((tests) -> {
- for (Test test : tests) {
- if (!Value.fromExpected(what, test.ok()).ok()) {
- return new Result(Value.FAILURE, "At least one of the sub-tests did not have the expected result.");
- }
- }
- return new Result(Value.SUCCESS, "All sub-tests had the expected result.");
- }, all);
- }
-
- public static Compound all(ExpectedValue what, String description, Test... all) {
- Compound result = Compound.all(what, all);
- result.setDescription(description);
- return result;
- }
-
- public static Compound any(ExpectedValue what, Test... any) {
- return new Compound((tests) -> {
- for (Test test : tests) {
- if (Value.fromExpected(what, test.ok()).ok()) {
- return new Result(Value.SUCCESS, "At least one of the sub-tests did have the expected result.");
- }
- }
- return new Result(Value.FAILURE, "None of the sub-tests had the expected result.");
- }, any);
- }
-
- public static Compound any(ExpectedValue what, String description, Test... any) {
- Compound result = Compound.any(what, any);
- result.setDescription(description);
- return result;
- }
-
- public static Compound mask(ExpectedValue[] results, Test... masked) {
- return new Compound((tests) -> {
- for (int i = 0; i < results.length; ++i) {
- if (!Value.fromExpected(results[i], tests[i].ok()).ok()) {
- return new Result(Value.FAILURE, "At least one of the sub-tests did not match the result mask.");
- }
- }
- return new Result(Value.SUCCESS, "All sub-tests matched the expected mask.");
- }, masked);
- }
-
- public static Compound mask(ExpectedValue[] results, String description, Test... masked) {
- Compound result = Compound.mask(results, masked);
- result.setDescription(description);
- return result;
- }
-
- public Test[] getTests() {
- return tests;
- }
-
- @Override
- public void run() throws CardException {
- if (hasRun)
- return;
-
- for (Test test : tests) {
- test.run();
- }
- result = callback.apply(tests);
- this.hasRun = true;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- @Override
- public String getDescription() {
- return description;
- }
- }
-}
diff --git a/src/cz/crcs/ectester/reader/test/TestRunner.java b/src/cz/crcs/ectester/reader/test/TestRunner.java
index baab6a8..dcc78db 100644
--- a/src/cz/crcs/ectester/reader/test/TestRunner.java
+++ b/src/cz/crcs/ectester/reader/test/TestRunner.java
@@ -1,9 +1,9 @@
package cz.crcs.ectester.reader.test;
+import cz.crcs.ectester.common.test.Test;
+import cz.crcs.ectester.common.test.TestException;
import cz.crcs.ectester.reader.output.TestWriter;
-import javax.smartcardio.CardException;
-
/**
* @author Jan Jancar johny@neuromancer.sk
*/
@@ -16,7 +16,7 @@ public class TestRunner {
this.writer = writer;
}
- public void run() throws CardException {
+ public void run() throws TestException {
writer.begin(suite);
for (Test t : suite.getTests()) {
if (!t.hasRun()) {
diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java
index 3b6af5a..dc8167b 100644
--- a/src/cz/crcs/ectester/reader/test/TestSuite.java
+++ b/src/cz/crcs/ectester/reader/test/TestSuite.java
@@ -2,11 +2,14 @@ package cz.crcs.ectester.reader.test;
import cz.crcs.ectester.applet.ECTesterApplet;
import cz.crcs.ectester.applet.EC_Consts;
+import cz.crcs.ectester.common.ec.EC_Curve;
+import cz.crcs.ectester.common.test.CompoundTest;
+import cz.crcs.ectester.common.test.Result;
+import cz.crcs.ectester.common.test.Test;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.ECTesterReader;
import cz.crcs.ectester.reader.command.Command;
-import cz.crcs.ectester.common.ec.EC_Curve;
import java.io.IOException;
import java.util.Collections;
@@ -15,8 +18,8 @@ import java.util.List;
import java.util.Map;
import java.util.function.Function;
-import static cz.crcs.ectester.reader.test.Result.ExpectedValue;
-import static cz.crcs.ectester.reader.test.Result.Value;
+import static cz.crcs.ectester.common.test.Result.ExpectedValue;
+import static cz.crcs.ectester.common.test.Result.Value;
/**
* @author Jan Jancar johny@neuromancer.sk
@@ -61,16 +64,16 @@ public abstract class TestSuite {
Test defaultCurveTests(CardMngr cardManager, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressExpected, ExpectedValue ecdsaExpected, String description) {
List<Test> tests = new LinkedList<>();
- tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected));
- tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected));
- tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected));
- tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), ExpectedValue.FAILURE));
- tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), ExpectedValue.FAILURE));
- tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), ExpectedValue.FAILURE));
- tests.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), ExpectedValue.FAILURE));
- tests.add(new Test.Simple(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected));
+ tests.add(new SimpleTest(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected));
+ tests.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected));
+ tests.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected));
+ tests.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ONE, EC_Consts.KA_ECDH), ExpectedValue.FAILURE));
+ tests.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_ZERO, EC_Consts.KA_ECDH), ExpectedValue.FAILURE));
+ tests.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_MAX, EC_Consts.KA_ECDH), ExpectedValue.FAILURE));
+ tests.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_FULLRANDOM, EC_Consts.KA_ECDH), ExpectedValue.FAILURE));
+ tests.add(new SimpleTest(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected));
- return Test.Compound.function((testArray) -> {
+ return CompoundTest.function((testArray) -> {
Function<ExpectedValue, String> shouldHave = (expected) -> {
switch (expected) {
case SUCCESS:
@@ -123,10 +126,10 @@ public abstract class TestSuite {
for (Map.Entry<String, EC_Curve> entry : curves.entrySet()) {
EC_Curve curve = entry.getValue();
if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) {
- tests.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS));
- tests.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected));
+ tests.add(new SimpleTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS));
+ tests.add(new SimpleTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), setExpected));
tests.add(defaultCurveTests(cardManager, generateExpected, ecdhExpected, ecdhCompressedExpected, ecdsaExpected, description));
- tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY));
+ tests.add(new SimpleTest(new Command.Cleanup(cardManager), ExpectedValue.ANY));
}
}
diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java
index 6a3121b..742661d 100644
--- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java
+++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java
@@ -2,6 +2,9 @@ package cz.crcs.ectester.reader.test;
import cz.crcs.ectester.applet.ECTesterApplet;
import cz.crcs.ectester.applet.EC_Consts;
+import cz.crcs.ectester.common.test.CompoundTest;
+import cz.crcs.ectester.common.test.Result;
+import cz.crcs.ectester.common.test.Test;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.ECTesterReader;
@@ -16,8 +19,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import static cz.crcs.ectester.reader.test.Result.ExpectedValue;
-import static cz.crcs.ectester.reader.test.Result.Value;
+import static cz.crcs.ectester.common.test.Result.ExpectedValue;
+import static cz.crcs.ectester.common.test.Result.Value;
/**
* @author Jan Jancar johny@neuromancer.sk
@@ -58,12 +61,12 @@ public class TestVectorSuite extends TestSuite {
}
List<Test> testVector = new LinkedList<>();
- testVector.add(new Test.Simple(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
- testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS));
+ testVector.add(new SimpleTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
+ testVector.add(new SimpleTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS));
//tests.add(new Test.Simple(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.SUCCESS));
- testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS));
- testVector.add(new Test.Simple(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS));
- testVector.add(new Test.Simple(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), (command, response) -> {
+ testVector.add(new SimpleTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS));
+ testVector.add(new SimpleTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS));
+ testVector.add(new SimpleTest(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), (command, response) -> {
Response.ECDH dh = (Response.ECDH) response;
if (!dh.successful())
return new Result(Value.FAILURE, "ECDH was unsuccessful.");
@@ -75,8 +78,8 @@ public class TestVectorSuite extends TestSuite {
}
return new Result(Value.SUCCESS);
}));
- tests.add(Test.Compound.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0])));
- tests.add(new Test.Simple(new Command.Cleanup(cardManager), ExpectedValue.ANY));
+ tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0])));
+ tests.add(new SimpleTest(new Command.Cleanup(cardManager), ExpectedValue.ANY));
}
}
diff --git a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java
index 09f10d3..76da718 100644
--- a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java
+++ b/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java
@@ -7,7 +7,7 @@ import javacard.security.KeyPair;
import java.io.IOException;
-import static cz.crcs.ectester.reader.test.Result.ExpectedValue;
+import static cz.crcs.ectester.common.test.Result.ExpectedValue;
/**
* @author Jan Jancar johny@neuromancer.sk