From 84a3a55be957900e0417a5afa77b65bfa6d19270 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 10 Nov 2017 22:18:07 +0100 Subject: Split test package into common. --- src/cz/crcs/ectester/reader/output/TextTestWriter.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/cz/crcs/ectester/reader/output/TextTestWriter.java') 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()); -- cgit v1.2.3-70-g09d2 From cccf2c9c382fa63c68a6c3821d587bc2caa72b05 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 13 Nov 2017 18:03:00 +0100 Subject: Add KeyAgreement/KeyGeneration/Signature tests. Implement KeyAgreementTest. --- src/cz/crcs/ectester/common/test/TestCallback.java | 11 +++ .../ectester/reader/output/TextTestWriter.java | 6 +- .../crcs/ectester/reader/output/XMLTestWriter.java | 6 +- .../ectester/reader/output/YAMLTestWriter.java | 6 +- src/cz/crcs/ectester/reader/test/CommandTest.java | 71 +++++++++++++++++++ .../ectester/reader/test/CompositeCurvesSuite.java | 10 +-- src/cz/crcs/ectester/reader/test/DefaultSuite.java | 8 +-- .../ectester/reader/test/InvalidCurvesSuite.java | 10 +-- src/cz/crcs/ectester/reader/test/SimpleTest.java | 71 ------------------- src/cz/crcs/ectester/reader/test/TestSuite.java | 22 +++--- .../crcs/ectester/reader/test/TestVectorSuite.java | 12 ++-- src/cz/crcs/ectester/standalone/consts/Ident.java | 13 +++- .../standalone/consts/KeyAgreementIdent.java | 11 ++- .../ectester/standalone/consts/SignatureIdent.java | 11 ++- .../ectester/standalone/test/KeyAgreementTest.java | 55 +++++++++++++++ .../standalone/test/KeyAgreementTestable.java | 80 ++++++++++++++++++++++ .../standalone/test/KeyGenerationTest.java | 19 +++++ .../ectester/standalone/test/SignatureTest.java | 19 +++++ 18 files changed, 323 insertions(+), 118 deletions(-) create mode 100644 src/cz/crcs/ectester/common/test/TestCallback.java create mode 100644 src/cz/crcs/ectester/reader/test/CommandTest.java delete mode 100644 src/cz/crcs/ectester/reader/test/SimpleTest.java create mode 100644 src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java create mode 100644 src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java create mode 100644 src/cz/crcs/ectester/standalone/test/KeyGenerationTest.java create mode 100644 src/cz/crcs/ectester/standalone/test/SignatureTest.java (limited to 'src/cz/crcs/ectester/reader/output/TextTestWriter.java') diff --git a/src/cz/crcs/ectester/common/test/TestCallback.java b/src/cz/crcs/ectester/common/test/TestCallback.java new file mode 100644 index 0000000..488e2f2 --- /dev/null +++ b/src/cz/crcs/ectester/common/test/TestCallback.java @@ -0,0 +1,11 @@ +package cz.crcs.ectester.common.test; + +import java.util.function.Function; + +/** + * + * @param + */ +public abstract class TestCallback implements Function { + +} diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index 07b2a2f..dc285b5 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -2,7 +2,7 @@ package cz.crcs.ectester.reader.output; 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.CommandTest; import cz.crcs.ectester.reader.test.TestSuite; import java.io.PrintStream; @@ -33,8 +33,8 @@ public class TextTestWriter implements TestWriter { } StringBuilder out = new StringBuilder(); - if (t instanceof SimpleTest) { - SimpleTest test = (SimpleTest) t; + if (t instanceof CommandTest) { + CommandTest test = (CommandTest) 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 24a308c..0a5155b 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -5,7 +5,7 @@ import cz.crcs.ectester.common.Util; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.reader.test.SimpleTest; +import cz.crcs.ectester.reader.test.CommandTest; import cz.crcs.ectester.reader.test.TestSuite; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -91,8 +91,8 @@ public class XMLTestWriter implements TestWriter { private Element testElement(Test t) { Element testElem = doc.createElement("test"); - if (t instanceof SimpleTest) { - SimpleTest test = (SimpleTest) t; + if (t instanceof CommandTest) { + CommandTest test = (CommandTest) t; testElem.setAttribute("type", "simple"); testElem.appendChild(commandElement(test.getCommand())); testElem.appendChild(responseElement(test.getResponse())); diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index c637a13..84f1eac 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -5,7 +5,7 @@ import cz.crcs.ectester.common.Util; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.reader.test.SimpleTest; +import cz.crcs.ectester.reader.test.CommandTest; import cz.crcs.ectester.reader.test.TestSuite; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; @@ -66,8 +66,8 @@ public class YAMLTestWriter implements TestWriter { private Map testObject(Test t) { Map testObj = new HashMap<>(); - if (t instanceof SimpleTest) { - SimpleTest test = (SimpleTest) t; + if (t instanceof CommandTest) { + CommandTest test = (CommandTest) t; testObj.put("type", "simple"); testObj.put("command", commandObject(test.getCommand())); testObj.put("response", responseObject(test.getResponse())); diff --git a/src/cz/crcs/ectester/reader/test/CommandTest.java b/src/cz/crcs/ectester/reader/test/CommandTest.java new file mode 100644 index 0000000..b7728b6 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CommandTest.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 CommandTest extends Test { + private BiFunction callback; + private Command command; + private Response response; + + public CommandTest(Command command, BiFunction callback) { + this.command = command; + this.callback = callback; + } + + public CommandTest(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 CommandTest(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/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java index 2e711a2..77df7d6 100644 --- a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java @@ -41,12 +41,12 @@ public class CompositeCurvesSuite extends TestSuite { continue; } if ((curve.getBits() == cfg.bits || cfg.all)) { - 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)); + tests.add(new CommandTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + tests.add(new CommandTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); + tests.add(new CommandTest(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 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)); + tests.add(new CommandTest(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 CommandTest(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 fb8fdab..0e25312 100644 --- a/src/cz/crcs/ectester/reader/test/DefaultSuite.java +++ b/src/cz/crcs/ectester/reader/test/DefaultSuite.java @@ -23,7 +23,7 @@ public class DefaultSuite extends TestSuite { @Override public void setup(CardMngr cardManager) throws IOException { - tests.add(new SimpleTest(new Command.Support(cardManager), ExpectedValue.ANY)); + tests.add(new CommandTest(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 SimpleTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, keyType), ExpectedValue.SUCCESS)); + tests.add(new CommandTest(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 SimpleTest(curve, ExpectedValue.SUCCESS)); + tests.add(new CommandTest(curve, ExpectedValue.SUCCESS)); tests.add(defaultCurveTests(cardManager, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, "Default tests.")); - tests.add(new SimpleTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + tests.add(new CommandTest(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 1f71ad5..e4afb5d 100644 --- a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java +++ b/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java @@ -55,16 +55,16 @@ public class InvalidCurvesSuite extends TestSuite { EC_Curve curve = e.getKey(); List keys = e.getValue(); - 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)); + tests.add(new CommandTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + tests.add(new CommandTest(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + tests.add(new CommandTest(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); List 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 SimpleTest(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); + ecdhTests.add(new CommandTest(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); } 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)); + tests.add(new CommandTest(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 deleted file mode 100644 index 067f43e..0000000 --- a/src/cz/crcs/ectester/reader/test/SimpleTest.java +++ /dev/null @@ -1,71 +0,0 @@ -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 callback; - private Command command; - private Response response; - - public SimpleTest(Command command, BiFunction 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/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java index dc8167b..034f579 100644 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestSuite.java @@ -64,14 +64,14 @@ public abstract class TestSuite { Test defaultCurveTests(CardMngr cardManager, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressExpected, ExpectedValue ecdsaExpected, String description) { List tests = new LinkedList<>(); - 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)); + tests.add(new CommandTest(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); + tests.add(new CommandTest(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 CommandTest(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 CommandTest(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 CommandTest(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 CommandTest(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 CommandTest(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 CommandTest(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); return CompoundTest.function((testArray) -> { Function shouldHave = (expected) -> { @@ -126,10 +126,10 @@ public abstract class TestSuite { for (Map.Entry entry : curves.entrySet()) { EC_Curve curve = entry.getValue(); if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { - 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(new CommandTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS)); + tests.add(new CommandTest(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 SimpleTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + tests.add(new CommandTest(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 3f11a79..77653d1 100644 --- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java +++ b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java @@ -61,12 +61,12 @@ public class TestVectorSuite extends TestSuite { } List testVector = new LinkedList<>(); - 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)); + testVector.add(new CommandTest(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + testVector.add(new CommandTest(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 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) -> { + testVector.add(new CommandTest(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 CommandTest(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 CommandTest(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."); @@ -79,7 +79,7 @@ public class TestVectorSuite extends TestSuite { return new Result(Value.SUCCESS); })); 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)); + tests.add(new CommandTest(new Command.Cleanup(cardManager), ExpectedValue.ANY)); } } diff --git a/src/cz/crcs/ectester/standalone/consts/Ident.java b/src/cz/crcs/ectester/standalone/consts/Ident.java index 3228c37..eaea0e3 100644 --- a/src/cz/crcs/ectester/standalone/consts/Ident.java +++ b/src/cz/crcs/ectester/standalone/consts/Ident.java @@ -6,11 +6,18 @@ import java.util.Set; import java.util.TreeSet; public abstract class Ident { - private Set idents; + Set idents; + String name; - public Ident(String... names) { + public Ident(String name, String... aliases) { + this.name = name; this.idents = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - this.idents.addAll(Arrays.asList(names)); + this.idents.add(name); + this.idents.addAll(Arrays.asList(aliases)); + } + + public String getName() { + return name; } public Set getIdents() { diff --git a/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java b/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java index 9dc9797..22b03a4 100644 --- a/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java +++ b/src/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java @@ -1,5 +1,8 @@ package cz.crcs.ectester.standalone.consts; +import javax.crypto.KeyAgreement; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; import java.util.LinkedList; import java.util.List; @@ -47,7 +50,11 @@ public class KeyAgreementIdent extends Ident { return null; } - private KeyAgreementIdent(String... names) { - super(names); + private KeyAgreementIdent(String name, String... aliases) { + super(name, aliases); + } + + public KeyAgreement getInstance(Provider provider) throws NoSuchAlgorithmException { + return KeyAgreement.getInstance(name, provider); } } diff --git a/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java b/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java index b41e9e4..dc554e2 100644 --- a/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java +++ b/src/cz/crcs/ectester/standalone/consts/SignatureIdent.java @@ -1,5 +1,8 @@ package cz.crcs.ectester.standalone.consts; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Signature; import java.util.LinkedList; import java.util.List; @@ -71,7 +74,11 @@ public class SignatureIdent extends Ident { return null; } - private SignatureIdent(String... names) { - super(names); + private SignatureIdent(String name, String... aliases) { + super(name, aliases); + } + + public Signature getInstance(Provider provider) throws NoSuchAlgorithmException { + return Signature.getInstance(name, provider); } } diff --git a/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java b/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java new file mode 100644 index 0000000..9c761fa --- /dev/null +++ b/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java @@ -0,0 +1,55 @@ +package cz.crcs.ectester.standalone.test; + +import cz.crcs.ectester.common.test.Result; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestCallback; +import cz.crcs.ectester.common.test.TestException; + +import java.util.Arrays; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class KeyAgreementTest extends Test { + private KeyAgreementTestable ka; + private TestCallback callback; + + private KeyAgreementTest(KeyAgreementTestable ka, TestCallback callback) { + this.ka = ka; + this.callback = callback; + } + + public static KeyAgreementTest match(KeyAgreementTestable ka, byte[] expectedSecret) { + return new KeyAgreementTest(ka, new TestCallback() { + @Override + public Result apply(KeyAgreementTestable ka) { + if (Arrays.equals(ka.getSecret(), expectedSecret)) { + return new Result(Result.Value.SUCCESS); + } else { + return new Result(Result.Value.FAILURE); + } + } + }); + } + + public static KeyAgreementTest expect(KeyAgreementTestable ka, Result.ExpectedValue expected) { + return new KeyAgreementTest(ka, new TestCallback() { + @Override + public Result apply(KeyAgreementTestable keyAgreementTestable) { + return new Result(Result.Value.fromExpected(expected, keyAgreementTestable.ok(), keyAgreementTestable.error())); + } + }); + } + + @Override + public String getDescription() { + return null; + } + + @Override + public void run() throws TestException { + ka.run(); + result = callback.apply(ka); + hasRun = true; + } +} diff --git a/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java b/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java new file mode 100644 index 0000000..51c295c --- /dev/null +++ b/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java @@ -0,0 +1,80 @@ +package cz.crcs.ectester.standalone.test; + +import cz.crcs.ectester.common.test.TestException; +import cz.crcs.ectester.common.test.Testable; + +import javax.crypto.KeyAgreement; +import java.security.InvalidKeyException; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class KeyAgreementTestable implements Testable { + private KeyAgreement ka; + private ECPrivateKey privateKey; + private ECPublicKey publicKey; + private byte[] secret; + private boolean hasRun; + private boolean error; + private boolean ok; + + public KeyAgreementTestable(KeyAgreement ka, ECPrivateKey privateKey, ECPublicKey publicKey) { + this.ka = ka; + this.privateKey = privateKey; + this.publicKey = publicKey; + } + + public byte[] getSecret() { + if (!hasRun) { + return null; + } + return secret; + } + + @Override + public boolean hasRun() { + return hasRun; + } + + @Override + public void run() throws TestException { + try { + ka.init(privateKey); + } catch (InvalidKeyException ikex) { + throw new TestException(ikex); + } + + try { + ka.doPhase(publicKey, true); + } catch (InvalidKeyException ikex) { + throw new TestException(ikex); + } catch (IllegalStateException isex) { + error = true; + ok = false; + hasRun = true; + return; + } + + try { + secret = ka.generateSecret(); + } catch (IllegalStateException isex) { + error = true; + ok = false; + hasRun = true; + return; + } + ok = true; + } + + @Override + public boolean ok() { + return ok; + } + + @Override + public boolean error() { + return error; + } +} diff --git a/src/cz/crcs/ectester/standalone/test/KeyGenerationTest.java b/src/cz/crcs/ectester/standalone/test/KeyGenerationTest.java new file mode 100644 index 0000000..7a96ba1 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/test/KeyGenerationTest.java @@ -0,0 +1,19 @@ +package cz.crcs.ectester.standalone.test; + +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestException; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class KeyGenerationTest extends Test { + @Override + public String getDescription() { + return null; + } + + @Override + public void run() throws TestException { + + } +} diff --git a/src/cz/crcs/ectester/standalone/test/SignatureTest.java b/src/cz/crcs/ectester/standalone/test/SignatureTest.java new file mode 100644 index 0000000..2102db0 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/test/SignatureTest.java @@ -0,0 +1,19 @@ +package cz.crcs.ectester.standalone.test; + +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestException; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class SignatureTest extends Test { + @Override + public String getDescription() { + return null; + } + + @Override + public void run() throws TestException { + + } +} -- cgit v1.2.3-70-g09d2 From da09715d9ec955b4b139b45a1b2c5270ca0ebf2d Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 3 Dec 2017 20:59:41 +0100 Subject: Introduce BaseTestable and Testable Metadata. --- src/cz/crcs/ectester/common/output/TestWriter.java | 15 +++++++ .../ectester/common/output/TestableWriter.java | 39 ++++++++++++++++++ src/cz/crcs/ectester/common/test/BaseTestable.java | 35 ++++++++++++++++ src/cz/crcs/ectester/common/test/Test.java | 18 +++++++-- src/cz/crcs/ectester/common/test/Testable.java | 23 +++++++++++ src/cz/crcs/ectester/reader/ECTesterReader.java | 1 + src/cz/crcs/ectester/reader/output/TestWriter.java | 15 ------- .../ectester/reader/output/TextTestWriter.java | 1 + .../crcs/ectester/reader/output/XMLTestWriter.java | 1 + .../ectester/reader/output/YAMLTestWriter.java | 1 + src/cz/crcs/ectester/reader/response/Response.java | 5 ++- .../crcs/ectester/reader/test/CommandTestable.java | 47 ++++++++++++++++++++++ src/cz/crcs/ectester/reader/test/TestRunner.java | 2 +- .../standalone/libs/jni/NativeSignatureSpi.java | 2 + .../standalone/test/KeyAgreementTestable.java | 21 +--------- .../standalone/test/KeyGenerationTestable.java | 23 +---------- .../standalone/test/SignatureTestable.java | 23 +---------- 17 files changed, 191 insertions(+), 81 deletions(-) create mode 100644 src/cz/crcs/ectester/common/output/TestWriter.java create mode 100644 src/cz/crcs/ectester/common/output/TestableWriter.java create mode 100644 src/cz/crcs/ectester/common/test/BaseTestable.java delete mode 100644 src/cz/crcs/ectester/reader/output/TestWriter.java create mode 100644 src/cz/crcs/ectester/reader/test/CommandTestable.java (limited to 'src/cz/crcs/ectester/reader/output/TextTestWriter.java') diff --git a/src/cz/crcs/ectester/common/output/TestWriter.java b/src/cz/crcs/ectester/common/output/TestWriter.java new file mode 100644 index 0000000..0f3c4e6 --- /dev/null +++ b/src/cz/crcs/ectester/common/output/TestWriter.java @@ -0,0 +1,15 @@ +package cz.crcs.ectester.common.output; + +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.reader.test.TestSuite; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public interface TestWriter { + void begin(TestSuite suite); + + void outputTest(Test t); + + void end(); +} diff --git a/src/cz/crcs/ectester/common/output/TestableWriter.java b/src/cz/crcs/ectester/common/output/TestableWriter.java new file mode 100644 index 0000000..2097254 --- /dev/null +++ b/src/cz/crcs/ectester/common/output/TestableWriter.java @@ -0,0 +1,39 @@ +package cz.crcs.ectester.common.output; + +import cz.crcs.ectester.common.test.BaseTestable; +import cz.crcs.ectester.common.test.Testable; + +import java.io.OutputStream; +import java.io.PrintStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TestableWriter { + private PrintStream output; + + public TestableWriter(PrintStream output) { + this.output = output; + } + + public TestableWriter(OutputStream output) { + this(new PrintStream(output)); + } + + + public String outputTestableMeta(BaseTestable t) { + return null; + } + + public void writeTestableMeta(BaseTestable t) { + + } + + public String outputTestable(BaseTestable t) { + return null; + } + + public void writeTestable(BaseTestable t) { + + } +} diff --git a/src/cz/crcs/ectester/common/test/BaseTestable.java b/src/cz/crcs/ectester/common/test/BaseTestable.java new file mode 100644 index 0000000..6a63b13 --- /dev/null +++ b/src/cz/crcs/ectester/common/test/BaseTestable.java @@ -0,0 +1,35 @@ +package cz.crcs.ectester.common.test; + +import java.util.Collections; +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class BaseTestable implements Testable { + protected boolean hasRun; + protected boolean ok; + protected boolean error; + + protected Map meta; + + @Override + public boolean hasRun() { + return hasRun; + } + + @Override + public boolean ok() { + return ok; + } + + @Override + public boolean error() { + return error; + } + + @Override + public Map meta() { + return Collections.unmodifiableMap(meta); + } +} diff --git a/src/cz/crcs/ectester/common/test/Test.java b/src/cz/crcs/ectester/common/test/Test.java index 750a410..5f55337 100644 --- a/src/cz/crcs/ectester/common/test/Test.java +++ b/src/cz/crcs/ectester/common/test/Test.java @@ -1,5 +1,8 @@ package cz.crcs.ectester.common.test; +import java.util.Collections; +import java.util.Map; + import static cz.crcs.ectester.common.test.Result.Value; /** @@ -8,8 +11,9 @@ import static cz.crcs.ectester.common.test.Result.Value; * @author Jan Jancar johny@neuromancer.sk */ public abstract class Test implements Testable { - protected boolean hasRun = false; + protected boolean hasRun; protected Result result; + protected Map meta; public Result getResult() { if (!hasRun) { @@ -39,6 +43,7 @@ public abstract class Test implements Testable { return result.ok(); } + @Override public boolean error() { if (!hasRun) { return false; @@ -46,12 +51,19 @@ public abstract class Test implements Testable { return result.compareTo(Value.ERROR); } - public abstract String getDescription(); - + @Override public boolean hasRun() { return hasRun; } + @Override + public Map meta() { + return Collections.unmodifiableMap(meta); + } + + public abstract String getDescription(); + + @Override public abstract void run() throws TestException; } diff --git a/src/cz/crcs/ectester/common/test/Testable.java b/src/cz/crcs/ectester/common/test/Testable.java index d05d31e..e8eb321 100644 --- a/src/cz/crcs/ectester/common/test/Testable.java +++ b/src/cz/crcs/ectester/common/test/Testable.java @@ -1,15 +1,38 @@ package cz.crcs.ectester.common.test; +import java.util.Map; + /** * @author Jan Jancar johny@neuromancer.sk */ public interface Testable { + /** + * @return Whether this testable was run. + */ boolean hasRun(); + /** + * Run this Testable. + * + * @throws TestException + */ void run() throws TestException; + /** + * @return Whether this Testable was OK. + */ boolean ok(); + /** + * @return Whether an error happened. + */ boolean error(); + + /** + * Get the metadata of this Testable. + * + * @return The metadata of the testable. + */ + Map meta(); } diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index d32d9d8..e627099 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -26,6 +26,7 @@ import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.cli.CLITools; import cz.crcs.ectester.common.ec.EC_Params; import cz.crcs.ectester.common.output.OutputLogger; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.TestException; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.data.EC_Store; diff --git a/src/cz/crcs/ectester/reader/output/TestWriter.java b/src/cz/crcs/ectester/reader/output/TestWriter.java deleted file mode 100644 index d79252d..0000000 --- a/src/cz/crcs/ectester/reader/output/TestWriter.java +++ /dev/null @@ -1,15 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.reader.test.TestSuite; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public interface TestWriter { - void begin(TestSuite suite); - - void outputTest(Test t); - - void end(); -} diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index dc285b5..a4bb33e 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.reader.output; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.test.Test; import cz.crcs.ectester.reader.test.CommandTest; diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index ebc93ac..1a94984 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.reader.output; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.reader.command.Command; diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index d8350ac..e0038fd 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.reader.output; +import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.reader.command.Command; diff --git a/src/cz/crcs/ectester/reader/response/Response.java b/src/cz/crcs/ectester/reader/response/Response.java index d8edf9e..3b5d98b 100644 --- a/src/cz/crcs/ectester/reader/response/Response.java +++ b/src/cz/crcs/ectester/reader/response/Response.java @@ -13,7 +13,6 @@ import javax.smartcardio.ResponseAPDU; * @author Jan Jancar johny@neuromancer.sk */ public abstract class Response { - private ResponseAPDU resp; private long time; private short[] sws; @@ -88,6 +87,10 @@ public abstract class Response { return (short) resp.getSW(); } + public short[] getSWs() { + return sws; + } + public short getSW(int index) { return sws[index]; } diff --git a/src/cz/crcs/ectester/reader/test/CommandTestable.java b/src/cz/crcs/ectester/reader/test/CommandTestable.java new file mode 100644 index 0000000..f09a736 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CommandTestable.java @@ -0,0 +1,47 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.common.test.BaseTestable; +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; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CommandTestable extends BaseTestable { + private Command command; + private Response response; + + public CommandTestable(Command command) { + this.command = command; + } + + public Command getCommand() { + return command; + } + + public Response getResponse() { + return response; + } + + @Override + public void run() throws TestException { + try { + response = command.send(); + } catch (CardException e) { + throw new TestException(e); + } + + hasRun = true; + if (response.error()) { + error = true; + } else if (response.successful()) { + ok = true; + } + meta.clear(); + meta.put("Natural SW", response.getNaturalSW()); + meta.put("SWs", response.getSWs()); + } +} diff --git a/src/cz/crcs/ectester/reader/test/TestRunner.java b/src/cz/crcs/ectester/reader/test/TestRunner.java index dcc78db..e581aaa 100644 --- a/src/cz/crcs/ectester/reader/test/TestRunner.java +++ b/src/cz/crcs/ectester/reader/test/TestRunner.java @@ -2,7 +2,7 @@ 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 cz.crcs.ectester.common.output.TestWriter; /** * @author Jan Jancar johny@neuromancer.sk diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java index a9ec8a6..76f01f0 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java +++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java @@ -61,11 +61,13 @@ public abstract class NativeSignatureSpi extends SignatureSpi { } @Override + @Deprecated protected void engineSetParameter(String param, Object value) throws InvalidParameterException { throw new UnsupportedOperationException("setParameter() not supported"); } @Override + @Deprecated protected Object engineGetParameter(String param) throws InvalidParameterException { throw new UnsupportedOperationException("getParameter() not supported"); } diff --git a/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java b/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java index ef363c3..fedf519 100644 --- a/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java +++ b/src/cz/crcs/ectester/standalone/test/KeyAgreementTestable.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.standalone.test; +import cz.crcs.ectester.common.test.BaseTestable; import cz.crcs.ectester.common.test.TestException; import cz.crcs.ectester.common.test.Testable; @@ -11,14 +12,11 @@ import java.security.interfaces.ECPublicKey; /** * @author Jan Jancar johny@neuromancer.sk */ -public class KeyAgreementTestable implements Testable { +public class KeyAgreementTestable extends BaseTestable { private KeyAgreement ka; private ECPrivateKey privateKey; private ECPublicKey publicKey; private byte[] secret; - private boolean hasRun; - private boolean error = false; - private boolean ok; public KeyAgreementTestable(KeyAgreement ka, ECPrivateKey privateKey, ECPublicKey publicKey) { this.ka = ka; @@ -33,11 +31,6 @@ public class KeyAgreementTestable implements Testable { return secret; } - @Override - public boolean hasRun() { - return hasRun; - } - @Override public void run() throws TestException { try { @@ -66,14 +59,4 @@ public class KeyAgreementTestable implements Testable { ok = true; hasRun = true; } - - @Override - public boolean ok() { - return ok; - } - - @Override - public boolean error() { - return error; - } } diff --git a/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java b/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java index 381ce70..5a891b7 100644 --- a/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java +++ b/src/cz/crcs/ectester/standalone/test/KeyGenerationTestable.java @@ -1,22 +1,18 @@ package cz.crcs.ectester.standalone.test; +import cz.crcs.ectester.common.test.BaseTestable; import cz.crcs.ectester.common.test.TestException; -import cz.crcs.ectester.common.test.Testable; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.spec.ECParameterSpec; -public class KeyGenerationTestable implements Testable { - +public class KeyGenerationTestable extends BaseTestable { private KeyPair kp; private KeyPairGenerator kpg; private int keysize = 0; private ECParameterSpec spec = null; - private boolean hasRun; - private boolean error = false; - private boolean ok; public KeyGenerationTestable(KeyPairGenerator kpg) { this.kpg = kpg; @@ -36,11 +32,6 @@ public class KeyGenerationTestable implements Testable { return kp; } - @Override - public boolean hasRun() { - return hasRun; - } - @Override public void run() throws TestException { try { @@ -58,14 +49,4 @@ public class KeyGenerationTestable implements Testable { hasRun = true; ok = true; } - - @Override - public boolean ok() { - return ok; - } - - @Override - public boolean error() { - return error; - } } diff --git a/src/cz/crcs/ectester/standalone/test/SignatureTestable.java b/src/cz/crcs/ectester/standalone/test/SignatureTestable.java index 5f58b4a..8b6815b 100644 --- a/src/cz/crcs/ectester/standalone/test/SignatureTestable.java +++ b/src/cz/crcs/ectester/standalone/test/SignatureTestable.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.standalone.test; +import cz.crcs.ectester.common.test.BaseTestable; import cz.crcs.ectester.common.test.TestException; import cz.crcs.ectester.common.test.Testable; @@ -9,8 +10,7 @@ import java.security.SignatureException; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; -public class SignatureTestable implements Testable { - +public class SignatureTestable extends BaseTestable { private Signature sig; private ECPrivateKey signKey; private ECPublicKey verifyKey; @@ -18,10 +18,6 @@ public class SignatureTestable implements Testable { private byte[] signature; private boolean verified; - private boolean hasRun; - private boolean error; - private boolean ok; - public SignatureTestable(Signature sig, ECPrivateKey signKey, ECPublicKey verifyKey, byte[] data) { this.sig = sig; this.signKey = signKey; @@ -37,11 +33,6 @@ public class SignatureTestable implements Testable { return verified; } - @Override - public boolean hasRun() { - return hasRun; - } - @Override public void run() throws TestException { try { @@ -89,14 +80,4 @@ public class SignatureTestable implements Testable { ok = true; hasRun = true; } - - @Override - public boolean ok() { - return ok; - } - - @Override - public boolean error() { - return error; - } } -- cgit v1.2.3-70-g09d2 From 5e8b2e0886049fe43d991fafa94bebcbde6a1f02 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 5 Dec 2017 23:35:06 +0100 Subject: Specialize test suites in reader package to classes. --- src/cz/crcs/ectester/common/output/TestWriter.java | 2 +- src/cz/crcs/ectester/common/test/TestRunner.java | 28 +++++ src/cz/crcs/ectester/common/test/TestSuite.java | 36 ++++++ src/cz/crcs/ectester/reader/ECTesterReader.java | 13 +- .../ectester/reader/output/TextTestWriter.java | 4 +- .../crcs/ectester/reader/output/XMLTestWriter.java | 4 +- .../ectester/reader/output/YAMLTestWriter.java | 4 +- .../reader/test/CardCompositeCurvesSuite.java | 53 ++++++++ .../ectester/reader/test/CardDefaultSuite.java | 69 +++++++++++ .../reader/test/CardInvalidCurvesSuite.java | 70 +++++++++++ .../crcs/ectester/reader/test/CardTestSuite.java | 121 ++++++++++++++++++ .../ectester/reader/test/CardTestVectorSuite.java | 90 ++++++++++++++ .../ectester/reader/test/CardWrongCurvesSuite.java | 34 +++++ .../ectester/reader/test/CompositeCurvesSuite.java | 53 -------- src/cz/crcs/ectester/reader/test/DefaultSuite.java | 69 ----------- .../ectester/reader/test/InvalidCurvesSuite.java | 70 ----------- src/cz/crcs/ectester/reader/test/TestRunner.java | 29 ----- src/cz/crcs/ectester/reader/test/TestSuite.java | 138 --------------------- .../crcs/ectester/reader/test/TestVectorSuite.java | 90 -------------- .../ectester/reader/test/WrongCurvesSuite.java | 34 ----- 20 files changed, 515 insertions(+), 496 deletions(-) create mode 100644 src/cz/crcs/ectester/common/test/TestRunner.java create mode 100644 src/cz/crcs/ectester/common/test/TestSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/CardDefaultSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/CardTestSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java create mode 100644 src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java delete mode 100644 src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java delete mode 100644 src/cz/crcs/ectester/reader/test/DefaultSuite.java delete mode 100644 src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java delete mode 100644 src/cz/crcs/ectester/reader/test/TestRunner.java delete mode 100644 src/cz/crcs/ectester/reader/test/TestSuite.java delete mode 100644 src/cz/crcs/ectester/reader/test/TestVectorSuite.java delete mode 100644 src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java (limited to 'src/cz/crcs/ectester/reader/output/TextTestWriter.java') diff --git a/src/cz/crcs/ectester/common/output/TestWriter.java b/src/cz/crcs/ectester/common/output/TestWriter.java index 0f3c4e6..0ecfd5a 100644 --- a/src/cz/crcs/ectester/common/output/TestWriter.java +++ b/src/cz/crcs/ectester/common/output/TestWriter.java @@ -1,7 +1,7 @@ package cz.crcs.ectester.common.output; import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.reader.test.TestSuite; +import cz.crcs.ectester.common.test.TestSuite; /** * @author Jan Jancar johny@neuromancer.sk diff --git a/src/cz/crcs/ectester/common/test/TestRunner.java b/src/cz/crcs/ectester/common/test/TestRunner.java new file mode 100644 index 0000000..8564d2c --- /dev/null +++ b/src/cz/crcs/ectester/common/test/TestRunner.java @@ -0,0 +1,28 @@ +package cz.crcs.ectester.common.test; + +import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.reader.test.CardTestSuite; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TestRunner { + private TestSuite suite; + private TestWriter writer; + + public TestRunner(CardTestSuite suite, TestWriter writer) { + this.suite = suite; + this.writer = writer; + } + + public void run() throws TestException { + writer.begin(suite); + for (Test t : suite.getTests()) { + if (!t.hasRun()) { + t.run(); + writer.outputTest(t); + } + } + writer.end(); + } +} diff --git a/src/cz/crcs/ectester/common/test/TestSuite.java b/src/cz/crcs/ectester/common/test/TestSuite.java new file mode 100644 index 0000000..74a24af --- /dev/null +++ b/src/cz/crcs/ectester/common/test/TestSuite.java @@ -0,0 +1,36 @@ +package cz.crcs.ectester.common.test; + +import cz.crcs.ectester.data.EC_Store; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class TestSuite { + protected String name; + protected String description; + protected List tests = new LinkedList<>(); + protected EC_Store dataStore; + + public TestSuite(EC_Store dataStore, String name, String description) { + this.dataStore = dataStore; + this.name = name; + this.description = description; + } + + public List getTests() { + return Collections.unmodifiableList(tests); + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + +} diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index e627099..be01129 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -28,6 +28,7 @@ import cz.crcs.ectester.common.ec.EC_Params; import cz.crcs.ectester.common.output.OutputLogger; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.TestException; +import cz.crcs.ectester.common.test.TestRunner; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.command.Command; @@ -406,14 +407,14 @@ public class ECTesterReader { * @throws IOException if an IO error occurs when writing to key file. */ private void test() throws IOException, TestException { - TestSuite suite; + CardTestSuite suite; switch (cfg.testSuite) { case "default": - suite = new DefaultSuite(dataStore, cfg); + suite = new CardDefaultSuite(dataStore, cfg); break; case "test-vectors": - suite = new TestVectorSuite(dataStore, cfg); + suite = new CardTestVectorSuite(dataStore, cfg); break; default: // These tests are dangerous, prompt before them. @@ -432,13 +433,13 @@ public class ECTesterReader { switch (cfg.testSuite) { case "wrong": - suite = new WrongCurvesSuite(dataStore, cfg); + suite = new CardWrongCurvesSuite(dataStore, cfg); break; case "composite": - suite = new CompositeCurvesSuite(dataStore, cfg); + suite = new CardCompositeCurvesSuite(dataStore, cfg); break; case "invalid": - suite = new InvalidCurvesSuite(dataStore, cfg); + suite = new CardInvalidCurvesSuite(dataStore, cfg); break; default: System.err.println("Unknown test suite."); diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index a4bb33e..06b6ea8 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -4,7 +4,7 @@ import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.test.Test; import cz.crcs.ectester.reader.test.CommandTest; -import cz.crcs.ectester.reader.test.TestSuite; +import cz.crcs.ectester.reader.test.CardTestSuite; import java.io.PrintStream; @@ -23,7 +23,7 @@ public class TextTestWriter implements TestWriter { } @Override - public void begin(TestSuite suite) { + public void begin(CardTestSuite suite) { output.println("=== Running test suite: " + suite.getName() + " ==="); output.println("=== " + suite.getDescription()); } diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index 1a94984..d889c3a 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -7,7 +7,7 @@ import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.common.test.Test; import cz.crcs.ectester.reader.test.CommandTest; -import cz.crcs.ectester.reader.test.TestSuite; +import cz.crcs.ectester.reader.test.CardTestSuite; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -38,7 +38,7 @@ public class XMLTestWriter implements TestWriter { } @Override - public void begin(TestSuite suite) { + public void begin(CardTestSuite suite) { doc = db.newDocument(); Element rootElem = doc.createElement("testSuite"); rootElem.setAttribute("name", suite.getName()); diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index e0038fd..cd89b1a 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -7,7 +7,7 @@ import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.common.test.Test; import cz.crcs.ectester.reader.test.CommandTest; -import cz.crcs.ectester.reader.test.TestSuite; +import cz.crcs.ectester.reader.test.CardTestSuite; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; @@ -31,7 +31,7 @@ public class YAMLTestWriter implements TestWriter { } @Override - public void begin(TestSuite suite) { + public void begin(CardTestSuite suite) { output.println("---"); testRun = new HashMap<>(); testSuite = new HashMap<>(); diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java new file mode 100644 index 0000000..930a0d0 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardCompositeCurvesSuite.java @@ -0,0 +1,53 @@ +package cz.crcs.ectester.reader.test; + +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.CardMngr; +import cz.crcs.ectester.reader.ECTesterReader; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.ec.EC_Key; +import javacard.security.KeyPair; + +import java.util.Map; + +import static cz.crcs.ectester.common.test.Result.ExpectedValue; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardCompositeCurvesSuite extends CardTestSuite { + + public CardCompositeCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { + super(dataStore, cfg, "composite", "The composite suite tests ECDH over curves with composite order. This should generally fail, as using such a curve is unsafe."); + } + + @Override + public void setup(CardMngr cardManager) { + /* Do the default tests with the public keys set to provided smallorder keys + * over composite order curves. Essentially small subgroup attacks. + * These should fail, the curves aren't safe so that if the computation with + * a small order public key succeeds the private key modulo the public key order + * is revealed. + */ + Map keys = dataStore.getObjects(EC_Key.class, "composite"); + for (EC_Key key : keys.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); + if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } + if ((curve.getBits() == cfg.bits || cfg.all)) { + tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); + tests.add(CommandTest.expect(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(CommandTest.expect(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(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + } + } + } +} diff --git a/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java new file mode 100644 index 0000000..06818d4 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardDefaultSuite.java @@ -0,0 +1,69 @@ +package cz.crcs.ectester.reader.test; + +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.CardMngr; +import cz.crcs.ectester.reader.ECTesterReader; +import cz.crcs.ectester.reader.command.Command; +import javacard.security.KeyPair; + +import java.io.IOException; + +import static cz.crcs.ectester.common.test.Result.ExpectedValue; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardDefaultSuite extends CardTestSuite { + + public CardDefaultSuite(EC_Store dataStore, ECTesterReader.Config cfg) { + super(dataStore, cfg, "default", "The default test suite tests basic support of ECDH and ECDSA."); + } + + @Override + public void setup(CardMngr cardManager) throws IOException { + tests.add(CommandTest.expect(new Command.Support(cardManager), ExpectedValue.ANY)); + if (cfg.namedCurve != null) { + String desc = "Default tests over the " + cfg.namedCurve + " curve category."; + if (cfg.primeField) { + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); + } + if (cfg.binaryField) { + tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); + } + } else { + if (cfg.all) { + if (cfg.primeField) { + //iterate over prime curve sizes used: EC_Consts.FP_SIZES + for (short keyLength : EC_Consts.FP_SIZES) { + defaultTests(cardManager, keyLength, KeyPair.ALG_EC_FP); + } + } + if (cfg.binaryField) { + //iterate over binary curve sizes used: EC_Consts.F2M_SIZES + for (short keyLength : EC_Consts.F2M_SIZES) { + defaultTests(cardManager, keyLength, KeyPair.ALG_EC_F2M); + } + } + } else { + if (cfg.primeField) { + defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_FP); + } + + if (cfg.binaryField) { + defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_F2M); + } + } + } + } + + private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { + tests.add(CommandTest.expect(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(CommandTest.expect(curve, ExpectedValue.SUCCESS)); + tests.add(defaultCurveTests(cardManager, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, "Default tests.")); + tests.add(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + } +} diff --git a/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java new file mode 100644 index 0000000..e4e55c9 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardInvalidCurvesSuite.java @@ -0,0 +1,70 @@ +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; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.common.ec.EC_Curve; +import cz.crcs.ectester.common.ec.EC_Key; +import javacard.security.KeyPair; + +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import static cz.crcs.ectester.common.test.Result.ExpectedValue; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardInvalidCurvesSuite extends CardTestSuite { + + public CardInvalidCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { + super(dataStore, cfg, "invalid", "The invalid curve suite tests whether the card rejects points outside of the curve during ECDH."); + } + + @Override + public void setup(CardMngr cardManager) throws IOException { + /* Set original curves (secg/nist/brainpool). Generate local. + * Try ECDH with invalid public keys of increasing (or decreasing) order. + */ + Map pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); + Map> curves = new HashMap<>(); + for (EC_Key.Public key : pubkeys.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); + if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getBits() != cfg.bits && !cfg.all) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } + List keys = curves.getOrDefault(curve, new LinkedList<>()); + keys.add(key); + curves.putIfAbsent(curve, keys); + } + for (Map.Entry> e : curves.entrySet()) { + EC_Curve curve = e.getKey(); + List keys = e.getValue(); + + tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); + tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); + List 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(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); + } + tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); + tests.add(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + } + } +} diff --git a/src/cz/crcs/ectester/reader/test/CardTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTestSuite.java new file mode 100644 index 0000000..e3cc155 --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardTestSuite.java @@ -0,0 +1,121 @@ +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.common.test.TestSuite; +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 java.io.IOException; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import static cz.crcs.ectester.common.test.Result.ExpectedValue; +import static cz.crcs.ectester.common.test.Result.Value; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class CardTestSuite extends TestSuite { + ECTesterReader.Config cfg; + + CardTestSuite(EC_Store dataStore, ECTesterReader.Config cfg, String name, String description) { + super(dataStore, name, description); + this.cfg = cfg; + } + + public abstract void setup(CardMngr cardManager) throws IOException; + + /** + * @param cardManager cardManager to send APDU through + * @param generateExpected expected result of the Generate command + * @param ecdhExpected expected result of the ordinary ECDH command + * @param ecdhCompressExpected expected result of ECDH with a compressed point + * @param ecdsaExpected expected result of the ordinary ECDSA command + * @param description compound test description + * @return test to run + */ + Test defaultCurveTests(CardMngr cardManager, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressExpected, ExpectedValue ecdsaExpected, String description) { + List tests = new LinkedList<>(); + + tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); + tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); + tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); + tests.add(CommandTest.expect(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(CommandTest.expect(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(CommandTest.expect(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(CommandTest.expect(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(CommandTest.expect(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); + + return CompoundTest.function((testArray) -> { + Function shouldHave = (expected) -> { + switch (expected) { + case SUCCESS: + return "succeeded"; + case FAILURE: + return "failed"; + case ANY: + default: + return ""; + } + }; + + for (int i = 0; i < testArray.length; ++i) { + Test t = testArray[i]; + if (!t.ok()) { + if (i == 0) { // generate + return new Result(Value.FAILURE, "The generation of a key should have " + shouldHave.apply(generateExpected) + ", but it did not."); + } else if (i == 2) { // ecdh compress + return new Result(Value.FAILURE, "The ECDH should have " + shouldHave.apply(ecdhExpected) + ", but it did not."); + } else if (i == 1) { // ecdh normal + return new Result(Value.FAILURE, "The ECDH of a compressed point should have " + shouldHave.apply(ecdhCompressExpected) + ", but it did not."); + } else if (i <= 6) { // ecdh wrong, should fail + return new Result(Value.FAILURE, "The ECDH of a corrupted point should have failed, but it did not."); + } else { // ecdsa + return new Result(Value.FAILURE, "The ECDSA should have " + shouldHave.apply(ecdsaExpected) + ", but it did not."); + } + } + } + return new Result(Value.SUCCESS); + }, description, tests.toArray(new Test[0])); + } + + /** + * @param cardManager cardManager to send APDU through + * @param category category to test + * @param field field to test (KeyPair.ALG_EC_FP || KeyPair.ALG_EC_F2M) + * @param setExpected expected result of the Set (curve) command + * @param generateExpected expected result of the Generate command + * @param ecdhExpected expected result of the ordinary ECDH command + * @param ecdhCompressedExpected expected result of the ECDH command with a compressed point. + * @param ecdsaExpected expected result of the ordinary ECDSA command + * @param description compound test description + * @return tests to run + */ + List defaultCategoryTests(CardMngr cardManager, String category, byte field, ExpectedValue setExpected, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressedExpected, ExpectedValue ecdsaExpected, String description) { + List tests = new LinkedList<>(); + Map curves = dataStore.getObjects(EC_Curve.class, category); + if (curves == null) + return tests; + for (Map.Entry entry : curves.entrySet()) { + EC_Curve curve = entry.getValue(); + if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { + tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS)); + tests.add(CommandTest.expect(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(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + } + } + + return tests; + } +} diff --git a/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java new file mode 100644 index 0000000..72e3cce --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardTestVectorSuite.java @@ -0,0 +1,90 @@ +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.*; +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.common.test.TestCallback; +import cz.crcs.ectester.common.util.ByteUtil; +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.reader.response.Response; +import javacard.security.KeyPair; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import static cz.crcs.ectester.common.test.Result.ExpectedValue; +import static cz.crcs.ectester.common.test.Result.Value; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardTestVectorSuite extends CardTestSuite { + + public CardTestVectorSuite(EC_Store dataStore, ECTesterReader.Config cfg) { + super(dataStore, cfg, "test", "The test-vectors suite contains a collection of test vectors which test basic ECDH correctness."); + } + + @Override + public void setup(CardMngr cardManager) throws IOException { + /* Set original curves (secg/nist/brainpool). Set keypairs from test vectors. + * Do ECDH both ways, export and verify that the result is correct. + */ + Map results = dataStore.getObjects(EC_KAResult.class, "test"); + for (EC_KAResult result : results.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, result.getCurve()); + if (cfg.namedCurve != null && !(result.getCurve().startsWith(cfg.namedCurve) || result.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getBits() != cfg.bits && !cfg.all) { + continue; + } + if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { + continue; + } + EC_Params onekey = dataStore.getObject(EC_Keypair.class, result.getOneKey()); + if (onekey == null) { + onekey = dataStore.getObject(EC_Key.Private.class, result.getOneKey()); + } + EC_Params otherkey = dataStore.getObject(EC_Keypair.class, result.getOtherKey()); + if (otherkey == null) { + otherkey = dataStore.getObject(EC_Key.Public.class, result.getOtherKey()); + } + if (onekey == null || otherkey == null) { + throw new IOException("Test vector keys couldn't be located."); + } + List testVector = new LinkedList<>(); + + testVector.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); + testVector.add(CommandTest.expect(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(CommandTest.expect(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(CommandTest.expect(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(CommandTest.function(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), new TestCallback() { + @Override + public Result apply(CommandTestable testable) { + Response.ECDH dh = (Response.ECDH) testable.getResponse(); + if (!dh.successful()) + return new Result(Value.FAILURE, "ECDH was unsuccessful."); + if (!dh.hasSecret()) + return new Result(Value.FAILURE, "ECDH response did not contain the derived secret."); + if (!ByteUtil.compareBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength())) { + int firstDiff = ByteUtil.diffBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength()); + return new Result(Value.FAILURE, "ECDH derived secret does not match the test, first difference was at byte " + String.valueOf(firstDiff) + "."); + } + return new Result(Value.SUCCESS); + } + })); + tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); + tests.add(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); + + } + } +} diff --git a/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java new file mode 100644 index 0000000..4c529da --- /dev/null +++ b/src/cz/crcs/ectester/reader/test/CardWrongCurvesSuite.java @@ -0,0 +1,34 @@ +package cz.crcs.ectester.reader.test; + +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.ECTesterReader; +import javacard.security.KeyPair; + +import java.io.IOException; + +import static cz.crcs.ectester.common.test.Result.ExpectedValue; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardWrongCurvesSuite extends CardTestSuite { + + public CardWrongCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { + super(dataStore, cfg, "wrong", "The wrong curve suite tests whether the card rejects domain parameters which are not curves."); + } + + @Override + public void setup(CardMngr cardManager) throws IOException { + /* Just do the default tests on the wrong curves. + * These should generally fail, the curves aren't curves. + */ + String desc = "Default tests over wrong curve params."; + if (cfg.primeField) { + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); + } + if (cfg.binaryField) { + tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); + } + } +} diff --git a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java b/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java deleted file mode 100644 index 8a02381..0000000 --- a/src/cz/crcs/ectester/reader/test/CompositeCurvesSuite.java +++ /dev/null @@ -1,53 +0,0 @@ -package cz.crcs.ectester.reader.test; - -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.CardMngr; -import cz.crcs.ectester.reader.ECTesterReader; -import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.ec.EC_Key; -import javacard.security.KeyPair; - -import java.util.Map; - -import static cz.crcs.ectester.common.test.Result.ExpectedValue; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class CompositeCurvesSuite extends TestSuite { - - public CompositeCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "composite", "The composite suite tests ECDH over curves with composite order. This should generally fail, as using such a curve is unsafe."); - } - - @Override - public void setup(CardMngr cardManager) { - /* Do the default tests with the public keys set to provided smallorder keys - * over composite order curves. Essentially small subgroup attacks. - * These should fail, the curves aren't safe so that if the computation with - * a small order public key succeeds the private key modulo the public key order - * is revealed. - */ - Map keys = dataStore.getObjects(EC_Key.class, "composite"); - for (EC_Key key : keys.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); - if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { - continue; - } - if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { - continue; - } - if ((curve.getBits() == cfg.bits || cfg.all)) { - tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY)); - tests.add(CommandTest.expect(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(CommandTest.expect(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(CommandTest.expect(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 deleted file mode 100644 index 881480c..0000000 --- a/src/cz/crcs/ectester/reader/test/DefaultSuite.java +++ /dev/null @@ -1,69 +0,0 @@ -package cz.crcs.ectester.reader.test; - -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.CardMngr; -import cz.crcs.ectester.reader.ECTesterReader; -import cz.crcs.ectester.reader.command.Command; -import javacard.security.KeyPair; - -import java.io.IOException; - -import static cz.crcs.ectester.common.test.Result.ExpectedValue; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class DefaultSuite extends TestSuite { - - public DefaultSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "default", "The default test suite tests basic support of ECDH and ECDSA."); - } - - @Override - public void setup(CardMngr cardManager) throws IOException { - tests.add(CommandTest.expect(new Command.Support(cardManager), ExpectedValue.ANY)); - if (cfg.namedCurve != null) { - String desc = "Default tests over the " + cfg.namedCurve + " curve category."; - if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_FP, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); - } - if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.namedCurve, KeyPair.ALG_EC_F2M, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, desc)); - } - } else { - if (cfg.all) { - if (cfg.primeField) { - //iterate over prime curve sizes used: EC_Consts.FP_SIZES - for (short keyLength : EC_Consts.FP_SIZES) { - defaultTests(cardManager, keyLength, KeyPair.ALG_EC_FP); - } - } - if (cfg.binaryField) { - //iterate over binary curve sizes used: EC_Consts.F2M_SIZES - for (short keyLength : EC_Consts.F2M_SIZES) { - defaultTests(cardManager, keyLength, KeyPair.ALG_EC_F2M); - } - } - } else { - if (cfg.primeField) { - defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_FP); - } - - if (cfg.binaryField) { - defaultTests(cardManager, (short) cfg.bits, KeyPair.ALG_EC_F2M); - } - } - } - } - - private void defaultTests(CardMngr cardManager, short keyLength, byte keyType) throws IOException { - tests.add(CommandTest.expect(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(CommandTest.expect(curve, ExpectedValue.SUCCESS)); - tests.add(defaultCurveTests(cardManager, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, "Default tests.")); - tests.add(CommandTest.expect(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 deleted file mode 100644 index 96e4ca2..0000000 --- a/src/cz/crcs/ectester/reader/test/InvalidCurvesSuite.java +++ /dev/null @@ -1,70 +0,0 @@ -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; -import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.ec.EC_Key; -import javacard.security.KeyPair; - -import java.io.IOException; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import static cz.crcs.ectester.common.test.Result.ExpectedValue; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class InvalidCurvesSuite extends TestSuite { - - public InvalidCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "invalid", "The invalid curve suite tests whether the card rejects points outside of the curve during ECDH."); - } - - @Override - public void setup(CardMngr cardManager) throws IOException { - /* Set original curves (secg/nist/brainpool). Generate local. - * Try ECDH with invalid public keys of increasing (or decreasing) order. - */ - Map pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); - Map> curves = new HashMap<>(); - for (EC_Key.Public key : pubkeys.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); - if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { - continue; - } - if (curve.getBits() != cfg.bits && !cfg.all) { - continue; - } - if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { - continue; - } - List keys = curves.getOrDefault(curve, new LinkedList<>()); - keys.add(key); - curves.putIfAbsent(curve, keys); - } - for (Map.Entry> e : curves.entrySet()) { - EC_Curve curve = e.getKey(); - List keys = e.getValue(); - - tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - tests.add(CommandTest.expect(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS)); - tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), ExpectedValue.SUCCESS)); - List 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(CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected point on invalid curve." , "Card incorrectly accepted point on invalid curve.")); - } - tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId(), ecdhTests.toArray(new Test[0]))); - tests.add(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); - } - } -} diff --git a/src/cz/crcs/ectester/reader/test/TestRunner.java b/src/cz/crcs/ectester/reader/test/TestRunner.java deleted file mode 100644 index e581aaa..0000000 --- a/src/cz/crcs/ectester/reader/test/TestRunner.java +++ /dev/null @@ -1,29 +0,0 @@ -package cz.crcs.ectester.reader.test; - -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.test.TestException; -import cz.crcs.ectester.common.output.TestWriter; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class TestRunner { - private TestSuite suite; - private TestWriter writer; - - public TestRunner(TestSuite suite, TestWriter writer) { - this.suite = suite; - this.writer = writer; - } - - public void run() throws TestException { - writer.begin(suite); - for (Test t : suite.getTests()) { - if (!t.hasRun()) { - t.run(); - writer.outputTest(t); - } - } - writer.end(); - } -} diff --git a/src/cz/crcs/ectester/reader/test/TestSuite.java b/src/cz/crcs/ectester/reader/test/TestSuite.java deleted file mode 100644 index e722960..0000000 --- a/src/cz/crcs/ectester/reader/test/TestSuite.java +++ /dev/null @@ -1,138 +0,0 @@ -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 java.io.IOException; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - -import static cz.crcs.ectester.common.test.Result.ExpectedValue; -import static cz.crcs.ectester.common.test.Result.Value; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public abstract class TestSuite { - EC_Store dataStore; - ECTesterReader.Config cfg; - String name; - String description; - List tests = new LinkedList<>(); - - TestSuite(EC_Store dataStore, ECTesterReader.Config cfg, String name, String description) { - this.dataStore = dataStore; - this.cfg = cfg; - this.name = name; - this.description = description; - } - - public abstract void setup(CardMngr cardManager) throws IOException; - - public List getTests() { - return Collections.unmodifiableList(tests); - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - /** - * @param cardManager cardManager to send APDU through - * @param generateExpected expected result of the Generate command - * @param ecdhExpected expected result of the ordinary ECDH command - * @param ecdhCompressExpected expected result of ECDH with a compressed point - * @param ecdsaExpected expected result of the ordinary ECDSA command - * @param description compound test description - * @return test to run - */ - Test defaultCurveTests(CardMngr cardManager, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressExpected, ExpectedValue ecdsaExpected, String description) { - List tests = new LinkedList<>(); - - tests.add(CommandTest.expect(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), generateExpected)); - tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(CommandTest.expect(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_COMPRESS, EC_Consts.KA_ECDH), ecdhExpected)); - tests.add(CommandTest.expect(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(CommandTest.expect(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(CommandTest.expect(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(CommandTest.expect(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(CommandTest.expect(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, null), ecdsaExpected)); - - return CompoundTest.function((testArray) -> { - Function shouldHave = (expected) -> { - switch (expected) { - case SUCCESS: - return "succeeded"; - case FAILURE: - return "failed"; - case ANY: - default: - return ""; - } - }; - - for (int i = 0; i < testArray.length; ++i) { - Test t = testArray[i]; - if (!t.ok()) { - if (i == 0) { // generate - return new Result(Value.FAILURE, "The generation of a key should have " + shouldHave.apply(generateExpected) + ", but it did not."); - } else if (i == 2) { // ecdh compress - return new Result(Value.FAILURE, "The ECDH should have " + shouldHave.apply(ecdhExpected) + ", but it did not."); - } else if (i == 1) { // ecdh normal - return new Result(Value.FAILURE, "The ECDH of a compressed point should have " + shouldHave.apply(ecdhCompressExpected) + ", but it did not."); - } else if (i <= 6) { // ecdh wrong, should fail - return new Result(Value.FAILURE, "The ECDH of a corrupted point should have failed, but it did not."); - } else { // ecdsa - return new Result(Value.FAILURE, "The ECDSA should have " + shouldHave.apply(ecdsaExpected) + ", but it did not."); - } - } - } - return new Result(Value.SUCCESS); - }, description, tests.toArray(new Test[0])); - } - - /** - * @param cardManager cardManager to send APDU through - * @param category category to test - * @param field field to test (KeyPair.ALG_EC_FP || KeyPair.ALG_EC_F2M) - * @param setExpected expected result of the Set (curve) command - * @param generateExpected expected result of the Generate command - * @param ecdhExpected expected result of the ordinary ECDH command - * @param ecdhCompressedExpected expected result of the ECDH command with a compressed point. - * @param ecdsaExpected expected result of the ordinary ECDSA command - * @param description compound test description - * @return tests to run - */ - List defaultCategoryTests(CardMngr cardManager, String category, byte field, ExpectedValue setExpected, ExpectedValue generateExpected, ExpectedValue ecdhExpected, ExpectedValue ecdhCompressedExpected, ExpectedValue ecdsaExpected, String description) { - List tests = new LinkedList<>(); - Map curves = dataStore.getObjects(EC_Curve.class, category); - if (curves == null) - return tests; - for (Map.Entry entry : curves.entrySet()) { - EC_Curve curve = entry.getValue(); - if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { - tests.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field), ExpectedValue.SUCCESS)); - tests.add(CommandTest.expect(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(CommandTest.expect(new Command.Cleanup(cardManager), ExpectedValue.ANY)); - } - } - - return tests; - } -} diff --git a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java b/src/cz/crcs/ectester/reader/test/TestVectorSuite.java deleted file mode 100644 index c89cfa6..0000000 --- a/src/cz/crcs/ectester/reader/test/TestVectorSuite.java +++ /dev/null @@ -1,90 +0,0 @@ -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.*; -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.common.test.TestCallback; -import cz.crcs.ectester.common.util.ByteUtil; -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.reader.response.Response; -import javacard.security.KeyPair; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import static cz.crcs.ectester.common.test.Result.ExpectedValue; -import static cz.crcs.ectester.common.test.Result.Value; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class TestVectorSuite extends TestSuite { - - public TestVectorSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "test", "The test-vectors suite contains a collection of test vectors which test basic ECDH correctness."); - } - - @Override - public void setup(CardMngr cardManager) throws IOException { - /* Set original curves (secg/nist/brainpool). Set keypairs from test vectors. - * Do ECDH both ways, export and verify that the result is correct. - */ - Map results = dataStore.getObjects(EC_KAResult.class, "test"); - for (EC_KAResult result : results.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, result.getCurve()); - if (cfg.namedCurve != null && !(result.getCurve().startsWith(cfg.namedCurve) || result.getCurve().equals(cfg.namedCurve))) { - continue; - } - if (curve.getBits() != cfg.bits && !cfg.all) { - continue; - } - if (curve.getField() == KeyPair.ALG_EC_FP && !cfg.primeField || curve.getField() == KeyPair.ALG_EC_F2M && !cfg.binaryField) { - continue; - } - EC_Params onekey = dataStore.getObject(EC_Keypair.class, result.getOneKey()); - if (onekey == null) { - onekey = dataStore.getObject(EC_Key.Private.class, result.getOneKey()); - } - EC_Params otherkey = dataStore.getObject(EC_Keypair.class, result.getOtherKey()); - if (otherkey == null) { - otherkey = dataStore.getObject(EC_Key.Public.class, result.getOtherKey()); - } - if (onekey == null || otherkey == null) { - throw new IOException("Test vector keys couldn't be located."); - } - List testVector = new LinkedList<>(); - - testVector.add(CommandTest.expect(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS)); - testVector.add(CommandTest.expect(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(CommandTest.expect(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(CommandTest.expect(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(CommandTest.function(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), new TestCallback() { - @Override - public Result apply(CommandTestable testable) { - Response.ECDH dh = (Response.ECDH) testable.getResponse(); - if (!dh.successful()) - return new Result(Value.FAILURE, "ECDH was unsuccessful."); - if (!dh.hasSecret()) - return new Result(Value.FAILURE, "ECDH response did not contain the derived secret."); - if (!ByteUtil.compareBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength())) { - int firstDiff = ByteUtil.diffBytes(dh.getSecret(), 0, result.getData(0), 0, dh.secretLength()); - return new Result(Value.FAILURE, "ECDH derived secret does not match the test, first difference was at byte " + String.valueOf(firstDiff) + "."); - } - return new Result(Value.SUCCESS); - } - })); - tests.add(CompoundTest.all(ExpectedValue.SUCCESS, "Test vector " + result.getId(), testVector.toArray(new Test[0]))); - tests.add(CommandTest.expect(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 deleted file mode 100644 index 76da718..0000000 --- a/src/cz/crcs/ectester/reader/test/WrongCurvesSuite.java +++ /dev/null @@ -1,34 +0,0 @@ -package cz.crcs.ectester.reader.test; - -import cz.crcs.ectester.data.EC_Store; -import cz.crcs.ectester.reader.CardMngr; -import cz.crcs.ectester.reader.ECTesterReader; -import javacard.security.KeyPair; - -import java.io.IOException; - -import static cz.crcs.ectester.common.test.Result.ExpectedValue; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class WrongCurvesSuite extends TestSuite { - - public WrongCurvesSuite(EC_Store dataStore, ECTesterReader.Config cfg) { - super(dataStore, cfg, "wrong", "The wrong curve suite tests whether the card rejects domain parameters which are not curves."); - } - - @Override - public void setup(CardMngr cardManager) throws IOException { - /* Just do the default tests on the wrong curves. - * These should generally fail, the curves aren't curves. - */ - String desc = "Default tests over wrong curve params."; - if (cfg.primeField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_FP, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); - } - if (cfg.binaryField) { - tests.addAll(defaultCategoryTests(cardManager, cfg.testSuite, KeyPair.ALG_EC_F2M, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, ExpectedValue.FAILURE, desc)); - } - } -} -- cgit v1.2.3-70-g09d2 From e14a28d7e6db9ad270e52a16b0ca3616cd8abfd5 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 6 Dec 2017 00:18:45 +0100 Subject: Fix TestWriters. --- src/cz/crcs/ectester/reader/output/TextTestWriter.java | 3 ++- src/cz/crcs/ectester/reader/output/XMLTestWriter.java | 3 ++- src/cz/crcs/ectester/reader/output/YAMLTestWriter.java | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/cz/crcs/ectester/reader/output/TextTestWriter.java') diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index 06b6ea8..b6cd51c 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -3,6 +3,7 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.reader.test.CommandTest; import cz.crcs.ectester.reader.test.CardTestSuite; @@ -23,7 +24,7 @@ public class TextTestWriter implements TestWriter { } @Override - public void begin(CardTestSuite suite) { + public void begin(TestSuite suite) { output.println("=== Running test suite: " + suite.getName() + " ==="); output.println("=== " + suite.getDescription()); } diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index d889c3a..19c14f1 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; @@ -38,7 +39,7 @@ public class XMLTestWriter implements TestWriter { } @Override - public void begin(CardTestSuite suite) { + public void begin(TestSuite suite) { doc = db.newDocument(); Element rootElem = doc.createElement("testSuite"); rootElem.setAttribute("name", suite.getName()); diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index cd89b1a..5107970 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.common.output.TestWriter; import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; @@ -31,7 +32,7 @@ public class YAMLTestWriter implements TestWriter { } @Override - public void begin(CardTestSuite suite) { + public void begin(TestSuite suite) { output.println("---"); testRun = new HashMap<>(); testSuite = new HashMap<>(); -- cgit v1.2.3-70-g09d2 From e069087e36540452ea03d4f3d97ca8f8f715c799 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 6 Dec 2017 15:03:02 +0100 Subject: Extract TestWriters into common. --- .../ectester/common/output/TestableWriter.java | 35 +++- .../ectester/common/output/TextTestWriter.java | 79 ++++++++ .../crcs/ectester/common/output/XMLTestWriter.java | 204 +++++++++++++++++++++ .../ectester/common/output/YAMLTestWriter.java | 161 ++++++++++++++++ src/cz/crcs/ectester/common/test/TestRunner.java | 3 +- src/cz/crcs/ectester/reader/ECTesterReader.java | 3 +- .../ectester/reader/output/ResponseWriter.java | 8 +- .../ectester/reader/output/TextTestWriter.java | 89 --------- .../crcs/ectester/reader/output/XMLTestWriter.java | 149 --------------- .../ectester/reader/output/YAMLTestWriter.java | 117 ------------ .../crcs/ectester/reader/test/CommandTestable.java | 4 +- 11 files changed, 485 insertions(+), 367 deletions(-) create mode 100644 src/cz/crcs/ectester/common/output/TextTestWriter.java create mode 100644 src/cz/crcs/ectester/common/output/XMLTestWriter.java create mode 100644 src/cz/crcs/ectester/common/output/YAMLTestWriter.java delete mode 100644 src/cz/crcs/ectester/reader/output/TextTestWriter.java delete mode 100644 src/cz/crcs/ectester/reader/output/XMLTestWriter.java delete mode 100644 src/cz/crcs/ectester/reader/output/YAMLTestWriter.java (limited to 'src/cz/crcs/ectester/reader/output/TextTestWriter.java') diff --git a/src/cz/crcs/ectester/common/output/TestableWriter.java b/src/cz/crcs/ectester/common/output/TestableWriter.java index a15193a..9876064 100644 --- a/src/cz/crcs/ectester/common/output/TestableWriter.java +++ b/src/cz/crcs/ectester/common/output/TestableWriter.java @@ -1,6 +1,12 @@ package cz.crcs.ectester.common.output; import cz.crcs.ectester.common.test.BaseTestable; +import cz.crcs.ectester.reader.output.ResponseWriter; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.CommandTestable; +import cz.crcs.ectester.standalone.test.KeyAgreementTestable; +import cz.crcs.ectester.standalone.test.KeyGeneratorTestable; +import cz.crcs.ectester.standalone.test.SignatureTestable; import java.io.OutputStream; import java.io.PrintStream; @@ -10,29 +16,50 @@ import java.io.PrintStream; */ public class TestableWriter { private PrintStream output; + private ResponseWriter respWriter; public TestableWriter(PrintStream output) { this.output = output; + this.respWriter = new ResponseWriter(output); } public TestableWriter(OutputStream output) { this(new PrintStream(output)); } + public String outputTestableSuffix(BaseTestable t) { + if (t instanceof CommandTestable) { + Response r = ((CommandTestable) t).getResponse(); + return respWriter.responseSuffix(r); + } else if (t instanceof KeyAgreementTestable) { - public String outputTestableMeta(BaseTestable t) { + } else if (t instanceof KeyGeneratorTestable) { + + } else if (t instanceof SignatureTestable) { + + } return null; } - public void writeTestableMeta(BaseTestable t) { - + public void writeTestableSuffix(BaseTestable t) { + output.println(outputTestableSuffix(t)); } public String outputTestable(BaseTestable t) { + if (t instanceof CommandTestable) { + CommandTestable testable = (CommandTestable) t; + return respWriter.responseString(testable.getResponse()); + } else if (t instanceof KeyAgreementTestable) { + + } else if (t instanceof KeyGeneratorTestable) { + + } else if (t instanceof SignatureTestable) { + + } return null; } public void writeTestable(BaseTestable t) { - + output.println(outputTestable(t)); } } diff --git a/src/cz/crcs/ectester/common/output/TextTestWriter.java b/src/cz/crcs/ectester/common/output/TextTestWriter.java new file mode 100644 index 0000000..2691ccb --- /dev/null +++ b/src/cz/crcs/ectester/common/output/TextTestWriter.java @@ -0,0 +1,79 @@ +package cz.crcs.ectester.common.output; + +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.SimpleTest; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestSuite; + +import java.io.PrintStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TextTestWriter implements TestWriter { + private PrintStream output; + private TestableWriter testableWriter; + + public static int BASE_WIDTH = 76; + + public TextTestWriter(PrintStream output) { + this.output = output; + this.testableWriter = new TestableWriter(output); + } + + @Override + public void begin(TestSuite suite) { + output.println("=== Running test suite: " + suite.getName() + " ==="); + output.println("=== " + suite.getDescription()); + } + + private String testString(Test t, int offset) { + if (!t.hasRun()) { + return null; + } + + StringBuilder out = new StringBuilder(); + out.append(t.ok() ? "OK " : "NOK "); + out.append("━ "); + int width = BASE_WIDTH - (offset + out.length()); + String widthSpec = "%-" + String.valueOf(width) + "s"; + out.append(String.format(widthSpec, t.getDescription())); + out.append(" ┃ "); + out.append(String.format("%-9s", t.getResultValue().name())); + out.append(" ┃ "); + + if (t instanceof CompoundTest) { + CompoundTest test = (CompoundTest) t; + out.append(test.getResultCause()); + out.append(System.lineSeparator()); + Test[] tests = test.getTests(); + for (int i = 0; i < tests.length; ++i) { + if (i == tests.length - 1) { + out.append(" ┗ "); + } else { + out.append(" ┣ "); + } + out.append(testString(tests[i], offset + 6)); + if (i != tests.length - 1) { + out.append(System.lineSeparator()); + } + } + } else { + SimpleTest test = (SimpleTest) t; + out.append(testableWriter.outputTestableSuffix(test.getTestable())); + } + return out.toString(); + } + + @Override + public void outputTest(Test t) { + if (!t.hasRun()) + return; + output.println(testString(t, 0)); + output.flush(); + } + + @Override + public void end() { + } +} diff --git a/src/cz/crcs/ectester/common/output/XMLTestWriter.java b/src/cz/crcs/ectester/common/output/XMLTestWriter.java new file mode 100644 index 0000000..4139330 --- /dev/null +++ b/src/cz/crcs/ectester/common/output/XMLTestWriter.java @@ -0,0 +1,204 @@ +package cz.crcs.ectester.common.output; + +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestSuite; +import cz.crcs.ectester.common.util.ByteUtil; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.CommandTest; +import cz.crcs.ectester.standalone.test.*; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.OutputStream; +import java.security.PrivateKey; +import java.security.PublicKey; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class XMLTestWriter implements TestWriter { + private OutputStream output; + private DocumentBuilder db; + private Document doc; + private Node root; + + public XMLTestWriter(OutputStream output) throws ParserConfigurationException { + this.output = output; + this.db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } + + @Override + public void begin(TestSuite suite) { + doc = db.newDocument(); + Element rootElem = doc.createElement("testSuite"); + rootElem.setAttribute("name", suite.getName()); + rootElem.setAttribute("desc", suite.getDescription()); + + root = rootElem; + doc.appendChild(root); + } + + private Element commandElement(Command c) { + Element commandElem = doc.createElement("command"); + + Element apdu = doc.createElement("apdu"); + apdu.setTextContent(ByteUtil.bytesToHex(c.getAPDU().getBytes())); + commandElem.appendChild(apdu); + + return commandElem; + } + + private Element responseElement(Response r) { + Element responseElem = doc.createElement("response"); + responseElem.setAttribute("successful", r.successful() ? "true" : "false"); + + Element apdu = doc.createElement("apdu"); + apdu.setTextContent(ByteUtil.bytesToHex(r.getAPDU().getBytes())); + responseElem.appendChild(apdu); + + Element naturalSW = doc.createElement("natural-sw"); + naturalSW.setTextContent(String.valueOf(Short.toUnsignedInt(r.getNaturalSW()))); + responseElem.appendChild(naturalSW); + + Element sws = doc.createElement("sws"); + for (int i = 0; i < r.getNumSW(); ++i) { + Element sw = doc.createElement("sw"); + sw.setTextContent(String.valueOf(Short.toUnsignedInt(r.getSW(i)))); + sws.appendChild(sw); + } + responseElem.appendChild(sws); + + Element duration = doc.createElement("duration"); + duration.setTextContent(String.valueOf(r.getDuration())); + responseElem.appendChild(duration); + + Element description = doc.createElement("desc"); + description.setTextContent(r.getDescription()); + responseElem.appendChild(description); + + return responseElem; + } + + private Element kaElement(KeyAgreementTestable kat) { + Element katElem = doc.createElement("key-agreement"); + + Element secret = doc.createElement("secret"); + secret.setTextContent(ByteUtil.bytesToHex(kat.getSecret())); + katElem.appendChild(secret); + + return katElem; + } + + private Element kgtElement(KeyGeneratorTestable kgt) { + Element kgtElem = doc.createElement("key-pair-generator"); + + Element keyPair = doc.createElement("key-pair"); + Element pubkey = doc.createElement("pubkey"); + PublicKey pkey = kgt.getKeyPair().getPublic(); + pubkey.setAttribute("algorithm", pkey.getAlgorithm()); + pubkey.setAttribute("format", pkey.getFormat()); + pubkey.setTextContent(ByteUtil.bytesToHex(pkey.getEncoded())); + keyPair.appendChild(pubkey); + + Element privkey = doc.createElement("privkey"); + PrivateKey skey = kgt.getKeyPair().getPrivate(); + privkey.setAttribute("algorithm", skey.getAlgorithm()); + privkey.setAttribute("format", skey.getFormat()); + privkey.setTextContent(ByteUtil.bytesToHex(skey.getEncoded())); + keyPair.appendChild(privkey); + + return kgtElem; + } + + private Element sigElement(SignatureTestable sig) { + Element sigElem = doc.createElement("signature"); + sigElem.setAttribute("verified", sig.getVerified() ? "true" : "false"); + + Element raw = doc.createElement("raw"); + raw.setTextContent(ByteUtil.bytesToHex(sig.getSignature())); + sigElem.appendChild(raw); + + return sigElem; + } + + private Element testElement(Test t) { + Element testElem = doc.createElement("test"); + + if (t instanceof CommandTest) { + CommandTest test = (CommandTest) t; + testElem.setAttribute("type", "command"); + testElem.appendChild(commandElement(test.getCommand())); + testElem.appendChild(responseElement(test.getResponse())); + } else if (t instanceof KeyAgreementTest) { + KeyAgreementTest test = (KeyAgreementTest) t; + testElem.setAttribute("type", "key-agreement"); + testElem.appendChild(kaElement(test.getTestable())); + } else if (t instanceof KeyGeneratorTest) { + KeyGeneratorTest test = (KeyGeneratorTest) t; + testElem.setAttribute("type", "key-pair-generator"); + testElem.appendChild(kgtElement(test.getTestable())); + } else if (t instanceof SignatureTest) { + SignatureTest test = (SignatureTest) t; + testElem.setAttribute("type", "signature"); + testElem.appendChild(sigElement(test.getTestable())); + } else if (t instanceof CompoundTest) { + CompoundTest test = (CompoundTest) t; + testElem.setAttribute("type", "compound"); + for (Test innerTest : test.getTests()) { + testElem.appendChild(testElement(innerTest)); + } + } + + Element description = doc.createElement("desc"); + description.setTextContent(t.getDescription()); + testElem.appendChild(description); + + Element result = doc.createElement("result"); + Element ok = doc.createElement("ok"); + ok.setTextContent(String.valueOf(t.ok())); + Element value = doc.createElement("value"); + value.setTextContent(t.getResultValue().name()); + Element cause = doc.createElement("cause"); + cause.setTextContent(t.getResultCause()); + result.appendChild(ok); + result.appendChild(value); + result.appendChild(cause); + testElem.appendChild(result); + + return testElem; + } + + @Override + public void outputTest(Test t) { + if (!t.hasRun()) + return; + root.appendChild(testElement(t)); + } + + @Override + public void end() { + try { + DOMSource domSource = new DOMSource(doc); + StreamResult result = new StreamResult(output); + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer transformer = tf.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + transformer.transform(domSource, result); + } catch (TransformerException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/cz/crcs/ectester/common/output/YAMLTestWriter.java b/src/cz/crcs/ectester/common/output/YAMLTestWriter.java new file mode 100644 index 0000000..ba9fa43 --- /dev/null +++ b/src/cz/crcs/ectester/common/output/YAMLTestWriter.java @@ -0,0 +1,161 @@ +package cz.crcs.ectester.common.output; + +import cz.crcs.ectester.common.test.CompoundTest; +import cz.crcs.ectester.common.test.Test; +import cz.crcs.ectester.common.test.TestSuite; +import cz.crcs.ectester.common.util.ByteUtil; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.CommandTest; +import cz.crcs.ectester.standalone.test.*; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; + +import java.io.PrintStream; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class YAMLTestWriter implements TestWriter { + private PrintStream output; + private Map testRun; + private Map testSuite; + private List tests; + + public YAMLTestWriter(PrintStream output) { + this.output = output; + } + + @Override + public void begin(TestSuite suite) { + output.println("---"); + testRun = new HashMap<>(); + testSuite = new HashMap<>(); + tests = new LinkedList<>(); + testSuite.put("name", suite.getName()); + testSuite.put("desc", suite.getDescription()); + + testRun.put("suite", testSuite); + testRun.put("tests", tests); + } + + private Map commandObject(Command c) { + Map commandObj = new HashMap<>(); + commandObj.put("apdu", ByteUtil.bytesToHex(c.getAPDU().getBytes())); + return commandObj; + } + + private Map responseObject(Response r) { + Map responseObj = new HashMap<>(); + responseObj.put("successful", r.successful()); + responseObj.put("apdu", ByteUtil.bytesToHex(r.getAPDU().getBytes())); + responseObj.put("natural_sw", Short.toUnsignedInt(r.getNaturalSW())); + List sws = new LinkedList<>(); + for (int i = 0; i < r.getNumSW(); ++i) { + sws.add(Short.toUnsignedInt(r.getSW(i))); + } + responseObj.put("sws", sws); + responseObj.put("duration", r.getDuration()); + responseObj.put("desc", r.getDescription()); + return responseObj; + } + + private Map kaObject(KeyAgreementTestable kat) { + Map katObject = new HashMap<>(); + katObject.put("secret", ByteUtil.bytesToHex(kat.getSecret())); + return katObject; + } + + private Map kgtObject(KeyGeneratorTestable kgt) { + Map kgtObject = new HashMap<>(); + Map pubObject = new HashMap<>(); + PublicKey pkey = kgt.getKeyPair().getPublic(); + pubObject.put("algorithm", pkey.getAlgorithm()); + pubObject.put("format", pkey.getFormat()); + pubObject.put("raw", ByteUtil.bytesToHex(pkey.getEncoded())); + kgtObject.put("pubkey", pubObject); + + Map privObject = new HashMap<>(); + PrivateKey skey = kgt.getKeyPair().getPrivate(); + privObject.put("algorithm", skey.getAlgorithm()); + privObject.put("format", skey.getFormat()); + privObject.put("raw", ByteUtil.bytesToHex(skey.getEncoded())); + kgtObject.put("privkey", privObject); + return kgtObject; + } + + private Map sigObject(SignatureTestable sig) { + Map sigObject = new HashMap<>(); + sigObject.put("verified", sig.getVerified()); + sigObject.put("raw", ByteUtil.bytesToHex(sig.getSignature())); + return sigObject; + } + + private Map testObject(Test t) { + Map testObj = new HashMap<>(); + + if (t instanceof CommandTest) { + CommandTest test = (CommandTest) t; + testObj.put("type", "command"); + testObj.put("command", commandObject(test.getCommand())); + testObj.put("response", responseObject(test.getResponse())); + } else if (t instanceof KeyAgreementTest) { + KeyAgreementTest test = (KeyAgreementTest) t; + testObj.put("type", "key-agreement"); + testObj.put("key-agreement", kaObject(test.getTestable())); + } else if (t instanceof KeyGeneratorTest) { + KeyGeneratorTest test = (KeyGeneratorTest) t; + testObj.put("type", "key-pair-generator"); + testObj.put("key-pair-generator", kgtObject(test.getTestable())); + } else if (t instanceof SignatureTest) { + SignatureTest test = (SignatureTest) t; + testObj.put("type", "signature"); + testObj.put("signature", sigObject(test.getTestable())); + } else if (t instanceof CompoundTest) { + CompoundTest test = (CompoundTest) t; + testObj.put("type", "compound"); + List> tests = new LinkedList<>(); + for (Test innerTest : test.getTests()) { + tests.add(testObject(innerTest)); + } + testObj.put("tests", tests); + } + + testObj.put("desc", t.getDescription()); + Map result = new HashMap<>(); + result.put("ok", t.ok()); + result.put("value", t.getResultValue().name()); + result.put("cause", t.getResultCause()); + testObj.put("result", result); + + return testObj; + } + + @Override + public void outputTest(Test t) { + if (!t.hasRun()) + return; + tests.add(testObject(t)); + } + + @Override + public void end() { + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setPrettyFlow(true); + Yaml yaml = new Yaml(options); + + Map result = new HashMap<>(); + result.put("testRun", testRun); + String out = yaml.dump(result); + + output.println(out); + output.println("---"); + } +} diff --git a/src/cz/crcs/ectester/common/test/TestRunner.java b/src/cz/crcs/ectester/common/test/TestRunner.java index 8564d2c..ef448c2 100644 --- a/src/cz/crcs/ectester/common/test/TestRunner.java +++ b/src/cz/crcs/ectester/common/test/TestRunner.java @@ -1,7 +1,6 @@ package cz.crcs.ectester.common.test; import cz.crcs.ectester.common.output.TestWriter; -import cz.crcs.ectester.reader.test.CardTestSuite; /** * @author Jan Jancar johny@neuromancer.sk @@ -10,7 +9,7 @@ public class TestRunner { private TestSuite suite; private TestWriter writer; - public TestRunner(CardTestSuite suite, TestWriter writer) { + public TestRunner(TestSuite suite, TestWriter writer) { this.suite = suite; this.writer = writer; } diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index be01129..6fa7068 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -25,8 +25,7 @@ import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.common.cli.CLITools; import cz.crcs.ectester.common.ec.EC_Params; -import cz.crcs.ectester.common.output.OutputLogger; -import cz.crcs.ectester.common.output.TestWriter; +import cz.crcs.ectester.common.output.*; import cz.crcs.ectester.common.test.TestException; import cz.crcs.ectester.common.test.TestRunner; import cz.crcs.ectester.common.util.ByteUtil; diff --git a/src/cz/crcs/ectester/reader/output/ResponseWriter.java b/src/cz/crcs/ectester/reader/output/ResponseWriter.java index 1dbfdfa..f8837f8 100644 --- a/src/cz/crcs/ectester/reader/output/ResponseWriter.java +++ b/src/cz/crcs/ectester/reader/output/ResponseWriter.java @@ -29,11 +29,15 @@ public class ResponseWriter { return String.format("%4d ms ┃ %s", r.getDuration() / 1000000, suffix); } - public void outputResponse(Response r) { + public String responseString(Response r) { String out = ""; out += String.format("%-70s", r.getDescription()) + " ┃ "; out += responseSuffix(r); - output.println(out); + return out; + } + + public void outputResponse(Response r) { + output.println(responseString(r)); output.flush(); } } diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java deleted file mode 100644 index b6cd51c..0000000 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ /dev/null @@ -1,89 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.common.output.TestWriter; -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.test.TestSuite; -import cz.crcs.ectester.reader.test.CommandTest; -import cz.crcs.ectester.reader.test.CardTestSuite; - -import java.io.PrintStream; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class TextTestWriter implements TestWriter { - private PrintStream output; - private ResponseWriter respWriter; - - public static int BASE_WIDTH = 76; - - public TextTestWriter(PrintStream output) { - this.output = output; - this.respWriter = new ResponseWriter(output); - } - - @Override - public void begin(TestSuite suite) { - output.println("=== Running test suite: " + suite.getName() + " ==="); - output.println("=== " + suite.getDescription()); - } - - private String testString(Test t, int offset) { - if (!t.hasRun()) { - return null; - } - - StringBuilder out = new StringBuilder(); - if (t instanceof CommandTest) { - CommandTest test = (CommandTest) t; - out.append(test.ok() ? "OK " : "NOK "); - out.append("━ "); - int width = BASE_WIDTH - (offset + out.length()); - String widthSpec = "%-" + String.valueOf(width) + "s"; - out.append(String.format(widthSpec, t.getDescription())); - out.append(" ┃ "); - out.append(String.format("%-9s", test.getResultValue().name())); - out.append(" ┃ "); - out.append(respWriter.responseSuffix(test.getResponse())); - } else { - CompoundTest test = (CompoundTest) t; - out.append(test.ok() ? "OK " : "NOK "); - out.append("┳ "); - int width = BASE_WIDTH - (offset + out.length()); - String widthSpec = "%-" + String.valueOf(width) + "s"; - out.append(String.format(widthSpec, t.getDescription())); - out.append(" ┃ "); - out.append(String.format("%-9s", test.getResultValue().name())); - out.append(" ┃ "); - out.append(test.getResultCause()); - out.append(System.lineSeparator()); - Test[] tests = test.getTests(); - for (int i = 0; i < tests.length; ++i) { - if (i == tests.length - 1) { - out.append(" ┗ "); - } else { - out.append(" ┣ "); - } - out.append(testString(tests[i], offset + 6)); - if (i != tests.length - 1) { - out.append(System.lineSeparator()); - } - } - } - - return out.toString(); - } - - @Override - public void outputTest(Test t) { - if (!t.hasRun()) - return; - output.println(testString(t, 0)); - output.flush(); - } - - @Override - public void end() { - } -} diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java deleted file mode 100644 index 19c14f1..0000000 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ /dev/null @@ -1,149 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.common.output.TestWriter; -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.TestSuite; -import cz.crcs.ectester.common.util.ByteUtil; -import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.reader.test.CommandTest; -import cz.crcs.ectester.reader.test.CardTestSuite; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import java.io.OutputStream; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class XMLTestWriter implements TestWriter { - private OutputStream output; - private DocumentBuilder db; - private Document doc; - private Node root; - - public XMLTestWriter(OutputStream output) throws ParserConfigurationException { - this.output = output; - this.db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - } - - @Override - public void begin(TestSuite suite) { - doc = db.newDocument(); - Element rootElem = doc.createElement("testSuite"); - rootElem.setAttribute("name", suite.getName()); - rootElem.setAttribute("desc", suite.getDescription()); - - root = rootElem; - doc.appendChild(root); - } - - private Element commandElement(Command c) { - Element commandElem = doc.createElement("command"); - - Element apdu = doc.createElement("apdu"); - apdu.setTextContent(ByteUtil.bytesToHex(c.getAPDU().getBytes())); - commandElem.appendChild(apdu); - - return commandElem; - } - - private Element responseElement(Response r) { - Element responseElem = doc.createElement("response"); - responseElem.setAttribute("successful", r.successful() ? "true" : "false"); - - Element apdu = doc.createElement("apdu"); - apdu.setTextContent(ByteUtil.bytesToHex(r.getAPDU().getBytes())); - responseElem.appendChild(apdu); - - Element naturalSW = doc.createElement("natural-sw"); - naturalSW.setTextContent(String.valueOf(Short.toUnsignedInt(r.getNaturalSW()))); - responseElem.appendChild(naturalSW); - - Element sws = doc.createElement("sws"); - for (int i = 0; i < r.getNumSW(); ++i) { - Element sw = doc.createElement("sw"); - sw.setTextContent(String.valueOf(Short.toUnsignedInt(r.getSW(i)))); - sws.appendChild(sw); - } - responseElem.appendChild(sws); - - Element duration = doc.createElement("duration"); - duration.setTextContent(String.valueOf(r.getDuration())); - responseElem.appendChild(duration); - - Element description = doc.createElement("desc"); - description.setTextContent(r.getDescription()); - responseElem.appendChild(description); - - return responseElem; - } - - private Element testElement(Test t) { - Element testElem = doc.createElement("test"); - - if (t instanceof CommandTest) { - CommandTest test = (CommandTest) t; - testElem.setAttribute("type", "simple"); - testElem.appendChild(commandElement(test.getCommand())); - testElem.appendChild(responseElement(test.getResponse())); - } else if (t instanceof CompoundTest) { - CompoundTest test = (CompoundTest) t; - testElem.setAttribute("type", "compound"); - for (Test innerTest : test.getTests()) { - testElem.appendChild(testElement(innerTest)); - } - } - - Element description = doc.createElement("desc"); - description.setTextContent(t.getDescription()); - testElem.appendChild(description); - - Element result = doc.createElement("result"); - Element ok = doc.createElement("ok"); - ok.setTextContent(String.valueOf(t.ok())); - Element value = doc.createElement("value"); - value.setTextContent(t.getResultValue().name()); - Element cause = doc.createElement("cause"); - cause.setTextContent(t.getResultCause()); - result.appendChild(ok); - result.appendChild(value); - result.appendChild(cause); - testElem.appendChild(result); - - return testElem; - } - - @Override - public void outputTest(Test t) { - if (!t.hasRun()) - return; - root.appendChild(testElement(t)); - } - - @Override - public void end() { - try { - DOMSource domSource = new DOMSource(doc); - StreamResult result = new StreamResult(output); - TransformerFactory tf = TransformerFactory.newInstance(); - Transformer transformer = tf.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); - transformer.transform(domSource, result); - } catch (TransformerException e) { - e.printStackTrace(); - } - } -} \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java deleted file mode 100644 index 5107970..0000000 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ /dev/null @@ -1,117 +0,0 @@ -package cz.crcs.ectester.reader.output; - -import cz.crcs.ectester.common.output.TestWriter; -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.TestSuite; -import cz.crcs.ectester.common.util.ByteUtil; -import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.reader.test.CommandTest; -import cz.crcs.ectester.reader.test.CardTestSuite; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; - -import java.io.PrintStream; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class YAMLTestWriter implements TestWriter { - private PrintStream output; - private Map testRun; - private Map testSuite; - private List tests; - - public YAMLTestWriter(PrintStream output) { - this.output = output; - } - - @Override - public void begin(TestSuite suite) { - output.println("---"); - testRun = new HashMap<>(); - testSuite = new HashMap<>(); - tests = new LinkedList<>(); - testSuite.put("name", suite.getName()); - testSuite.put("desc", suite.getDescription()); - - testRun.put("suite", testSuite); - testRun.put("tests", tests); - } - - private Map commandObject(Command c) { - Map commandObj = new HashMap<>(); - commandObj.put("apdu", ByteUtil.bytesToHex(c.getAPDU().getBytes())); - return commandObj; - } - - private Map responseObject(Response r) { - Map responseObj = new HashMap<>(); - responseObj.put("successful", r.successful()); - responseObj.put("apdu", ByteUtil.bytesToHex(r.getAPDU().getBytes())); - responseObj.put("natural_sw", Short.toUnsignedInt(r.getNaturalSW())); - List sws = new LinkedList<>(); - for (int i = 0; i < r.getNumSW(); ++i) { - sws.add(Short.toUnsignedInt(r.getSW(i))); - } - responseObj.put("sws", sws); - responseObj.put("duration", r.getDuration()); - responseObj.put("desc", r.getDescription()); - return responseObj; - } - - private Map testObject(Test t) { - Map testObj = new HashMap<>(); - - if (t instanceof CommandTest) { - CommandTest test = (CommandTest) t; - testObj.put("type", "simple"); - testObj.put("command", commandObject(test.getCommand())); - testObj.put("response", responseObject(test.getResponse())); - } else if (t instanceof CompoundTest) { - CompoundTest test = (CompoundTest) t; - testObj.put("type", "compound"); - List> tests = new LinkedList<>(); - for (Test innerTest : test.getTests()) { - tests.add(testObject(innerTest)); - } - testObj.put("tests", tests); - } - - testObj.put("desc", t.getDescription()); - Map result = new HashMap<>(); - result.put("ok", t.ok()); - result.put("value", t.getResultValue().name()); - result.put("cause", t.getResultCause()); - testObj.put("result", result); - - return testObj; - } - - @Override - public void outputTest(Test t) { - if (!t.hasRun()) - return; - tests.add(testObject(t)); - } - - @Override - public void end() { - DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - options.setPrettyFlow(true); - Yaml yaml = new Yaml(options); - - Map result = new HashMap<>(); - result.put("testRun", testRun); - String out = yaml.dump(result); - - output.println(out); - output.println("---"); - } -} diff --git a/src/cz/crcs/ectester/reader/test/CommandTestable.java b/src/cz/crcs/ectester/reader/test/CommandTestable.java index f09a736..4025c61 100644 --- a/src/cz/crcs/ectester/reader/test/CommandTestable.java +++ b/src/cz/crcs/ectester/reader/test/CommandTestable.java @@ -41,7 +41,7 @@ public class CommandTestable extends BaseTestable { ok = true; } meta.clear(); - meta.put("Natural SW", response.getNaturalSW()); - meta.put("SWs", response.getSWs()); + meta.put("natural-sw", response.getNaturalSW()); + meta.put("sws", response.getSWs()); } } -- cgit v1.2.3-70-g09d2 From 71006eb01c60b3556b620b7d4579d65ed6f86926 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 27 Dec 2017 01:10:06 +0100 Subject: Split output to remove cross-dependency of reader and standalone. --- nbproject/reader/project.properties | 2 +- nbproject/standalone/project.properties | 2 +- .../ectester/common/output/BaseTextTestWriter.java | 76 ++++++++ .../ectester/common/output/BaseXMLTestWriter.java | 100 ++++++++++ .../ectester/common/output/BaseYAMLTestWriter.java | 88 +++++++++ .../ectester/common/output/TestableWriter.java | 65 ------- .../ectester/common/output/TextTestWriter.java | 79 -------- .../crcs/ectester/common/output/XMLTestWriter.java | 204 --------------------- .../ectester/common/output/YAMLTestWriter.java | 161 ---------------- src/cz/crcs/ectester/reader/ECTesterReader.java | 5 +- .../ectester/reader/output/TextTestWriter.java | 28 +++ .../crcs/ectester/reader/output/XMLTestWriter.java | 75 ++++++++ .../ectester/reader/output/YAMLTestWriter.java | 57 ++++++ .../ectester/standalone/ECTesterStandalone.java | 2 +- .../ectester/standalone/output/TextTestWriter.java | 20 ++ .../ectester/standalone/output/XMLTestWriter.java | 82 +++++++++ .../ectester/standalone/output/YAMLTestWriter.java | 70 +++++++ 17 files changed, 603 insertions(+), 513 deletions(-) create mode 100644 src/cz/crcs/ectester/common/output/BaseTextTestWriter.java create mode 100644 src/cz/crcs/ectester/common/output/BaseXMLTestWriter.java create mode 100644 src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java delete mode 100644 src/cz/crcs/ectester/common/output/TestableWriter.java delete mode 100644 src/cz/crcs/ectester/common/output/TextTestWriter.java delete mode 100644 src/cz/crcs/ectester/common/output/XMLTestWriter.java delete mode 100644 src/cz/crcs/ectester/common/output/YAMLTestWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/TextTestWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/XMLTestWriter.java create mode 100644 src/cz/crcs/ectester/reader/output/YAMLTestWriter.java create mode 100644 src/cz/crcs/ectester/standalone/output/TextTestWriter.java create mode 100644 src/cz/crcs/ectester/standalone/output/XMLTestWriter.java create mode 100644 src/cz/crcs/ectester/standalone/output/YAMLTestWriter.java (limited to 'src/cz/crcs/ectester/reader/output/TextTestWriter.java') diff --git a/nbproject/reader/project.properties b/nbproject/reader/project.properties index 5eb8ae3..69db523 100644 --- a/nbproject/reader/project.properties +++ b/nbproject/reader/project.properties @@ -30,7 +30,7 @@ dist.javadoc.dir=${dist.dir}/javadoc libs.CopyLibs.classpath=nbproject/copylibstask.jar endorsed.classpath= excludes= -includes=**/applet/**,**/common/**,**/data/**,**/reader/**,**/standalone/** +includes=**/applet/**,**/common/**,**/data/**,**/reader/** jar.compress=false javac.classpath=\ lib/bcprov-jdk15on-1.58.jar:\ diff --git a/nbproject/standalone/project.properties b/nbproject/standalone/project.properties index 2d3a9eb..9fed4c2 100644 --- a/nbproject/standalone/project.properties +++ b/nbproject/standalone/project.properties @@ -30,7 +30,7 @@ dist.javadoc.dir=${dist.dir}/javadoc libs.CopyLibs.classpath=nbproject/copylibstask.jar endorsed.classpath= excludes= -includes=**/common/**,**/standalone/**,**/data/**,**/applet/*,**/reader/** +includes=**/common/**,**/standalone/**,**/data/**,**/applet/* jar.compress=false javac.classpath=\ lib/bcprov-jdk15on-1.58.jar:\ diff --git a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java new file mode 100644 index 0000000..9635d0c --- /dev/null +++ b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java @@ -0,0 +1,76 @@ +package cz.crcs.ectester.common.output; + +import cz.crcs.ectester.common.test.*; + +import java.io.PrintStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class BaseTextTestWriter implements TestWriter { + private PrintStream output; + + public static int BASE_WIDTH = 76; + + public BaseTextTestWriter(PrintStream output) { + this.output = output; + } + + @Override + public void begin(TestSuite suite) { + output.println("=== Running test suite: " + suite.getName() + " ==="); + output.println("=== " + suite.getDescription()); + } + + protected abstract String testableString(Testable t); + + private String testString(Test t, int offset) { + if (!t.hasRun()) { + return null; + } + + StringBuilder out = new StringBuilder(); + out.append(t.ok() ? "OK " : "NOK "); + out.append("━ "); + int width = BASE_WIDTH - (offset + out.length()); + String widthSpec = "%-" + String.valueOf(width) + "s"; + out.append(String.format(widthSpec, t.getDescription())); + out.append(" ┃ "); + out.append(String.format("%-9s", t.getResultValue().name())); + out.append(" ┃ "); + + if (t instanceof CompoundTest) { + CompoundTest test = (CompoundTest) t; + out.append(test.getResultCause()); + out.append(System.lineSeparator()); + Test[] tests = test.getTests(); + for (int i = 0; i < tests.length; ++i) { + if (i == tests.length - 1) { + out.append(" ┗ "); + } else { + out.append(" ┣ "); + } + out.append(testString(tests[i], offset + 6)); + if (i != tests.length - 1) { + out.append(System.lineSeparator()); + } + } + } else { + SimpleTest test = (SimpleTest) t; + out.append(testableString(test.getTestable())); + } + return out.toString(); + } + + @Override + public void outputTest(Test t) { + if (!t.hasRun()) + return; + output.println(testString(t, 0)); + output.flush(); + } + + @Override + public void end() { + } +} diff --git a/src/cz/crcs/ectester/common/output/BaseXMLTestWriter.java b/src/cz/crcs/ectester/common/output/BaseXMLTestWriter.java new file mode 100644 index 0000000..9d3c8f3 --- /dev/null +++ b/src/cz/crcs/ectester/common/output/BaseXMLTestWriter.java @@ -0,0 +1,100 @@ +package cz.crcs.ectester.common.output; + +import cz.crcs.ectester.common.test.*; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.OutputStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class BaseXMLTestWriter implements TestWriter { + private OutputStream output; + private DocumentBuilder db; + protected Document doc; + private Node root; + + public BaseXMLTestWriter(OutputStream output) throws ParserConfigurationException { + this.output = output; + this.db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } + + @Override + public void begin(TestSuite suite) { + doc = db.newDocument(); + Element rootElem = doc.createElement("testSuite"); + rootElem.setAttribute("name", suite.getName()); + rootElem.setAttribute("desc", suite.getDescription()); + + root = rootElem; + doc.appendChild(root); + } + + protected abstract Element testableElement(Testable t); + + private Element testElement(Test t) { + Element testElem; + if (t instanceof CompoundTest) { + CompoundTest test = (CompoundTest) t; + testElem = doc.createElement("test"); + testElem.setAttribute("type", "compound"); + for (Test innerTest : test.getTests()) { + testElem.appendChild(testElement(innerTest)); + } + } else { + SimpleTest test = (SimpleTest) t; + testElem = testableElement(test.getTestable()); + } + + Element description = doc.createElement("desc"); + description.setTextContent(t.getDescription()); + testElem.appendChild(description); + + Element result = doc.createElement("result"); + Element ok = doc.createElement("ok"); + ok.setTextContent(String.valueOf(t.ok())); + Element value = doc.createElement("value"); + value.setTextContent(t.getResultValue().name()); + Element cause = doc.createElement("cause"); + cause.setTextContent(t.getResultCause()); + result.appendChild(ok); + result.appendChild(value); + result.appendChild(cause); + testElem.appendChild(result); + + return testElem; + } + + @Override + public void outputTest(Test t) { + if (!t.hasRun()) + return; + root.appendChild(testElement(t)); + } + + @Override + public void end() { + try { + DOMSource domSource = new DOMSource(doc); + StreamResult result = new StreamResult(output); + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer transformer = tf.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + transformer.transform(domSource, result); + } catch (TransformerException e) { + e.printStackTrace(); + } + } +} diff --git a/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java b/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java new file mode 100644 index 0000000..af76927 --- /dev/null +++ b/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java @@ -0,0 +1,88 @@ +package cz.crcs.ectester.common.output; + +import cz.crcs.ectester.common.test.*; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; + +import java.io.PrintStream; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class BaseYAMLTestWriter implements TestWriter { + private PrintStream output; + private Map testRun; + private Map testSuite; + protected List tests; + + public BaseYAMLTestWriter(PrintStream output) { + this.output = output; + } + + @Override + public void begin(TestSuite suite) { + output.println("---"); + testRun = new HashMap<>(); + testSuite = new HashMap<>(); + tests = new LinkedList<>(); + testSuite.put("name", suite.getName()); + testSuite.put("desc", suite.getDescription()); + + testRun.put("suite", testSuite); + testRun.put("tests", tests); + } + + abstract protected Map testableObject(Testable t); + + private Map testObject(Test t) { + Map testObj; + if (t instanceof CompoundTest) { + CompoundTest test = (CompoundTest) t; + testObj = new HashMap<>(); + testObj.put("type", "compound"); + List> innerTests = new LinkedList<>(); + for (Test innerTest : test.getTests()) { + innerTests.add(testObject(innerTest)); + } + testObj.put("tests", innerTests); + } else { + SimpleTest test = (SimpleTest) t; + testObj = testableObject(test.getTestable()); + } + + testObj.put("desc", t.getDescription()); + Map result = new HashMap<>(); + result.put("ok", t.ok()); + result.put("value", t.getResultValue().name()); + result.put("cause", t.getResultCause()); + testObj.put("result", result); + + return testObj; + } + + @Override + public void outputTest(Test t) { + if (!t.hasRun()) + return; + tests.add(testObject(t)); + } + + @Override + public void end() { + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setPrettyFlow(true); + Yaml yaml = new Yaml(options); + + Map result = new HashMap<>(); + result.put("testRun", testRun); + String out = yaml.dump(result); + + output.println(out); + output.println("---"); + } +} diff --git a/src/cz/crcs/ectester/common/output/TestableWriter.java b/src/cz/crcs/ectester/common/output/TestableWriter.java deleted file mode 100644 index 9876064..0000000 --- a/src/cz/crcs/ectester/common/output/TestableWriter.java +++ /dev/null @@ -1,65 +0,0 @@ -package cz.crcs.ectester.common.output; - -import cz.crcs.ectester.common.test.BaseTestable; -import cz.crcs.ectester.reader.output.ResponseWriter; -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.CommandTestable; -import cz.crcs.ectester.standalone.test.KeyAgreementTestable; -import cz.crcs.ectester.standalone.test.KeyGeneratorTestable; -import cz.crcs.ectester.standalone.test.SignatureTestable; - -import java.io.OutputStream; -import java.io.PrintStream; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class TestableWriter { - private PrintStream output; - private ResponseWriter respWriter; - - public TestableWriter(PrintStream output) { - this.output = output; - this.respWriter = new ResponseWriter(output); - } - - public TestableWriter(OutputStream output) { - this(new PrintStream(output)); - } - - public String outputTestableSuffix(BaseTestable t) { - if (t instanceof CommandTestable) { - Response r = ((CommandTestable) t).getResponse(); - return respWriter.responseSuffix(r); - } else if (t instanceof KeyAgreementTestable) { - - } else if (t instanceof KeyGeneratorTestable) { - - } else if (t instanceof SignatureTestable) { - - } - return null; - } - - public void writeTestableSuffix(BaseTestable t) { - output.println(outputTestableSuffix(t)); - } - - public String outputTestable(BaseTestable t) { - if (t instanceof CommandTestable) { - CommandTestable testable = (CommandTestable) t; - return respWriter.responseString(testable.getResponse()); - } else if (t instanceof KeyAgreementTestable) { - - } else if (t instanceof KeyGeneratorTestable) { - - } else if (t instanceof SignatureTestable) { - - } - return null; - } - - public void writeTestable(BaseTestable t) { - output.println(outputTestable(t)); - } -} diff --git a/src/cz/crcs/ectester/common/output/TextTestWriter.java b/src/cz/crcs/ectester/common/output/TextTestWriter.java deleted file mode 100644 index 2691ccb..0000000 --- a/src/cz/crcs/ectester/common/output/TextTestWriter.java +++ /dev/null @@ -1,79 +0,0 @@ -package cz.crcs.ectester.common.output; - -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.SimpleTest; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.test.TestSuite; - -import java.io.PrintStream; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class TextTestWriter implements TestWriter { - private PrintStream output; - private TestableWriter testableWriter; - - public static int BASE_WIDTH = 76; - - public TextTestWriter(PrintStream output) { - this.output = output; - this.testableWriter = new TestableWriter(output); - } - - @Override - public void begin(TestSuite suite) { - output.println("=== Running test suite: " + suite.getName() + " ==="); - output.println("=== " + suite.getDescription()); - } - - private String testString(Test t, int offset) { - if (!t.hasRun()) { - return null; - } - - StringBuilder out = new StringBuilder(); - out.append(t.ok() ? "OK " : "NOK "); - out.append("━ "); - int width = BASE_WIDTH - (offset + out.length()); - String widthSpec = "%-" + String.valueOf(width) + "s"; - out.append(String.format(widthSpec, t.getDescription())); - out.append(" ┃ "); - out.append(String.format("%-9s", t.getResultValue().name())); - out.append(" ┃ "); - - if (t instanceof CompoundTest) { - CompoundTest test = (CompoundTest) t; - out.append(test.getResultCause()); - out.append(System.lineSeparator()); - Test[] tests = test.getTests(); - for (int i = 0; i < tests.length; ++i) { - if (i == tests.length - 1) { - out.append(" ┗ "); - } else { - out.append(" ┣ "); - } - out.append(testString(tests[i], offset + 6)); - if (i != tests.length - 1) { - out.append(System.lineSeparator()); - } - } - } else { - SimpleTest test = (SimpleTest) t; - out.append(testableWriter.outputTestableSuffix(test.getTestable())); - } - return out.toString(); - } - - @Override - public void outputTest(Test t) { - if (!t.hasRun()) - return; - output.println(testString(t, 0)); - output.flush(); - } - - @Override - public void end() { - } -} diff --git a/src/cz/crcs/ectester/common/output/XMLTestWriter.java b/src/cz/crcs/ectester/common/output/XMLTestWriter.java deleted file mode 100644 index 4139330..0000000 --- a/src/cz/crcs/ectester/common/output/XMLTestWriter.java +++ /dev/null @@ -1,204 +0,0 @@ -package cz.crcs.ectester.common.output; - -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.test.TestSuite; -import cz.crcs.ectester.common.util.ByteUtil; -import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.CommandTest; -import cz.crcs.ectester.standalone.test.*; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import java.io.OutputStream; -import java.security.PrivateKey; -import java.security.PublicKey; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class XMLTestWriter implements TestWriter { - private OutputStream output; - private DocumentBuilder db; - private Document doc; - private Node root; - - public XMLTestWriter(OutputStream output) throws ParserConfigurationException { - this.output = output; - this.db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - } - - @Override - public void begin(TestSuite suite) { - doc = db.newDocument(); - Element rootElem = doc.createElement("testSuite"); - rootElem.setAttribute("name", suite.getName()); - rootElem.setAttribute("desc", suite.getDescription()); - - root = rootElem; - doc.appendChild(root); - } - - private Element commandElement(Command c) { - Element commandElem = doc.createElement("command"); - - Element apdu = doc.createElement("apdu"); - apdu.setTextContent(ByteUtil.bytesToHex(c.getAPDU().getBytes())); - commandElem.appendChild(apdu); - - return commandElem; - } - - private Element responseElement(Response r) { - Element responseElem = doc.createElement("response"); - responseElem.setAttribute("successful", r.successful() ? "true" : "false"); - - Element apdu = doc.createElement("apdu"); - apdu.setTextContent(ByteUtil.bytesToHex(r.getAPDU().getBytes())); - responseElem.appendChild(apdu); - - Element naturalSW = doc.createElement("natural-sw"); - naturalSW.setTextContent(String.valueOf(Short.toUnsignedInt(r.getNaturalSW()))); - responseElem.appendChild(naturalSW); - - Element sws = doc.createElement("sws"); - for (int i = 0; i < r.getNumSW(); ++i) { - Element sw = doc.createElement("sw"); - sw.setTextContent(String.valueOf(Short.toUnsignedInt(r.getSW(i)))); - sws.appendChild(sw); - } - responseElem.appendChild(sws); - - Element duration = doc.createElement("duration"); - duration.setTextContent(String.valueOf(r.getDuration())); - responseElem.appendChild(duration); - - Element description = doc.createElement("desc"); - description.setTextContent(r.getDescription()); - responseElem.appendChild(description); - - return responseElem; - } - - private Element kaElement(KeyAgreementTestable kat) { - Element katElem = doc.createElement("key-agreement"); - - Element secret = doc.createElement("secret"); - secret.setTextContent(ByteUtil.bytesToHex(kat.getSecret())); - katElem.appendChild(secret); - - return katElem; - } - - private Element kgtElement(KeyGeneratorTestable kgt) { - Element kgtElem = doc.createElement("key-pair-generator"); - - Element keyPair = doc.createElement("key-pair"); - Element pubkey = doc.createElement("pubkey"); - PublicKey pkey = kgt.getKeyPair().getPublic(); - pubkey.setAttribute("algorithm", pkey.getAlgorithm()); - pubkey.setAttribute("format", pkey.getFormat()); - pubkey.setTextContent(ByteUtil.bytesToHex(pkey.getEncoded())); - keyPair.appendChild(pubkey); - - Element privkey = doc.createElement("privkey"); - PrivateKey skey = kgt.getKeyPair().getPrivate(); - privkey.setAttribute("algorithm", skey.getAlgorithm()); - privkey.setAttribute("format", skey.getFormat()); - privkey.setTextContent(ByteUtil.bytesToHex(skey.getEncoded())); - keyPair.appendChild(privkey); - - return kgtElem; - } - - private Element sigElement(SignatureTestable sig) { - Element sigElem = doc.createElement("signature"); - sigElem.setAttribute("verified", sig.getVerified() ? "true" : "false"); - - Element raw = doc.createElement("raw"); - raw.setTextContent(ByteUtil.bytesToHex(sig.getSignature())); - sigElem.appendChild(raw); - - return sigElem; - } - - private Element testElement(Test t) { - Element testElem = doc.createElement("test"); - - if (t instanceof CommandTest) { - CommandTest test = (CommandTest) t; - testElem.setAttribute("type", "command"); - testElem.appendChild(commandElement(test.getCommand())); - testElem.appendChild(responseElement(test.getResponse())); - } else if (t instanceof KeyAgreementTest) { - KeyAgreementTest test = (KeyAgreementTest) t; - testElem.setAttribute("type", "key-agreement"); - testElem.appendChild(kaElement(test.getTestable())); - } else if (t instanceof KeyGeneratorTest) { - KeyGeneratorTest test = (KeyGeneratorTest) t; - testElem.setAttribute("type", "key-pair-generator"); - testElem.appendChild(kgtElement(test.getTestable())); - } else if (t instanceof SignatureTest) { - SignatureTest test = (SignatureTest) t; - testElem.setAttribute("type", "signature"); - testElem.appendChild(sigElement(test.getTestable())); - } else if (t instanceof CompoundTest) { - CompoundTest test = (CompoundTest) t; - testElem.setAttribute("type", "compound"); - for (Test innerTest : test.getTests()) { - testElem.appendChild(testElement(innerTest)); - } - } - - Element description = doc.createElement("desc"); - description.setTextContent(t.getDescription()); - testElem.appendChild(description); - - Element result = doc.createElement("result"); - Element ok = doc.createElement("ok"); - ok.setTextContent(String.valueOf(t.ok())); - Element value = doc.createElement("value"); - value.setTextContent(t.getResultValue().name()); - Element cause = doc.createElement("cause"); - cause.setTextContent(t.getResultCause()); - result.appendChild(ok); - result.appendChild(value); - result.appendChild(cause); - testElem.appendChild(result); - - return testElem; - } - - @Override - public void outputTest(Test t) { - if (!t.hasRun()) - return; - root.appendChild(testElement(t)); - } - - @Override - public void end() { - try { - DOMSource domSource = new DOMSource(doc); - StreamResult result = new StreamResult(output); - TransformerFactory tf = TransformerFactory.newInstance(); - Transformer transformer = tf.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); - transformer.transform(domSource, result); - } catch (TransformerException e) { - e.printStackTrace(); - } - } -} \ No newline at end of file diff --git a/src/cz/crcs/ectester/common/output/YAMLTestWriter.java b/src/cz/crcs/ectester/common/output/YAMLTestWriter.java deleted file mode 100644 index ba9fa43..0000000 --- a/src/cz/crcs/ectester/common/output/YAMLTestWriter.java +++ /dev/null @@ -1,161 +0,0 @@ -package cz.crcs.ectester.common.output; - -import cz.crcs.ectester.common.test.CompoundTest; -import cz.crcs.ectester.common.test.Test; -import cz.crcs.ectester.common.test.TestSuite; -import cz.crcs.ectester.common.util.ByteUtil; -import cz.crcs.ectester.reader.command.Command; -import cz.crcs.ectester.reader.response.Response; -import cz.crcs.ectester.reader.test.CommandTest; -import cz.crcs.ectester.standalone.test.*; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; - -import java.io.PrintStream; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class YAMLTestWriter implements TestWriter { - private PrintStream output; - private Map testRun; - private Map testSuite; - private List tests; - - public YAMLTestWriter(PrintStream output) { - this.output = output; - } - - @Override - public void begin(TestSuite suite) { - output.println("---"); - testRun = new HashMap<>(); - testSuite = new HashMap<>(); - tests = new LinkedList<>(); - testSuite.put("name", suite.getName()); - testSuite.put("desc", suite.getDescription()); - - testRun.put("suite", testSuite); - testRun.put("tests", tests); - } - - private Map commandObject(Command c) { - Map commandObj = new HashMap<>(); - commandObj.put("apdu", ByteUtil.bytesToHex(c.getAPDU().getBytes())); - return commandObj; - } - - private Map responseObject(Response r) { - Map responseObj = new HashMap<>(); - responseObj.put("successful", r.successful()); - responseObj.put("apdu", ByteUtil.bytesToHex(r.getAPDU().getBytes())); - responseObj.put("natural_sw", Short.toUnsignedInt(r.getNaturalSW())); - List sws = new LinkedList<>(); - for (int i = 0; i < r.getNumSW(); ++i) { - sws.add(Short.toUnsignedInt(r.getSW(i))); - } - responseObj.put("sws", sws); - responseObj.put("duration", r.getDuration()); - responseObj.put("desc", r.getDescription()); - return responseObj; - } - - private Map kaObject(KeyAgreementTestable kat) { - Map katObject = new HashMap<>(); - katObject.put("secret", ByteUtil.bytesToHex(kat.getSecret())); - return katObject; - } - - private Map kgtObject(KeyGeneratorTestable kgt) { - Map kgtObject = new HashMap<>(); - Map pubObject = new HashMap<>(); - PublicKey pkey = kgt.getKeyPair().getPublic(); - pubObject.put("algorithm", pkey.getAlgorithm()); - pubObject.put("format", pkey.getFormat()); - pubObject.put("raw", ByteUtil.bytesToHex(pkey.getEncoded())); - kgtObject.put("pubkey", pubObject); - - Map privObject = new HashMap<>(); - PrivateKey skey = kgt.getKeyPair().getPrivate(); - privObject.put("algorithm", skey.getAlgorithm()); - privObject.put("format", skey.getFormat()); - privObject.put("raw", ByteUtil.bytesToHex(skey.getEncoded())); - kgtObject.put("privkey", privObject); - return kgtObject; - } - - private Map sigObject(SignatureTestable sig) { - Map sigObject = new HashMap<>(); - sigObject.put("verified", sig.getVerified()); - sigObject.put("raw", ByteUtil.bytesToHex(sig.getSignature())); - return sigObject; - } - - private Map testObject(Test t) { - Map testObj = new HashMap<>(); - - if (t instanceof CommandTest) { - CommandTest test = (CommandTest) t; - testObj.put("type", "command"); - testObj.put("command", commandObject(test.getCommand())); - testObj.put("response", responseObject(test.getResponse())); - } else if (t instanceof KeyAgreementTest) { - KeyAgreementTest test = (KeyAgreementTest) t; - testObj.put("type", "key-agreement"); - testObj.put("key-agreement", kaObject(test.getTestable())); - } else if (t instanceof KeyGeneratorTest) { - KeyGeneratorTest test = (KeyGeneratorTest) t; - testObj.put("type", "key-pair-generator"); - testObj.put("key-pair-generator", kgtObject(test.getTestable())); - } else if (t instanceof SignatureTest) { - SignatureTest test = (SignatureTest) t; - testObj.put("type", "signature"); - testObj.put("signature", sigObject(test.getTestable())); - } else if (t instanceof CompoundTest) { - CompoundTest test = (CompoundTest) t; - testObj.put("type", "compound"); - List> tests = new LinkedList<>(); - for (Test innerTest : test.getTests()) { - tests.add(testObject(innerTest)); - } - testObj.put("tests", tests); - } - - testObj.put("desc", t.getDescription()); - Map result = new HashMap<>(); - result.put("ok", t.ok()); - result.put("value", t.getResultValue().name()); - result.put("cause", t.getResultCause()); - testObj.put("result", result); - - return testObj; - } - - @Override - public void outputTest(Test t) { - if (!t.hasRun()) - return; - tests.add(testObject(t)); - } - - @Override - public void end() { - DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - options.setPrettyFlow(true); - Yaml yaml = new Yaml(options); - - Map result = new HashMap<>(); - result.put("testRun", testRun); - String out = yaml.dump(result); - - output.println(out); - output.println("---"); - } -} diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index 6fa7068..f566c9c 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -31,7 +31,10 @@ import cz.crcs.ectester.common.test.TestRunner; import cz.crcs.ectester.common.util.ByteUtil; 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.output.ResponseWriter; +import cz.crcs.ectester.reader.output.TextTestWriter; +import cz.crcs.ectester.reader.output.XMLTestWriter; +import cz.crcs.ectester.reader.output.YAMLTestWriter; import cz.crcs.ectester.reader.response.Response; import cz.crcs.ectester.reader.test.*; import javacard.security.KeyPair; diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java new file mode 100644 index 0000000..dedf561 --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -0,0 +1,28 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.common.output.BaseTextTestWriter; +import cz.crcs.ectester.common.test.Testable; +import cz.crcs.ectester.reader.test.CommandTestable; + +import java.io.PrintStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TextTestWriter extends BaseTextTestWriter { + private ResponseWriter writer; + + public TextTestWriter(PrintStream output) { + super(output); + this.writer = new ResponseWriter(output); + } + + @Override + protected String testableString(Testable t) { + if (t instanceof CommandTestable) { + CommandTestable cmd = (CommandTestable) t; + return writer.responseSuffix(cmd.getResponse()); + } + return ""; + } +} diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java new file mode 100644 index 0000000..d88a64e --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -0,0 +1,75 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.common.output.BaseXMLTestWriter; +import cz.crcs.ectester.common.test.Testable; +import cz.crcs.ectester.common.util.ByteUtil; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.CommandTestable; +import org.w3c.dom.Element; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.OutputStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class XMLTestWriter extends BaseXMLTestWriter { + public XMLTestWriter(OutputStream output) throws ParserConfigurationException { + super(output); + } + + private Element commandElement(Command c) { + Element commandElem = doc.createElement("command"); + + Element apdu = doc.createElement("apdu"); + apdu.setTextContent(ByteUtil.bytesToHex(c.getAPDU().getBytes())); + commandElem.appendChild(apdu); + + return commandElem; + } + + private Element responseElement(Response r) { + Element responseElem = doc.createElement("response"); + responseElem.setAttribute("successful", r.successful() ? "true" : "false"); + + Element apdu = doc.createElement("apdu"); + apdu.setTextContent(ByteUtil.bytesToHex(r.getAPDU().getBytes())); + responseElem.appendChild(apdu); + + Element naturalSW = doc.createElement("natural-sw"); + naturalSW.setTextContent(String.valueOf(Short.toUnsignedInt(r.getNaturalSW()))); + responseElem.appendChild(naturalSW); + + Element sws = doc.createElement("sws"); + for (int i = 0; i < r.getNumSW(); ++i) { + Element sw = doc.createElement("sw"); + sw.setTextContent(String.valueOf(Short.toUnsignedInt(r.getSW(i)))); + sws.appendChild(sw); + } + responseElem.appendChild(sws); + + Element duration = doc.createElement("duration"); + duration.setTextContent(String.valueOf(r.getDuration())); + responseElem.appendChild(duration); + + Element description = doc.createElement("desc"); + description.setTextContent(r.getDescription()); + responseElem.appendChild(description); + + return responseElem; + } + + @Override + protected Element testableElement(Testable t) { + if (t instanceof CommandTestable) { + CommandTestable cmd = (CommandTestable) t; + Element result = doc.createElement("test"); + result.setAttribute("type", "command"); + result.appendChild(commandElement(cmd.getCommand())); + result.appendChild(responseElement(cmd.getResponse())); + return result; + } + return null; + } +} \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java new file mode 100644 index 0000000..49a20f1 --- /dev/null +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -0,0 +1,57 @@ +package cz.crcs.ectester.reader.output; + +import cz.crcs.ectester.common.output.BaseYAMLTestWriter; +import cz.crcs.ectester.common.test.Testable; +import cz.crcs.ectester.common.util.ByteUtil; +import cz.crcs.ectester.reader.command.Command; +import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.CommandTestable; + +import java.io.PrintStream; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class YAMLTestWriter extends BaseYAMLTestWriter { + public YAMLTestWriter(PrintStream output) { + super(output); + } + + private Map commandObject(Command c) { + Map commandObj = new HashMap<>(); + commandObj.put("apdu", ByteUtil.bytesToHex(c.getAPDU().getBytes())); + return commandObj; + } + + private Map responseObject(Response r) { + Map responseObj = new HashMap<>(); + responseObj.put("successful", r.successful()); + responseObj.put("apdu", ByteUtil.bytesToHex(r.getAPDU().getBytes())); + responseObj.put("natural_sw", Short.toUnsignedInt(r.getNaturalSW())); + List sws = new LinkedList<>(); + for (int i = 0; i < r.getNumSW(); ++i) { + sws.add(Short.toUnsignedInt(r.getSW(i))); + } + responseObj.put("sws", sws); + responseObj.put("duration", r.getDuration()); + responseObj.put("desc", r.getDescription()); + return responseObj; + } + + @Override + protected Map testableObject(Testable t) { + if (t instanceof CommandTestable) { + CommandTestable cmd = (CommandTestable) t; + Map result = new HashMap<>(); + result.put("type", "command"); + result.put("command", commandObject(cmd.getCommand())); + result.put("response", responseObject(cmd.getResponse())); + return result; + } + return null; + } +} diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java index c3dfbbe..237897c 100644 --- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -2,7 +2,6 @@ package cz.crcs.ectester.standalone; import cz.crcs.ectester.common.cli.*; import cz.crcs.ectester.common.ec.EC_Curve; -import cz.crcs.ectester.common.output.TextTestWriter; import cz.crcs.ectester.common.test.TestException; import cz.crcs.ectester.common.test.TestRunner; import cz.crcs.ectester.common.util.ByteUtil; @@ -12,6 +11,7 @@ import cz.crcs.ectester.standalone.consts.KeyAgreementIdent; import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; import cz.crcs.ectester.standalone.consts.SignatureIdent; import cz.crcs.ectester.standalone.libs.*; +import cz.crcs.ectester.standalone.output.TextTestWriter; import cz.crcs.ectester.standalone.test.StandaloneDefaultSuite; import cz.crcs.ectester.standalone.test.StandaloneTestSuite; import org.apache.commons.cli.DefaultParser; diff --git a/src/cz/crcs/ectester/standalone/output/TextTestWriter.java b/src/cz/crcs/ectester/standalone/output/TextTestWriter.java new file mode 100644 index 0000000..ddb1029 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/output/TextTestWriter.java @@ -0,0 +1,20 @@ +package cz.crcs.ectester.standalone.output; + +import cz.crcs.ectester.common.output.BaseTextTestWriter; +import cz.crcs.ectester.common.test.Testable; + +import java.io.PrintStream; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class TextTestWriter extends BaseTextTestWriter { + public TextTestWriter(PrintStream output) { + super(output); + } + + @Override + protected String testableString(Testable t) { + return ""; + } +} \ No newline at end of file diff --git a/src/cz/crcs/ectester/standalone/output/XMLTestWriter.java b/src/cz/crcs/ectester/standalone/output/XMLTestWriter.java new file mode 100644 index 0000000..cc1a19e --- /dev/null +++ b/src/cz/crcs/ectester/standalone/output/XMLTestWriter.java @@ -0,0 +1,82 @@ +package cz.crcs.ectester.standalone.output; + +import cz.crcs.ectester.common.output.BaseXMLTestWriter; +import cz.crcs.ectester.common.test.Testable; +import cz.crcs.ectester.common.util.ByteUtil; +import cz.crcs.ectester.standalone.test.KeyAgreementTestable; +import cz.crcs.ectester.standalone.test.KeyGeneratorTestable; +import cz.crcs.ectester.standalone.test.SignatureTestable; +import org.w3c.dom.Element; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.OutputStream; +import java.security.PrivateKey; +import java.security.PublicKey; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class XMLTestWriter extends BaseXMLTestWriter { + + public XMLTestWriter(OutputStream output) throws ParserConfigurationException { + super(output); + } + + private Element kaElement(KeyAgreementTestable kat) { + Element katElem = doc.createElement("key-agreement"); + + Element secret = doc.createElement("secret"); + secret.setTextContent(ByteUtil.bytesToHex(kat.getSecret())); + katElem.appendChild(secret); + + return katElem; + } + + private Element kgtElement(KeyGeneratorTestable kgt) { + Element kgtElem = doc.createElement("key-pair-generator"); + + Element keyPair = doc.createElement("key-pair"); + Element pubkey = doc.createElement("pubkey"); + PublicKey pkey = kgt.getKeyPair().getPublic(); + pubkey.setAttribute("algorithm", pkey.getAlgorithm()); + pubkey.setAttribute("format", pkey.getFormat()); + pubkey.setTextContent(ByteUtil.bytesToHex(pkey.getEncoded())); + keyPair.appendChild(pubkey); + + Element privkey = doc.createElement("privkey"); + PrivateKey skey = kgt.getKeyPair().getPrivate(); + privkey.setAttribute("algorithm", skey.getAlgorithm()); + privkey.setAttribute("format", skey.getFormat()); + privkey.setTextContent(ByteUtil.bytesToHex(skey.getEncoded())); + keyPair.appendChild(privkey); + + return kgtElem; + } + + private Element sigElement(SignatureTestable sig) { + Element sigElem = doc.createElement("signature"); + sigElem.setAttribute("verified", sig.getVerified() ? "true" : "false"); + + Element raw = doc.createElement("raw"); + raw.setTextContent(ByteUtil.bytesToHex(sig.getSignature())); + sigElem.appendChild(raw); + + return sigElem; + } + + @Override + protected Element testableElement(Testable t) { + Element result = doc.createElement("test"); + if (t instanceof KeyGeneratorTestable) { + result.setAttribute("type", "key-pair-generator"); + result.appendChild(kgtElement((KeyGeneratorTestable) t)); + } else if (t instanceof KeyAgreementTestable) { + result.setAttribute("type", "key-agreement"); + result.appendChild(kaElement((KeyAgreementTestable) t)); + } else if (t instanceof SignatureTestable) { + result.setAttribute("type", "signature"); + result.appendChild(sigElement((SignatureTestable) t)); + } + return result; + } +} diff --git a/src/cz/crcs/ectester/standalone/output/YAMLTestWriter.java b/src/cz/crcs/ectester/standalone/output/YAMLTestWriter.java new file mode 100644 index 0000000..7ede623 --- /dev/null +++ b/src/cz/crcs/ectester/standalone/output/YAMLTestWriter.java @@ -0,0 +1,70 @@ +package cz.crcs.ectester.standalone.output; + +import cz.crcs.ectester.common.output.BaseYAMLTestWriter; +import cz.crcs.ectester.common.test.Testable; +import cz.crcs.ectester.common.util.ByteUtil; +import cz.crcs.ectester.standalone.test.KeyAgreementTestable; +import cz.crcs.ectester.standalone.test.KeyGeneratorTestable; +import cz.crcs.ectester.standalone.test.SignatureTestable; + +import java.io.PrintStream; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class YAMLTestWriter extends BaseYAMLTestWriter { + public YAMLTestWriter(PrintStream output) { + super(output); + } + + private Map kaObject(KeyAgreementTestable kat) { + Map katObject = new HashMap<>(); + katObject.put("secret", ByteUtil.bytesToHex(kat.getSecret())); + return katObject; + } + + private Map kgtObject(KeyGeneratorTestable kgt) { + Map kgtObject = new HashMap<>(); + Map pubObject = new HashMap<>(); + PublicKey pkey = kgt.getKeyPair().getPublic(); + pubObject.put("algorithm", pkey.getAlgorithm()); + pubObject.put("format", pkey.getFormat()); + pubObject.put("raw", ByteUtil.bytesToHex(pkey.getEncoded())); + kgtObject.put("pubkey", pubObject); + + Map privObject = new HashMap<>(); + PrivateKey skey = kgt.getKeyPair().getPrivate(); + privObject.put("algorithm", skey.getAlgorithm()); + privObject.put("format", skey.getFormat()); + privObject.put("raw", ByteUtil.bytesToHex(skey.getEncoded())); + kgtObject.put("privkey", privObject); + return kgtObject; + } + + private Map sigObject(SignatureTestable sig) { + Map sigObject = new HashMap<>(); + sigObject.put("verified", sig.getVerified()); + sigObject.put("raw", ByteUtil.bytesToHex(sig.getSignature())); + return sigObject; + } + + @Override + protected Map testableObject(Testable t) { + Map result = new HashMap<>(); + if (t instanceof KeyGeneratorTestable) { + result.put("type", "key-pair-generator"); + result.put("key-pair-generator", kgtObject((KeyGeneratorTestable) t)); + } else if (t instanceof KeyAgreementTestable) { + result.put("type", "key-agreement"); + result.put("key-agreement", kaObject((KeyAgreementTestable) t)); + } else if (t instanceof SignatureTestable) { + result.put("type", "signature"); + result.put("signature", sigObject((SignatureTestable) t)); + } + return result; + } +} -- cgit v1.2.3-70-g09d2 From aeb322e1da26dcfc83762d9bc8df83667a22282a Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 14 Jan 2018 15:26:30 +0100 Subject: Export CPLC data and card ATR in test suite outputs. --- .../ectester/common/output/BaseTextTestWriter.java | 3 ++ .../ectester/common/output/BaseXMLTestWriter.java | 3 ++ .../ectester/common/output/BaseYAMLTestWriter.java | 3 ++ src/cz/crcs/ectester/reader/CardMngr.java | 21 +++++++++--- .../ectester/reader/output/TextTestWriter.java | 29 +++++++++++++++++ .../crcs/ectester/reader/output/XMLTestWriter.java | 38 ++++++++++++++++++++++ .../ectester/reader/output/YAMLTestWriter.java | 33 +++++++++++++++++++ .../crcs/ectester/reader/test/CardTestSuite.java | 4 +++ .../ectester/standalone/output/TextTestWriter.java | 8 +++++ .../ectester/standalone/output/XMLTestWriter.java | 7 ++++ .../ectester/standalone/output/YAMLTestWriter.java | 7 ++++ 11 files changed, 151 insertions(+), 5 deletions(-) (limited to 'src/cz/crcs/ectester/reader/output/TextTestWriter.java') diff --git a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java index 6ace3a0..29eb671 100644 --- a/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java +++ b/src/cz/crcs/ectester/common/output/BaseTextTestWriter.java @@ -20,10 +20,13 @@ public abstract class BaseTextTestWriter implements TestWriter { public void begin(TestSuite suite) { output.println("═══ Running test suite: " + suite.getName() + " ═══"); output.println("═══ " + suite.getDescription()); + output.print(deviceString(suite)); } protected abstract String testableString(Testable t); + protected abstract String deviceString(TestSuite suite); + private String testString(Test t, String prefix) { if (!t.hasRun()) { return null; diff --git a/src/cz/crcs/ectester/common/output/BaseXMLTestWriter.java b/src/cz/crcs/ectester/common/output/BaseXMLTestWriter.java index 9d3c8f3..f3e9411 100644 --- a/src/cz/crcs/ectester/common/output/BaseXMLTestWriter.java +++ b/src/cz/crcs/ectester/common/output/BaseXMLTestWriter.java @@ -39,10 +39,13 @@ public abstract class BaseXMLTestWriter implements TestWriter { root = rootElem; doc.appendChild(root); + root.appendChild(deviceElement(suite)); } protected abstract Element testableElement(Testable t); + protected abstract Element deviceElement(TestSuite suite); + private Element testElement(Test t) { Element testElem; if (t instanceof CompoundTest) { diff --git a/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java b/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java index af76927..0769e83 100644 --- a/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java +++ b/src/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java @@ -33,11 +33,14 @@ public abstract class BaseYAMLTestWriter implements TestWriter { testSuite.put("desc", suite.getDescription()); testRun.put("suite", testSuite); + testRun.put("device", deviceObject(suite)); testRun.put("tests", tests); } abstract protected Map testableObject(Testable t); + abstract protected Map deviceObject(TestSuite suite); + private Map testObject(Test t) { Map testObj; if (t instanceof CompoundTest) { diff --git a/src/cz/crcs/ectester/reader/CardMngr.java b/src/cz/crcs/ectester/reader/CardMngr.java index a959f2a..1e42c52 100644 --- a/src/cz/crcs/ectester/reader/CardMngr.java +++ b/src/cz/crcs/ectester/reader/CardMngr.java @@ -174,10 +174,10 @@ public class CardMngr { public byte[] fetchCPLC() throws CardException { // Try CPLC via GP - ResponseAPDU resp = sendAPDU(FETCH_GP_CPLC_APDU); + ResponseAPDU resp = send(FETCH_GP_CPLC_APDU); // If GP CLA fails, try with ISO if (resp.getSW() == (ISO7816.SW_CLA_NOT_SUPPORTED & 0xffff)) { - resp = sendAPDU(FETCH_ISO_CPLC_APDU); + resp = send(FETCH_ISO_CPLC_APDU); } if (resp.getSW() == (ISO7816.SW_NO_ERROR & 0xffff)) { return resp.getData(); @@ -207,10 +207,13 @@ public class CardMngr { ICPersonalizationEquipmentID } - private Map values = new HashMap<>(); + private Map values = new TreeMap<>(); public CPLC(byte[] data) { - if (data == null || data.length < 3 || data[2] != 0x2A) { + if (data == null) { + return; + } + if (data.length < 3 || data[2] != 0x2A) { throw new IllegalArgumentException("CPLC must be 0x2A bytes long"); } //offset = TLVUtils.skipTag(data, offset, (short)0x9F7F); @@ -263,7 +266,7 @@ public class CardMngr { return new CPLC(data); } - public String mapCPLCField(CPLC.Field field, byte[] value) { + public static String mapCPLCField(CPLC.Field field, byte[] value) { switch (field) { case ICFabricator: String id = ByteUtil.bytesToHex(value, false); @@ -289,6 +292,14 @@ public class CardMngr { } } + public ATR getATR() { + if (simulate) { + return new ATR(simulator.getATR()); + } else { + return card.getATR(); + } + } + public static List getReaderList() { try { TerminalFactory factory = TerminalFactory.getDefault(); diff --git a/src/cz/crcs/ectester/reader/output/TextTestWriter.java b/src/cz/crcs/ectester/reader/output/TextTestWriter.java index dedf561..eb52937 100644 --- a/src/cz/crcs/ectester/reader/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/TextTestWriter.java @@ -1,10 +1,16 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.common.output.BaseTextTestWriter; +import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.common.test.Testable; +import cz.crcs.ectester.common.util.ByteUtil; +import cz.crcs.ectester.reader.CardMngr; +import cz.crcs.ectester.reader.test.CardTestSuite; import cz.crcs.ectester.reader.test.CommandTestable; +import javax.smartcardio.CardException; import java.io.PrintStream; +import java.util.Map; /** * @author Jan Jancar johny@neuromancer.sk @@ -25,4 +31,27 @@ public class TextTestWriter extends BaseTextTestWriter { } return ""; } + + @Override + protected String deviceString(TestSuite suite) { + if (suite instanceof CardTestSuite) { + CardTestSuite cardSuite = (CardTestSuite) suite; + StringBuilder sb = new StringBuilder(); + sb.append("═══ Card ATR: ").append(ByteUtil.bytesToHex(cardSuite.getCard().getATR().getBytes(), false)).append(System.lineSeparator()); + try { + CardMngr.CPLC cplc = cardSuite.getCard().getCPLC(); + if (!cplc.values().isEmpty()) { + sb.append("═══ Card CPLC data:").append(System.lineSeparator()); + for (Map.Entry entry : cplc.values().entrySet()) { + CardMngr.CPLC.Field field = entry.getKey(); + byte[] value = entry.getValue(); + sb.append("═══ ").append(field.name()).append(": ").append(CardMngr.mapCPLCField(field, value)); + } + } + } catch (CardException ignored) { + } + return sb.toString(); + } + return ""; + } } diff --git a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java index d88a64e..356593e 100644 --- a/src/cz/crcs/ectester/reader/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/XMLTestWriter.java @@ -1,15 +1,20 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.common.output.BaseXMLTestWriter; +import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.common.test.Testable; import cz.crcs.ectester.common.util.ByteUtil; +import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.CardTestSuite; import cz.crcs.ectester.reader.test.CommandTestable; import org.w3c.dom.Element; +import javax.smartcardio.CardException; import javax.xml.parsers.ParserConfigurationException; import java.io.OutputStream; +import java.util.Map; /** * @author Jan Jancar johny@neuromancer.sk @@ -72,4 +77,37 @@ public class XMLTestWriter extends BaseXMLTestWriter { } return null; } + + private Element cplcElement(CardMngr card) { + Element result = doc.createElement("cplc"); + try { + CardMngr.CPLC cplc = card.getCPLC(); + if (!cplc.values().isEmpty()) { + for (Map.Entry entry : cplc.values().entrySet()) { + CardMngr.CPLC.Field field = entry.getKey(); + byte[] value = entry.getValue(); + Element keyVal = doc.createElement(field.name()); + keyVal.setTextContent(ByteUtil.bytesToHex(value, false)); + result.appendChild(keyVal); + } + } + } catch (CardException ignored) { + } + return result; + } + + @Override + protected Element deviceElement(TestSuite suite) { + if (suite instanceof CardTestSuite) { + CardTestSuite cardSuite = (CardTestSuite) suite; + Element result = doc.createElement("device"); + result.setAttribute("type", "card"); + result.appendChild(cplcElement(cardSuite.getCard())); + + Element atr = doc.createElement("ATR"); + atr.setTextContent(ByteUtil.bytesToHex(cardSuite.getCard().getATR().getBytes(), false)); + result.appendChild(atr); + } + return null; + } } \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java index 49a20f1..199f2c0 100644 --- a/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/reader/output/YAMLTestWriter.java @@ -1,12 +1,16 @@ package cz.crcs.ectester.reader.output; import cz.crcs.ectester.common.output.BaseYAMLTestWriter; +import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.common.test.Testable; import cz.crcs.ectester.common.util.ByteUtil; +import cz.crcs.ectester.reader.CardMngr; import cz.crcs.ectester.reader.command.Command; import cz.crcs.ectester.reader.response.Response; +import cz.crcs.ectester.reader.test.CardTestSuite; import cz.crcs.ectester.reader.test.CommandTestable; +import javax.smartcardio.CardException; import java.io.PrintStream; import java.util.HashMap; import java.util.LinkedList; @@ -54,4 +58,33 @@ public class YAMLTestWriter extends BaseYAMLTestWriter { } return null; } + + private Map cplcObject(CardMngr card) { + Map result = new HashMap<>(); + try { + CardMngr.CPLC cplc = card.getCPLC(); + if (!cplc.values().isEmpty()) { + for (Map.Entry entry : cplc.values().entrySet()) { + CardMngr.CPLC.Field field = entry.getKey(); + byte[] value = entry.getValue(); + result.put(field.name(), ByteUtil.bytesToHex(value, false)); + } + } + } catch (CardException ignored) { + } + return result; + } + + @Override + protected Map deviceObject(TestSuite suite) { + if (suite instanceof CardTestSuite) { + CardTestSuite cardSuite = (CardTestSuite) suite; + Map result = new HashMap<>(); + result.put("type", "card"); + result.put("cplc", cplcObject(cardSuite.getCard())); + result.put("ATR", ByteUtil.bytesToHex(cardSuite.getCard().getATR().getBytes(), false)); + return result; + } + return null; + } } diff --git a/src/cz/crcs/ectester/reader/test/CardTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTestSuite.java index e12a588..b451265 100644 --- a/src/cz/crcs/ectester/reader/test/CardTestSuite.java +++ b/src/cz/crcs/ectester/reader/test/CardTestSuite.java @@ -116,4 +116,8 @@ public abstract class CardTestSuite extends TestSuite { return null; } + + public CardMngr getCard() { + return card; + } } diff --git a/src/cz/crcs/ectester/standalone/output/TextTestWriter.java b/src/cz/crcs/ectester/standalone/output/TextTestWriter.java index ddb1029..972af18 100644 --- a/src/cz/crcs/ectester/standalone/output/TextTestWriter.java +++ b/src/cz/crcs/ectester/standalone/output/TextTestWriter.java @@ -1,6 +1,7 @@ package cz.crcs.ectester.standalone.output; import cz.crcs.ectester.common.output.BaseTextTestWriter; +import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.common.test.Testable; import java.io.PrintStream; @@ -15,6 +16,13 @@ public class TextTestWriter extends BaseTextTestWriter { @Override protected String testableString(Testable t) { + //TODO + return ""; + } + + @Override + protected String deviceString(TestSuite suite) { + //TODO return ""; } } \ No newline at end of file diff --git a/src/cz/crcs/ectester/standalone/output/XMLTestWriter.java b/src/cz/crcs/ectester/standalone/output/XMLTestWriter.java index 9606646..d2b16d8 100644 --- a/src/cz/crcs/ectester/standalone/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/standalone/output/XMLTestWriter.java @@ -1,6 +1,7 @@ package cz.crcs.ectester.standalone.output; import cz.crcs.ectester.common.output.BaseXMLTestWriter; +import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.common.test.Testable; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.standalone.test.KeyAgreementTestable; @@ -109,4 +110,10 @@ public class XMLTestWriter extends BaseXMLTestWriter { } return result; } + + @Override + protected Element deviceElement(TestSuite suite) { + //TODO + return null; + } } diff --git a/src/cz/crcs/ectester/standalone/output/YAMLTestWriter.java b/src/cz/crcs/ectester/standalone/output/YAMLTestWriter.java index 2133a8e..dfc6813 100644 --- a/src/cz/crcs/ectester/standalone/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/standalone/output/YAMLTestWriter.java @@ -1,6 +1,7 @@ package cz.crcs.ectester.standalone.output; import cz.crcs.ectester.common.output.BaseYAMLTestWriter; +import cz.crcs.ectester.common.test.TestSuite; import cz.crcs.ectester.common.test.Testable; import cz.crcs.ectester.common.util.ByteUtil; import cz.crcs.ectester.standalone.test.KeyAgreementTestable; @@ -88,4 +89,10 @@ public class YAMLTestWriter extends BaseYAMLTestWriter { } return result; } + + @Override + protected Map deviceObject(TestSuite suite) { + //TODO + return null; + } } -- cgit v1.2.3-70-g09d2