diff options
| author | J08nY | 2017-11-10 22:18:07 +0100 |
|---|---|---|
| committer | J08nY | 2017-11-10 22:18:07 +0100 |
| commit | 84a3a55be957900e0417a5afa77b65bfa6d19270 (patch) | |
| tree | 0b2da8b46c78e4660dacc2e06a1c96929627d783 | |
| parent | 59a043192903918a68e8d9df629c09221a13c641 (diff) | |
| download | ECTester-84a3a55be957900e0417a5afa77b65bfa6d19270.tar.gz ECTester-84a3a55be957900e0417a5afa77b65bfa6d19270.tar.zst ECTester-84a3a55be957900e0417a5afa77b65bfa6d19270.zip | |
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 |
